• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nickg / nvc / 12854971287

19 Jan 2025 03:39PM UTC coverage: 92.194% (+0.002%) from 92.192%
12854971287

push

github

nickg
Implement PSL prev() built-in function. Fixes #1135

48 of 53 new or added lines in 3 files covered. (90.57%)

419 existing lines in 12 files now uncovered.

64159 of 69591 relevant lines covered (92.19%)

508771.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.84
/src/common.c
1
//
2
//  Copyright (C) 2013-2024  Nick Gasson
3
//
4
//  This program is free software: you can redistribute it and/or modify
5
//  it under the terms of the GNU General Public License as published by
6
//  the Free Software Foundation, either version 3 of the License, or
7
//  (at your option) any later version.
8
//
9
//  This program is distributed in the hope that it will be useful,
10
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
//  GNU General Public License for more details.
13
//
14
//  You should have received a copy of the GNU General Public License
15
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

18
#include "util.h"
19
#include "common.h"
20
#include "diag.h"
21
#include "hash.h"
22
#include "ident.h"
23
#include "lib.h"
24
#include "lower.h"
25
#include "option.h"
26
#include "phase.h"
27
#include "scan.h"
28
#include "thread.h"
29
#include "type.h"
30
#include "vlog/vlog-phase.h"
31
#include "sdf/sdf-phase.h"
32
#include "sdf/sdf-util.h"
33

34
#include <assert.h>
35
#include <ctype.h>
36
#include <string.h>
37
#include <stdlib.h>
38
#include <inttypes.h>
39

40
static vhdl_standard_t  current_std  = STD_08;
41
static bool             have_set_std = false;
42
static ident_t          id_cache[NUM_WELL_KNOWN];
43
static text_buf_t      *syntax_buf = NULL;
44

45
int64_t assume_int(tree_t t)
376,193✔
46
{
47
   int64_t value;
376,193✔
48
   if (folded_int(t, &value))
376,193✔
49
      return value;
376,193✔
50

51
   fatal_at(tree_loc(t), "expression cannot be folded to "
×
52
            "an integer constant");
53
}
54

55
void range_bounds(tree_t r, int64_t *low, int64_t *high)
28,372✔
56
{
57
   assert(tree_kind(r) == T_RANGE);
28,372✔
58

59
   const int64_t left = assume_int(tree_left(r));
28,372✔
60
   const int64_t right = assume_int(tree_right(r));
28,372✔
61

62
   *low  = tree_subkind(r) == RANGE_TO ? left : right;
28,372✔
63
   *high = tree_subkind(r) == RANGE_TO ? right : left;
28,372✔
64
}
28,372✔
65

66
bool folded_int(tree_t t, int64_t *l)
3,625,798✔
67
{
68
   switch (tree_kind(t)) {
3,659,336✔
69
   case T_LITERAL:
2,647,286✔
70
      switch (tree_subkind(t)) {
2,647,286✔
71
      case L_PHYSICAL:
16,583✔
72
         if (tree_has_ref(t))
16,583✔
73
            return false;
74
         // Fall-through
75
      case L_INT:
76
         *l = tree_ival(t);
2,600,668✔
77
         return true;
2,600,668✔
78
      default:
79
         return false;
80
      }
81
   case T_QUALIFIED:
362✔
82
      return folded_int(tree_value(t), l);
362✔
83
   case T_REF:
797,401✔
84
      if (tree_has_ref(t)) {
797,401✔
85
         tree_t decl = tree_ref(t);
797,400✔
86
         switch (tree_kind(decl)) {
797,400✔
87
         case T_CONST_DECL:
40,847✔
88
            if (tree_has_value(decl))
40,847✔
89
               return folded_int(tree_value(decl), l);
32,837✔
90
            else
91
               return false;
92
         case T_ENUM_LIT:
686,297✔
93
            *l = tree_pos(decl);
686,297✔
94
            return true;
686,297✔
95
         case T_ALIAS:
339✔
96
            return folded_int(tree_value(decl), l);
339✔
97
         default:
98
            return false;
99
         }
100
      }
101
      // Fall-through
102
   default:
103
      return false;
104
   }
105
}
106

107
bool folded_real(tree_t t, double *l)
195,652✔
108
{
109
   switch (tree_kind(t)) {
195,655✔
110
   case T_LITERAL:
187,393✔
111
      if (tree_subkind(t) == L_REAL) {
187,393✔
112
         *l = tree_dval(t);
187,322✔
113
         return true;
187,322✔
114
      }
115
      else
116
         return false;
117
   case T_QUALIFIED:
3✔
118
      return folded_real(tree_value(t), l);
3✔
119
   default:
120
      return false;
121
   }
122
}
123

124
bool folded_length(tree_t r, int64_t *l)
55,679✔
125
{
126
   int64_t low, high;
55,679✔
127
   if (folded_bounds(r, &low, &high)) {
55,679✔
128
      *l = MAX(high - low + 1, 0);
52,847✔
129
      return true;
52,847✔
130
   }
131
   else
132
      return false;
133
}
134

135
bool folded_bounds(tree_t r, int64_t *low, int64_t *high)
1,497,326✔
136
{
137
   assert(tree_kind(r) == T_RANGE);
1,497,326✔
138

139
   const range_kind_t rkind = tree_subkind(r);
1,497,326✔
140

141
   if (rkind != RANGE_TO && rkind != RANGE_DOWNTO)
1,497,326✔
142
      return false;
143

144
   int64_t left, right;
1,484,774✔
145
   if (!folded_int(tree_left(r), &left))
1,484,774✔
146
      return false;
147
   else if (!folded_int(tree_right(r), &right))
1,373,055✔
148
      return false;
149

150
   switch (rkind) {
1,336,928✔
151
   case RANGE_TO:
1,213,573✔
152
      *low  = left;
1,213,573✔
153
      *high = right;
1,213,573✔
154
      return true;
1,213,573✔
155
   case RANGE_DOWNTO:
123,355✔
156
      *low  = right;
123,355✔
157
      *high = left;
123,355✔
158
      return true;
123,355✔
159
   default:
160
      return false;
161
   }
162
}
163

164
bool folded_bounds_real(tree_t r, double *low, double *high)
78,119✔
165
{
166
   assert(tree_kind(r) == T_RANGE);
78,119✔
167

168
   const range_kind_t rkind = tree_subkind(r);
78,119✔
169

170
   if (rkind != RANGE_TO && rkind != RANGE_DOWNTO)
78,119✔
171
      return false;
172

173
   double left, right;
78,116✔
174
   if (folded_real(tree_left(r), &left) && folded_real(tree_right(r), &right)) {
78,116✔
175
      switch (rkind) {
78,031✔
176
      case RANGE_TO:
78,031✔
177
         *low  = left;
78,031✔
178
         *high = right;
78,031✔
179
         return true;
78,031✔
180
      case RANGE_DOWNTO:
×
181
         *low  = right;
×
182
         *high = left;
×
183
         return true;
×
184
      default:
185
         return false;
186
      }
187
   }
188
   else
189
      return false;
85✔
190
}
191

192
bool folded_bool(tree_t t, bool *b)
40,700✔
193
{
194
   if (tree_kind(t) == T_REF) {
40,700✔
195
      tree_t decl = tree_ref(t);
10,560✔
196
      if (tree_kind(decl) == T_ENUM_LIT
10,560✔
197
          && type_ident(tree_type(decl)) == well_known(W_STD_BOOL)) {
8,148✔
198
         *b = (tree_pos(decl) == 1);
8,148✔
199
         return true;
8,148✔
200
      }
201
   }
202

203
   return false;
204
}
205

206
tree_t get_enum_lit(tree_t t, type_t type, int pos)
7,378✔
207
{
208
   type_t enum_type = type_base_recur(type ?: tree_type(t));
7,378✔
209
   tree_t lit = type_enum_literal(enum_type, pos);
7,378✔
210

211
   tree_t b = tree_new(T_REF);
7,378✔
212
   tree_set_loc(b, tree_loc(t));
7,378✔
213
   tree_set_ref(b, lit);
7,378✔
214
   tree_set_type(b, enum_type);
7,378✔
215
   tree_set_ident(b, tree_ident(lit));
7,378✔
216

217
   return b;
7,378✔
218
}
219

220
tree_t get_int_lit(tree_t t, type_t type, int64_t i)
41,686✔
221
{
222
   tree_t f = tree_new(T_LITERAL);
41,686✔
223
   tree_set_subkind(f, L_INT);
41,686✔
224
   tree_set_ival(f, i);
41,686✔
225
   tree_set_loc(f, tree_loc(t));
41,686✔
226
   tree_set_type(f, type ?: tree_type(t));
41,686✔
227

228
   return f;
41,686✔
229
}
230

231
tree_t get_discrete_lit(tree_t t, type_t type, int64_t i)
3,458✔
232
{
233
   if (type_is_enum(type)) {
3,458✔
234
      type_t base = type_base_recur(type);
68✔
235
      const int maxlit = type_enum_literals(base);
68✔
236
      if (i >= maxlit)
68✔
237
         return NULL;
238
      else
239
         return get_enum_lit(t, type, i);
68✔
240
   }
241
   else
242
      return get_int_lit(t, type, i);
3,390✔
243
}
244

245
tree_t get_real_lit(tree_t t, type_t type, double r)
×
246
{
247
   tree_t f = tree_new(T_LITERAL);
×
248
   tree_set_loc(f, tree_loc(t));
×
249
   tree_set_subkind(f, L_REAL);
×
250
   tree_set_dval(f, r);
×
251
   tree_set_type(f, type ?: tree_type(t));
×
252

253
   return f;
×
254
}
255

256
bool parse_value(type_t type, const char *str, parsed_value_t *value)
92✔
257
{
258
   type_t base = type_base_recur(type);
92✔
259
   const type_kind_t basek = type_kind(base);
92✔
260

261
   if (basek == T_ARRAY && type_is_character_array(base)) {
92✔
262
      value->enums = NULL;
17✔
263

264
      int map[256];
17✔
265
      for (int i = 0; i < ARRAY_LEN(map); i++)
4,369✔
266
         map[i] = INT_MAX;
4,352✔
267

268
      type_t elem = type_elem(base);
17✔
269

270
      const int nlits = type_enum_literals(elem);
17✔
271
      for (int i = 0; i < nlits; i++) {
2,591✔
272
         ident_t id = tree_ident(type_enum_literal(elem, i));
2,574✔
273
         if (ident_char(id, 0) == '\'')
2,574✔
274
            map[(uint8_t)ident_char(id, 1)] = i;
1,924✔
275
      }
276

277
      while (map[(uint8_t)*str] == INT_MAX && isspace_iso88591(*str))
20✔
278
         ++str;
3✔
279

280
      const bool quoted = map['\"'] == INT_MAX && *str == '\"';
17✔
281
      if (quoted) str++;
17✔
282

283
      const size_t max = strlen(str);
17✔
284
      enum_array_t *array = xmalloc_flex(sizeof(enum_array_t), max, 1);
17✔
285

286
      int n = 0, m;
17✔
287
      for (; *str != '\0' && (m = map[(uint8_t)*str]) != INT_MAX; str++, n++)
99✔
288
         array->values[n] = m;
65✔
289

290
      assert(n <= max);
17✔
291
      array->count = n;
17✔
292

293
      if (quoted && *str++ != '\"') {
17✔
294
         free(array);
1✔
295
         return false;
1✔
296
      }
297

298
      for (; *str; str++) {
20✔
299
         if (!isspace_iso88591(*str)) {
5✔
300
            free(array);
1✔
301
            return false;
1✔
302
         }
303
      }
304

305
      value->enums = array;
15✔
306
      return true;
15✔
307
   }
308

309
   while (isspace_iso88591(*str))
85✔
310
      ++str;
10✔
311

312
   switch (basek) {
75✔
313
   case T_INTEGER:
50✔
314
      {
315
         const bool is_negative = *str == '-';
50✔
316
         int num_digits = 0;
50✔
317

318
         if (is_negative) ++str;
50✔
319

320
         int64_t sum = 0;
321
         for (; isdigit_iso88591(*str) || (*str == '_'); str++) {
144✔
322
            if (*str != '_') {
94✔
323
               sum *= 10;
92✔
324
               sum += (*str - '0');
92✔
325
               num_digits++;
92✔
326
            }
327
         }
328

329
         value->integer = is_negative ? -sum : sum;
50✔
330

331
         if (num_digits == 0)
50✔
332
            return false;
333
      }
334
      break;
335

336
   case T_ENUM:
14✔
337
      {
338
         bool upcase = true;
14✔
339
         char *copy LOCAL = xstrdup(str), *p;
27✔
340
         for (p = copy; (*p != '\0') && !isspace_iso88591(*p); p++, str++) {
55✔
341
            if (*p == '\'')
41✔
342
               upcase = false;
343
            if (upcase)
23✔
344
               *p = toupper_iso88591(*p);
14✔
345
         }
346
         *p = '\0';
14✔
347

348
         ident_t id = ident_new(copy);
14✔
349

350
         value->integer = -1;
14✔
351

352
         const int nlits = type_enum_literals(base);
14✔
353
         for (int i = 0; i < nlits; i++) {
38✔
354
            if (tree_ident(type_enum_literal(base, i)) == id) {
37✔
355
               value->integer = i;
13✔
356
               break;
13✔
357
            }
358
         }
359

360
         if (value->integer == -1)
14✔
361
            return false;
1✔
362
      }
363
      break;
364

365
   case T_REAL:
6✔
366
      {
367
         char *eptr = NULL;
6✔
368
         value->real = strtod(str, &eptr);
6✔
369
         str = eptr;
6✔
370
      }
371
      break;
6✔
372

373
   case T_PHYSICAL:
5✔
374
      {
375
         char *eptr = NULL;
5✔
376
         double scale = strtod(str, &eptr);
5✔
377
         str = eptr;
5✔
378

379
         while (isspace_iso88591(*str)) ++str;
10✔
380

381
         char *copy LOCAL = xstrdup(str), *p;
10✔
382
         for (p = copy; *p && !isspace_iso88591(*p); p++, str++)
13✔
383
            *p = toupper_iso88591(*p);
8✔
384
         *p = '\0';
5✔
385

386
         if (p == copy)
5✔
387
            return false;
388

389
         ident_t id = ident_new(copy);
4✔
390

391
         value->integer = -1;
4✔
392

393
         const int nunits = type_units(base);
4✔
394
         for (int i = 0; i < nunits; i++) {
11✔
395
            tree_t u = type_unit(base, i);
11✔
396
            if (tree_ident(u) == id) {
11✔
397
               value->integer = scale * assume_int(tree_value(u));
4✔
398
               break;
4✔
399
            }
400
         }
401

402
         if (value->integer == -1)
4✔
403
            return false;
404
      }
405
      break;
406

407
   default:
408
      return false;
409
   }
410

411
   for (; *str; str++) {
84✔
412
      if (!isspace_iso88591(*str))
11✔
413
         return false;
414
   }
415

416
   return true;
417
}
418

419
tree_t make_ref(tree_t to)
7,763✔
420
{
421
   tree_t t = tree_new(T_REF);
7,763✔
422
   tree_set_ident(t, tree_ident(to));
7,763✔
423
   tree_set_ref(t, to);
7,763✔
424
   tree_set_type(t, tree_type(to));
7,763✔
425
   return t;
7,763✔
426
}
427

428
vhdl_standard_t standard(void)
2,652,229✔
429
{
430
   return current_std;
2,652,229✔
431
}
432

433
void set_standard(vhdl_standard_t s)
4,934✔
434
{
435
   current_std = s;
4,934✔
436
   have_set_std = true;
4,934✔
437
}
4,934✔
438

439
void set_default_standard(vhdl_standard_t s)
453✔
440
{
441
   if (!have_set_std)
453✔
442
      set_standard(s);
82✔
443
}
453✔
444

445
const char *standard_text(vhdl_standard_t s)
4,498✔
446
{
447
   static const char *text[] = {
4,498✔
448
      "1987", "1993", "2000", "2002", "2008", "2019"
449
   };
450

451
   if ((unsigned)s < ARRAY_LEN(text))
4,498✔
452
      return text[s];
4,498✔
453
   else
454
      return "????";
455
}
456

457
tree_t find_record_field(tree_t rref)
9,069✔
458
{
459
   ident_t fname = tree_ident(rref);
9,069✔
460
   type_t value_type = tree_type(tree_value(rref));
9,069✔
461

462
   if (!type_is_record(value_type))
9,069✔
463
      return NULL;
464

465
   const int nfields = type_fields(value_type);
9,069✔
466
   for (int i = 0; i < nfields; i++) {
28,792✔
467
      tree_t field = type_field(value_type, i);
28,787✔
468
      if (tree_ident(field) == fname)
28,787✔
469
         return field;
9,064✔
470
   }
471

472
   return NULL;
473
}
474

475
tree_t find_element_mode_indication(tree_t view, tree_t field, bool *converse)
397✔
476
{
477
   switch (tree_kind(view)) {
1,255✔
478
   case T_REF:
541✔
479
      return find_element_mode_indication(tree_ref(view), field, converse);
541✔
480

481
   case T_ALIAS:
144✔
482
      return find_element_mode_indication(tree_value(view), field, converse);
144✔
483

484
   case T_ATTR_REF:
173✔
485
      assert(tree_subkind(view) == ATTR_CONVERSE);
173✔
486
      *converse = !*converse;
173✔
487
      return find_element_mode_indication(tree_name(view), field, converse);
173✔
488

489
   case T_VIEW_DECL:
397✔
490
      {
491
         type_t view_type = tree_type(view);
397✔
492
         assert(type_kind(view_type) == T_VIEW);
397✔
493

494
         const int nelems = type_fields(view_type);
397✔
495
         for (int i = 0; i < nelems; i++) {
673✔
496
            tree_t e = type_field(view_type, i);
673✔
497
            if (tree_ref(e) == field)
673✔
498
               return e;
397✔
499
         }
500

501
         return NULL;
502
      }
503

504
   default:
×
505
      fatal_trace("unhandled tree kind %s in find_element_mode_indication",
506
                  tree_kind_str(tree_kind(view)));
507
   }
508
}
509

510
port_mode_t converse_mode(tree_t port, bool converse)
265✔
511
{
512
   const port_mode_t mode = tree_subkind(port);
265✔
513
   switch (mode) {
265✔
514
   case PORT_IN: return converse ? PORT_OUT : PORT_IN;
135✔
515
   case PORT_OUT: return converse ? PORT_IN : PORT_OUT;
121✔
516
   default: return mode;
517
   }
518
}
519

520
class_t class_of(tree_t t)
1,022,768✔
521
{
522
   switch (tree_kind(t)) {
1,082,333✔
523
   case T_VAR_DECL:
524
      return C_VARIABLE;
525
   case T_SIGNAL_DECL:
45,392✔
526
   case T_IMPLICIT_SIGNAL:
527
      return C_SIGNAL;
45,392✔
528
   case T_CONST_DECL:
36,838✔
529
      return C_CONSTANT;
36,838✔
530
   case T_PORT_DECL:
152,811✔
531
   case T_GENERIC_DECL:
532
   case T_PARAM_DECL:
533
   case T_EXTERNAL_NAME:
534
      return tree_class(t);
152,811✔
535
   case T_ENUM_LIT:
594,401✔
536
   case T_LITERAL:
537
   case T_STRING:
538
      return C_LITERAL;
594,401✔
539
   case T_FIELD_DECL:
1,047✔
540
   case T_ATTR_DECL:
541
      return C_DEFAULT;
1,047✔
542
   case T_VIEW_DECL:
126✔
543
      return C_VIEW;
126✔
544
   case T_UNIT_DECL:
7,491✔
545
      return C_UNITS;
7,491✔
546
   case T_ARCH:
44✔
547
      return C_ARCHITECTURE;
44✔
548
   case T_FUNC_DECL:
5,142✔
549
   case T_FUNC_BODY:
550
   case T_FUNC_INST:
551
   case T_FCALL:
552
   case T_PROT_FCALL:
553
      return C_FUNCTION;
5,142✔
554
   case T_PROC_DECL:
10,059✔
555
   case T_PROC_BODY:
556
   case T_PROC_INST:
557
   case T_PCALL:
558
   case T_PROT_PCALL:
559
      return C_PROCEDURE;
10,059✔
560
   case T_ENTITY:
137✔
561
      return C_ENTITY;
137✔
562
   case T_SUBTYPE_DECL:
18,745✔
563
      return C_SUBTYPE;
18,745✔
564
   case T_TYPE_DECL:
71,625✔
565
   case T_PROT_DECL:
566
   case T_PROT_BODY:
567
      return C_TYPE;
71,625✔
568
   case T_FILE_DECL:
1,101✔
569
      return C_FILE;
1,101✔
570
   case T_PROCESS:
138✔
571
   case T_BLOCK:
572
   case T_FOR:
573
   case T_INSTANCE:
574
   case T_CONCURRENT:
575
   case T_ELAB:
576
   case T_PSL_DECL:
577
   case T_PSL_DIRECT:
578
   case T_FOR_GENERATE:
579
   case T_IF_GENERATE:
580
   case T_CASE_GENERATE:
581
      return C_LABEL;
138✔
582
   case T_COMPONENT:
1✔
583
      return C_COMPONENT;
1✔
584
   case T_REF:
50,859✔
585
   case T_PROT_REF:
586
      return tree_has_ref(t) ? class_of(tree_ref(t)) : C_DEFAULT;
50,859✔
587
   case T_ARRAY_REF:
8,711✔
588
   case T_ARRAY_SLICE:
589
   case T_RECORD_REF:
590
   case T_ALL:
591
   case T_ALIAS:
592
   case T_QUALIFIED:
593
      return class_of(tree_value(t));
8,711✔
594
   case T_PACKAGE:
1,225✔
595
   case T_PACK_BODY:
596
   case T_PACK_INST:
597
      return C_PACKAGE;
1,225✔
598
   case T_CONFIGURATION:
1✔
599
      return C_CONFIGURATION;
1✔
600
   case T_LIBRARY:
1✔
601
      return C_LIBRARY;
1✔
602
   case T_ATTR_REF:
86✔
603
      switch (tree_subkind(t)) {
86✔
604
      case ATTR_DELAYED:
605
      case ATTR_STABLE:
606
      case ATTR_QUIET:
607
      case ATTR_TRANSACTION:
608
         return C_SIGNAL;
609
      default:
80✔
610
         return C_DEFAULT;
80✔
611
      }
612
   case T_CONTEXT:
×
613
      return C_CONTEXT;
×
UNCOV
614
   default:
×
615
      fatal_trace("missing class_of for %s", tree_kind_str(tree_kind(t)));
616
   }
617
}
618

619
bool class_has_type(class_t c)
860,926✔
620
{
621
   switch (c) {
860,926✔
622
   case C_LABEL:
623
   case C_ENTITY:
624
   case C_ARCHITECTURE:
625
   case C_COMPONENT:
626
   case C_CONFIGURATION:
627
   case C_PACKAGE:
628
   case C_LIBRARY:
629
      return false;
630
   default:
859,648✔
631
      return true;
859,648✔
632
   }
633
}
634

635
const char *class_str(class_t c)
326✔
636
{
637
   static const char *strs[] = {
326✔
638
      "default", "signal", "variable", "constant", "file", "entity",
639
      "component", "configuration", "architecture", "function", "package",
640
      "type", "subtype", "label", "procedure", "literal", "units", "library",
641
      "context", "view",
642
   };
643
   assert(c < ARRAY_LEN(strs));
326✔
644
   return strs[c];
326✔
645
}
646

647
const char *assoc_kind_str(assoc_kind_t akind)
9✔
648
{
649
   switch (akind) {
9✔
650
   case A_NAMED:  return "named";
651
   case A_CONCAT:
2✔
652
   case A_POS:    return "positional";
2✔
653
   case A_OTHERS: return "others";
3✔
654
   case A_SLICE:
1✔
655
   case A_RANGE:  return "range";
1✔
UNCOV
656
   default:       return "??";
×
657
   }
658
}
659

660
bool is_subprogram(tree_t t)
792,566✔
661
{
662
   switch (tree_kind(t)) {
792,566✔
663
   case T_FUNC_DECL:
664
   case T_FUNC_BODY:
665
   case T_FUNC_INST:
666
   case T_PROC_DECL:
667
   case T_PROC_BODY:
668
   case T_PROC_INST:
669
      return true;
670
   case T_GENERIC_DECL:
2,858✔
671
      {
672
         const class_t class = tree_class(t);
2,858✔
673
         return class == C_FUNCTION || class == C_PROCEDURE;
2,858✔
674
      }
675
   default:
622,879✔
676
      return false;
622,879✔
677
   }
678
}
679

680
bool is_loop_stmt(tree_t t)
421✔
681
{
682
   const tree_kind_t kind = tree_kind(t);
421✔
683
   return kind == T_WHILE || kind == T_FOR || kind == T_LOOP;
421✔
684
}
685

686
bool is_container(tree_t t)
10,364✔
687
{
688
   switch (tree_kind(t)) {
10,364✔
689
   case T_FUNC_BODY:
690
   case T_PROC_BODY:
691
   case T_ENTITY:
692
   case T_ARCH:
693
   case T_PACKAGE:
694
   case T_PACK_BODY:
695
   case T_CONFIGURATION:
696
   case T_BLOCK:
697
   case T_PROT_BODY:
698
   case T_ELAB:
699
   case T_FOR:
700
   case T_PROCESS:
701
   case T_PACK_INST:
702
      return true;
703
   default:
8,065✔
704
      return false;
8,065✔
705
   }
706
}
707

708
bool is_concurrent_block(tree_t t)
1,109✔
709
{
710
   switch (tree_kind(t)) {
1,109✔
711
   case T_ARCH:
712
   case T_ENTITY:
713
   case T_BLOCK:
714
   case T_IF_GENERATE:
715
   case T_FOR_GENERATE:
716
      return true;
717
   default:
370✔
718
      return false;
370✔
719
   }
720
}
721

722
bool is_package(tree_t t)
45,327✔
723
{
724
   switch (tree_kind(t)) {
45,327✔
725
   case T_PACKAGE:
726
   case T_PACK_BODY:
727
   case T_PACK_INST:
728
      return true;
729
   default:
929✔
730
      return false;
929✔
731
   }
732
}
733

734
bool is_design_unit(tree_t t)
38,183✔
735
{
736
   switch (tree_kind(t)) {
38,183✔
737
   case T_ENTITY:
738
   case T_ARCH:
739
   case T_PACKAGE:
740
   case T_PACK_BODY:
741
   case T_CONFIGURATION:
742
   case T_CONTEXT:
743
   case T_PACK_INST:
744
      return true;
745
   default:
8,456✔
746
      return false;
8,456✔
747
   }
748
}
749

750
bool is_literal(tree_t t)
31,958✔
751
{
752
   switch (tree_kind(t)) {
31,958✔
753
   case T_REF:
4,287✔
754
      return tree_has_ref(t) && tree_kind(tree_ref(t)) == T_ENUM_LIT;
7,555✔
755
   case T_LITERAL:
756
      return true;
757
   case T_STRING:
22,207✔
758
   default:
759
      return false;
22,207✔
760
   }
761
}
762

763
bool is_body(tree_t t)
6,998✔
764
{
765
   switch (tree_kind(t)) {
6,998✔
766
   case T_FUNC_BODY:
767
   case T_PROC_BODY:
768
   case T_PACK_BODY:
769
   case T_PROT_BODY:
770
      return true;
771
   default:
43✔
772
      return false;
43✔
773
   }
774
}
775

776
bool is_guarded_signal(tree_t decl)
13,728✔
777
{
778
   switch (tree_kind(decl)) {
13,728✔
779
   case T_PORT_DECL:
13,335✔
780
   case T_SIGNAL_DECL:
781
      return !!(tree_flags(decl) & (TREE_F_BUS | TREE_F_REGISTER));
13,335✔
782
   default:
783
      return false;
784
   }
785
}
786

787
bool is_type_decl(tree_t t)
985,751✔
788
{
789
   switch (tree_kind(t)) {
985,751✔
790
   case T_TYPE_DECL:
791
   case T_SUBTYPE_DECL:
792
   case T_PROT_DECL:
793
   case T_PROT_BODY:
794
      return true;
795
   default:
808,901✔
796
      return false;
808,901✔
797
   }
798
}
799

800
tree_t aliased_type_decl(tree_t decl)
124,030✔
801
{
802
   switch (tree_kind(decl)) {
124,294✔
803
   case T_ALIAS:
266✔
804
      {
805
         tree_t value = tree_value(decl);
266✔
806
         const tree_kind_t kind = tree_kind(value);
266✔
807
         if (kind == T_REF && tree_has_ref(value))
266✔
808
            return aliased_type_decl(tree_ref(value));
264✔
809
         else if (kind == T_ATTR_REF && is_type_attribute(tree_subkind(value)))
2✔
810
             return value;
811
         else
UNCOV
812
            return NULL;
×
813
      }
814
   case T_TYPE_DECL:
815
   case T_SUBTYPE_DECL:
816
   case T_PROT_DECL:
817
   case T_PROT_BODY:
818
      return decl;
819
   case T_GENERIC_DECL:
1,521✔
820
      if (tree_class(decl) == C_TYPE)
1,521✔
821
         return decl;
822
      else
823
         return NULL;
740✔
824
   default:
28,994✔
825
      return NULL;
28,994✔
826
   }
827
}
828

829
tree_t add_param(tree_t call, tree_t value, param_kind_t kind, tree_t name)
158,289✔
830
{
831
   tree_t p = tree_new(T_PARAM);
158,289✔
832
   tree_set_loc(p, tree_loc(value));
158,289✔
833
   tree_set_subkind(p, kind);
158,289✔
834
   tree_set_value(p, value);
158,289✔
835

836
   switch (kind) {
158,289✔
837
   case P_NAMED:
74✔
838
      assert(name != NULL);
74✔
839
      tree_set_name(p, name);
74✔
840
      break;
74✔
841
   case P_POS:
158,215✔
842
      tree_set_pos(p, tree_params(call));
158,215✔
843
      break;
158,215✔
844
   }
845

846
   tree_add_param(call, p);
158,289✔
847
   return p;
158,289✔
848
}
849

850
type_t array_aggregate_type(type_t array, int from_dim)
291✔
851
{
852
   if (type_is_none(array))
291✔
853
      return type_new(T_NONE);
2✔
854

855
   if (type_is_unconstrained(array)) {
289✔
856
      const int nindex = type_indexes(array);
45✔
857
      assert(from_dim < nindex);
45✔
858

859
      type_t type = type_new(T_ARRAY);
45✔
860
      type_set_ident(type, type_ident(array));
45✔
861
      type_set_elem(type, type_elem(array));
45✔
862

863
      for (int i = from_dim; i < nindex; i++)
90✔
864
         type_add_index(type, type_index(array, i));
45✔
865

866
      return type;
867
   }
868
   else {
869
      const int ndims = dimension_of(array);
244✔
870
      assert(from_dim < ndims);
244✔
871

872
      type_t base = type_new(T_ARRAY);
244✔
873
      type_set_ident(base, type_ident(array));
244✔
874
      type_set_elem(base, type_elem(array));
244✔
875

876
      tree_t constraint = tree_new(T_CONSTRAINT);
244✔
877
      tree_set_subkind(constraint, C_INDEX);
244✔
878

879
      type_t sub = type_new(T_SUBTYPE);
244✔
880
      type_set_base(sub, base);
244✔
881
      type_add_constraint(sub, constraint);
244✔
882

883
      for (int i = from_dim; i < ndims; i++) {
510✔
884
         tree_t r = range_of(array, i);
266✔
885
         if (r == NULL) {
266✔
886
            // Not enough constraints were provided for the type
887
            r = tree_new(T_RANGE);
1✔
888
            tree_set_subkind(r, RANGE_ERROR);
1✔
889
            tree_set_type(r, type_new(T_NONE));
1✔
890
         }
891

892
         type_add_index(base, tree_type(r));
266✔
893
         tree_add_range(constraint, r);
266✔
894
      }
895

896
      return sub;
897
   }
898
}
899

900
unsigned bits_for_range(int64_t low, int64_t high)
1,679,997✔
901
{
902
   if (low > high)
1,679,997✔
903
      return 0;   // Null range
904
   else if (low < 0) {
1,679,996✔
905
      // Signed integers
906
      if (low >= INT8_MIN && high <= INT8_MAX)
516,000✔
907
         return 8;
908
      else if (low >= INT16_MIN && high <= INT16_MAX)
509,029✔
909
         return 16;
910
      else if (low >= INT32_MIN && high <= INT32_MAX)
508,798✔
911
         return 32;
912
      else
913
         return 64;
113,796✔
914
   }
915
   else {
916
      // Unsigned integers
917
      if (high <= 1)
1,163,996✔
918
         return 1;
919
      else if (high <= UINT8_MAX)
576,895✔
920
         return 8;
921
      else if (high <= UINT16_MAX)
137,720✔
922
         return 16;
923
      else if (high <= UINT32_MAX)
134,399✔
924
         return 32;
925
      else
926
         return 64;
15,946✔
927
   }
928
}
929

930
unsigned dimension_of(type_t type)
1,197,100✔
931
{
932
   switch (type_kind(type)) {
2,235,666✔
933
   case T_SUBTYPE:
1,038,564✔
934
      return dimension_of(type_base(type));
1,038,564✔
935
   case T_GENERIC:
133✔
936
      switch (type_subkind(type)) {
133✔
937
      case GTYPE_ARRAY:
121✔
938
         return type_indexes(type);
121✔
939
      case GTYPE_ACCESS:
×
UNCOV
940
         return dimension_of(type_designated(type));
×
941
      case GTYPE_FILE:
942
      case GTYPE_PRIVATE:
943
         return 0;
944
      default:
12✔
945
         return 1;
12✔
946
      }
947
   case T_ARRAY:
1,189,974✔
948
      return type_indexes(type);
1,189,974✔
949
   case T_NONE:
950
   case T_RECORD:
951
   case T_INCOMPLETE:
952
      return 0;
953
   case T_INTEGER:
6,937✔
954
   case T_REAL:
955
   case T_PHYSICAL:
956
   case T_ENUM:
957
      return type_dims(type);
6,937✔
958
   case T_ACCESS:
2✔
959
      return dimension_of(type_designated(type));
2✔
UNCOV
960
   default:
×
961
      fatal_trace("invalid type kind %s in dimension_of",
962
                  type_kind_str(type_kind(type)));
963
   }
964
}
965

966
tree_t range_of(type_t type, unsigned dim)
1,533,035✔
967
{
968
   switch (type_kind(type)) {
1,565,780✔
969
   case T_SUBTYPE:
1,225,915✔
970
      if (type_constraints(type) > 0) {
1,225,915✔
971
         tree_t c0 = type_constraint(type, 0);
1,193,392✔
972
         switch (tree_subkind(c0)) {
1,193,392✔
973
         case C_OPEN:
222✔
974
            return range_of(type_base(type), dim);
222✔
975
         case C_INDEX:
1,193,170✔
976
         case C_RANGE:
977
            if (dim < tree_ranges(c0))
1,193,170✔
978
               return tree_range(c0, dim);
1,193,169✔
979
            else
980
               return NULL;   // Must be an error
UNCOV
981
         default:
×
982
            fatal_trace("invalid constraint in range_of");
983
         }
984
      }
985
      else
986
         return range_of(type_base(type), dim);
32,523✔
987
   case T_INTEGER:
339,865✔
988
   case T_REAL:
989
   case T_PHYSICAL:
990
   case T_ENUM:
991
      return type_dim(type, dim);
339,865✔
UNCOV
992
   default:
×
993
      fatal_trace("invalid type kind %s in range_of",
994
                  type_kind_str(type_kind(type)));
995
   }
996
}
997

998
range_kind_t direction_of(type_t type, unsigned dim)
24,532✔
999
{
1000
   switch (type_kind(type)) {
24,576✔
1001
   case T_ENUM:
1002
      return RANGE_TO;
1003
   case T_NONE:
×
UNCOV
1004
      return RANGE_ERROR;
×
1005
   case T_INTEGER:
24,471✔
1006
   case T_REAL:
1007
   case T_PHYSICAL:
1008
   case T_SUBTYPE:
1009
      {
1010
         tree_t r = range_of(type, dim);
24,471✔
1011
         const range_kind_t rkind = tree_subkind(r);
24,471✔
1012
         if (rkind == RANGE_EXPR) {
24,471✔
1013
            // Return a fixed direction if possible
1014
            tree_t value = tree_value(r);
113✔
1015
            assert(tree_kind(value) == T_ATTR_REF);
113✔
1016

1017
            DEBUG_ONLY({
113✔
1018
                  const attr_kind_t attr = tree_subkind(value);
1019
                  assert(attr == ATTR_RANGE || attr == ATTR_REVERSE_RANGE);
1020
               });
113✔
1021

1022
            tree_t name = tree_name(value);
113✔
1023
            if (tree_kind(name) == T_REF && tree_has_ref(name)) {
113✔
1024
               tree_t decl = tree_ref(name);
112✔
1025
               if (is_type_decl(decl))
112✔
1026
                  return direction_of(tree_type(decl), 0);
44✔
1027
            }
1028
         }
1029

1030
         return rkind;
1031
      }
UNCOV
1032
   default:
×
1033
      fatal_trace("invalid type kind %s in direction_of",
1034
                  type_kind_str(type_kind(type)));
1035
   }
1036
}
1037

1038
type_t index_type_of(type_t type, unsigned dim)
211,450✔
1039
{
1040
   if (dim >= dimension_of(type))
211,452✔
1041
      return NULL;
1042

1043
   type_t base = type_base_recur(type);
211,426✔
1044
   type_kind_t base_kind = type_kind(base);
211,426✔
1045
   if (base_kind == T_ARRAY)
211,426✔
1046
      return type_index(base, dim);
208,111✔
1047
   else if (base_kind == T_ENUM || base_kind == T_NONE)
3,315✔
1048
      return type;
1049
   else if (base_kind == T_GENERIC && type_subkind(base) == GTYPE_ARRAY)
3,161✔
1050
      return type_index(base, dim);
74✔
1051
   else if (base_kind == T_RECORD || base_kind == T_GENERIC)
3,087✔
1052
      return NULL;
1053
   else if (base_kind == T_ACCESS)
3,081✔
1054
      return index_type_of(type_designated(type), dim);
2✔
1055
   else
1056
      return tree_type(range_of(base, dim));
3,079✔
1057
}
1058

1059
int64_t rebase_index(type_t array_type, int dim, int64_t value)
240✔
1060
{
1061
   // Convert value which is in the range of array_type to a zero-based index
1062
   tree_t r = range_of(array_type, dim);
240✔
1063
   const int64_t left = assume_int(tree_left(r));
240✔
1064
   return (tree_subkind(r) == RANGE_TO) ? value - left : left - value;
240✔
1065
}
1066

1067
ident_t well_known(well_known_t id)
402,318✔
1068
{
1069
   assert(id < NUM_WELL_KNOWN);
402,318✔
1070
   return id_cache[id];
402,318✔
1071
}
1072

1073
well_known_t is_well_known(ident_t ident)
269,999✔
1074
{
1075
   well_known_t pos = 0;
269,999✔
1076
   for (; pos < NUM_WELL_KNOWN; pos++) {
14,323,270✔
1077
      if (id_cache[pos] == ident)
14,185,454✔
1078
         break;
1079
   }
1080

1081
   return pos;
269,999✔
1082
}
1083

1084
void intern_strings(void)
5,080✔
1085
{
1086
   id_cache[W_STD_STANDARD]    = ident_new("STD.STANDARD");
5,080✔
1087
   id_cache[W_ALL]             = ident_new("all");
5,080✔
1088
   id_cache[W_STD_BIT]         = ident_new("STD.STANDARD.BIT");
5,080✔
1089
   id_cache[W_STD_BOOL]        = ident_new("STD.STANDARD.BOOLEAN");
5,080✔
1090
   id_cache[W_STD_CHAR]        = ident_new("STD.STANDARD.CHARACTER");
5,080✔
1091
   id_cache[W_STD_NATURAL]     = ident_new("STD.STANDARD.NATURAL");
5,080✔
1092
   id_cache[W_STD_POSITIVE]    = ident_new("STD.STANDARD.POSITIVE");
5,080✔
1093
   id_cache[W_STD_INTEGER]     = ident_new("STD.STANDARD.INTEGER");
5,080✔
1094
   id_cache[W_STD_STRING]      = ident_new("STD.STANDARD.STRING");
5,080✔
1095
   id_cache[W_STD_REAL]        = ident_new("STD.STANDARD.REAL");
5,080✔
1096
   id_cache[W_STD_TIME]        = ident_new("STD.STANDARD.TIME");
5,080✔
1097
   id_cache[W_STD_BIT_VECTOR]  = ident_new("STD.STANDARD.BIT_VECTOR");
5,080✔
1098
   id_cache[W_IEEE_SIGNED]     = ident_new("IEEE.NUMERIC_STD.SIGNED");
5,080✔
1099
   id_cache[W_IEEE_UNSIGNED]   = ident_new("IEEE.NUMERIC_STD.UNSIGNED");
5,080✔
1100
   id_cache[W_IEEE_LOGIC]      = ident_new("IEEE.STD_LOGIC_1164.STD_LOGIC");
5,080✔
1101
   id_cache[W_IEEE_ULOGIC]     = ident_new("IEEE.STD_LOGIC_1164.STD_ULOGIC");
5,080✔
1102
   id_cache[W_IEEE_1164_AND]   = ident_new("IEEE.STD_LOGIC_1164.\"and\"");
5,080✔
1103
   id_cache[W_IEEE_1164_NAND]  = ident_new("IEEE.STD_LOGIC_1164.\"nand\"");
5,080✔
1104
   id_cache[W_IEEE_1164_OR]    = ident_new("IEEE.STD_LOGIC_1164.\"or\"");
5,080✔
1105
   id_cache[W_IEEE_1164_NOR]   = ident_new("IEEE.STD_LOGIC_1164.\"nor\"");
5,080✔
1106
   id_cache[W_IEEE_1164_XOR]   = ident_new("IEEE.STD_LOGIC_1164.\"xor\"");
5,080✔
1107
   id_cache[W_IEEE_1164_XNOR]  = ident_new("IEEE.STD_LOGIC_1164.\"xnor\"");
5,080✔
1108
   id_cache[W_FOREIGN]         = ident_new("FOREIGN");
5,080✔
1109
   id_cache[W_WORK]            = ident_new("WORK");
5,080✔
1110
   id_cache[W_STD]             = ident_new("STD");
5,080✔
1111
   id_cache[W_THUNK]           = ident_new("thunk");
5,080✔
1112
   id_cache[W_BODY]            = ident_new("body");
5,080✔
1113
   id_cache[W_CARET]           = ident_new("^");
5,080✔
1114
   id_cache[W_IEEE]            = ident_new("IEEE");
5,080✔
1115
   id_cache[W_IEEE_1164]       = ident_new("IEEE.STD_LOGIC_1164");
5,080✔
1116
   id_cache[W_ERROR]           = ident_new("error");
5,080✔
1117
   id_cache[W_ELAB]            = ident_new("elab");
5,080✔
1118
   id_cache[W_NUMERIC_STD]     = ident_new("IEEE.NUMERIC_STD");
5,080✔
1119
   id_cache[W_NUMERIC_BIT]     = ident_new("IEEE.NUMERIC_BIT");
5,080✔
1120
   id_cache[W_NVC]             = ident_new("NVC");
5,080✔
1121
   id_cache[W_DEFAULT_CLOCK]   = ident_new("default clock");
5,080✔
1122
   id_cache[W_STD_REFLECTION]  = ident_new("STD.REFLECTION");
5,080✔
1123
   id_cache[W_NEVER_WAITS]     = ident_new("NEVER_WAITS");
5,080✔
1124
   id_cache[W_NVC_VERILOG]     = ident_new("NVC.VERILOG");
5,080✔
1125
   id_cache[W_NVC_PSL_SUPPORT] = ident_new("NVC.PSL_SUPPORT");
5,080✔
1126
   id_cache[W_SHAPE]           = ident_new("shape");
5,080✔
1127
   id_cache[W_INSTANCE_NAME]   = ident_new("instance_name");
5,080✔
1128
   id_cache[W_PATH_NAME]       = ident_new("path_name");
5,080✔
1129
   id_cache[W_VITAL]           = ident_new("VITAL");
5,080✔
1130

1131
   id_cache[W_IEEE_LOGIC_VECTOR] =
10,160✔
1132
      ident_new("IEEE.STD_LOGIC_1164.STD_LOGIC_VECTOR");
5,080✔
1133
   id_cache[W_IEEE_ULOGIC_VECTOR] =
10,160✔
1134
      ident_new("IEEE.STD_LOGIC_1164.STD_ULOGIC_VECTOR");
5,080✔
1135
   id_cache[W_IEEE_1164_RISING_EDGE] =
10,160✔
1136
      ident_new("IEEE.STD_LOGIC_1164.RISING_EDGE(sU)B");
5,080✔
1137
   id_cache[W_IEEE_1164_FALLING_EDGE] =
10,160✔
1138
      ident_new("IEEE.STD_LOGIC_1164.FALLING_EDGE(sU)B");
5,080✔
1139

1140
   id_cache[W_NUMERIC_STD_UNSIGNED] = ident_new("IEEE.NUMERIC_STD_UNSIGNED");
5,080✔
1141
   id_cache[W_NUMERIC_BIT_UNSIGNED] = ident_new("IEEE.NUMERIC_BIT_UNSIGNED");
5,080✔
1142

1143
   id_cache[W_OP_CCONV]               = ident_new("\"??\"");
5,080✔
1144
   id_cache[W_OP_AND]                 = ident_new("\"and\"");
5,080✔
1145
   id_cache[W_OP_OR]                  = ident_new("\"or\"");
5,080✔
1146
   id_cache[W_OP_NAND]                = ident_new("\"nand\"");
5,080✔
1147
   id_cache[W_OP_NOR]                 = ident_new("\"nor\"");
5,080✔
1148
   id_cache[W_OP_XOR]                 = ident_new("\"xor\"");
5,080✔
1149
   id_cache[W_OP_XNOR]                = ident_new("\"xnor\"");
5,080✔
1150
   id_cache[W_OP_EQUAL]               = ident_new("\"=\"");
5,080✔
1151
   id_cache[W_OP_NOT_EQUAL]           = ident_new("\"/=\"");
5,080✔
1152
   id_cache[W_OP_LESS_THAN]           = ident_new("\"<\"");
5,080✔
1153
   id_cache[W_OP_LESS_EQUAL]          = ident_new("\"<=\"");
5,080✔
1154
   id_cache[W_OP_GREATER_THAN]        = ident_new("\">\"");
5,080✔
1155
   id_cache[W_OP_GREATER_EQUAL]       = ident_new("\">=\"");
5,080✔
1156
   id_cache[W_OP_MATCH_EQUAL]         = ident_new("\"?=\"");
5,080✔
1157
   id_cache[W_OP_MATCH_NOT_EQUAL]     = ident_new("\"?/=\"");
5,080✔
1158
   id_cache[W_OP_MATCH_LESS_THAN]     = ident_new("\"?<\"");
5,080✔
1159
   id_cache[W_OP_MATCH_LESS_EQUAL]    = ident_new("\"?<=\"");
5,080✔
1160
   id_cache[W_OP_MATCH_GREATER_THAN]  = ident_new("\"?>\"");
5,080✔
1161
   id_cache[W_OP_MATCH_GREATER_EQUAL] = ident_new("\"?>=\"");
5,080✔
1162
   id_cache[W_OP_SLL]                 = ident_new("\"sll\"");
5,080✔
1163
   id_cache[W_OP_SRL]                 = ident_new("\"srl\"");
5,080✔
1164
   id_cache[W_OP_SLA]                 = ident_new("\"sla\"");
5,080✔
1165
   id_cache[W_OP_SRA]                 = ident_new("\"sra\"");
5,080✔
1166
   id_cache[W_OP_ROL]                 = ident_new("\"rol\"");
5,080✔
1167
   id_cache[W_OP_ROR]                 = ident_new("\"ror\"");
5,080✔
1168
   id_cache[W_OP_ADD]                 = ident_new("\"+\"");
5,080✔
1169
   id_cache[W_OP_MINUS]               = ident_new("\"-\"");
5,080✔
1170
   id_cache[W_OP_CONCAT]              = ident_new("\"&\"");
5,080✔
1171
   id_cache[W_OP_TIMES]               = ident_new("\"*\"");
5,080✔
1172
   id_cache[W_OP_DIVIDE]              = ident_new("\"/\"");
5,080✔
1173
   id_cache[W_OP_MOD]                 = ident_new("\"mod\"");
5,080✔
1174
   id_cache[W_OP_REM]                 = ident_new("\"rem\"");
5,080✔
1175
   id_cache[W_OP_EXPONENT]            = ident_new("\"**\"");
5,080✔
1176
   id_cache[W_OP_ABS]                 = ident_new("\"abs\"");
5,080✔
1177
   id_cache[W_OP_NOT]                 = ident_new("\"not\"");
5,080✔
1178
}
5,080✔
1179

1180
bool is_uninstantiated_package(tree_t pack)
35,959✔
1181
{
1182
   return tree_kind(pack) == T_PACKAGE
35,959✔
1183
      && tree_generics(pack) > 0
34,830✔
1184
      && tree_genmaps(pack) == 0;
37,235✔
1185
}
1186

1187
bool is_uninstantiated_subprogram(tree_t decl)
98,486✔
1188
{
1189
   switch (tree_kind(decl)) {
98,486✔
1190
   case T_FUNC_DECL:
97,951✔
1191
   case T_FUNC_BODY:
1192
   case T_PROC_DECL:
1193
   case T_PROC_BODY:
1194
      return tree_generics(decl) > 0;
97,951✔
1195
   default:
1196
      return false;
1197
   }
1198
}
1199

1200
bool is_anonymous_subtype(type_t type)
147,026✔
1201
{
1202
   return type_kind(type) == T_SUBTYPE && !type_has_ident(type);
147,026✔
1203
}
1204

1205
bool unit_needs_cgen(tree_t unit)
194✔
1206
{
1207
   switch (tree_kind(unit)) {
194✔
1208
   case T_PACK_INST:
1209
      return true;
UNCOV
1210
   case T_PACK_BODY:
×
1211
      {
1212
         tree_t pack = tree_primary(unit);
×
UNCOV
1213
         return package_needs_body(pack) && !is_uninstantiated_package(pack);
×
1214
      }
1215
   case T_PACKAGE:
12✔
1216
      return !package_needs_body(unit) && !is_uninstantiated_package(unit);
24✔
1217
   default:
×
UNCOV
1218
      return false;
×
1219
   }
1220
}
1221

1222
bool package_needs_body(tree_t pack)
1,831✔
1223
{
1224
   assert(tree_kind(pack) == T_PACKAGE);
1,831✔
1225

1226
   const int ndecls = tree_decls(pack);
1,831✔
1227
   for (int i = 0; i < ndecls; i++) {
83,201✔
1228
      tree_t d = tree_decl(pack, i);
82,714✔
1229
      const tree_kind_t dkind = tree_kind(d);
82,714✔
1230
      if ((dkind == T_FUNC_DECL || dkind == T_PROC_DECL)
82,714✔
1231
          && !(tree_flags(d) & TREE_F_PREDEFINED))
72,670✔
1232
         return true;
1233
      else if (dkind == T_CONST_DECL && !tree_has_value(d))
81,524✔
1234
         return true;
1235
      else if (dkind == T_PROT_DECL)
81,460✔
1236
         return true;
1237
   }
1238

1239
   return false;
1240
}
1241

1242
static tree_t cached_unit(tree_t hint, tree_t *cache, well_known_t lib_name,
13,690✔
1243
                          well_known_t unit_name)
1244
{
1245
   const vhdl_standard_t curr = standard();
13,690✔
1246

1247
   if (cache[curr] == NULL) {
13,690✔
1248
      if (hint != NULL)
4,276✔
1249
         cache[curr] = hint;
1,381✔
1250
      else {
1251
         lib_t std = lib_require(well_known(lib_name));
2,895✔
1252
         cache[curr] = lib_get(std, well_known(unit_name));
2,895✔
1253
         assert(cache[curr] != NULL);
2,895✔
1254
      }
1255
   }
1256

1257
   assert(hint == NULL || hint == cache[curr]);
13,690✔
1258
   return cache[curr];
13,690✔
1259
}
1260

1261
static tree_t cached_std(tree_t hint)
13,300✔
1262
{
1263
   static tree_t standard_cache[STD_19 + 1] = {};
13,300✔
1264
   return cached_unit(hint, standard_cache, W_STD, W_STD_STANDARD);
13,300✔
1265
}
1266

1267
static tree_t search_type_decls(tree_t container, ident_t name)
13,586✔
1268
{
1269
   const int ndecls = tree_decls(container);
13,586✔
1270

1271
   for (int i = 0; i < ndecls; i++) {
878,376✔
1272
      tree_t d = tree_decl(container, i);
878,376✔
1273
      if (is_type_decl(d) && tree_ident(d) == name)
878,376✔
1274
         return d;
13,586✔
1275
   }
1276

1277
   return NULL;
1278
}
1279

1280
type_t std_type(tree_t std, std_type_t which)
938,060✔
1281
{
1282
   static type_t cache[STD_FILE_OPEN_STATE + 1] = {};
938,060✔
1283
   assert(which < ARRAY_LEN(cache));
938,060✔
1284

1285
   if (cache[which] == NULL) {
938,060✔
1286
      const char *names[] = {
13,300✔
1287
         "universal_integer",
1288
         "universal_real",
1289
         "INTEGER",
1290
         "REAL",
1291
         "BOOLEAN",
1292
         "STRING",
1293
         "TIME",
1294
         "BIT",
1295
         "FILE_OPEN_KIND",
1296
         "FILE_OPEN_STATUS",
1297
         "NATURAL",
1298
         "BIT_VECTOR",
1299
         "SEVERITY_LEVEL",
1300
         "FILE_ORIGIN_KIND",
1301
         "FILE_OPEN_STATE",
1302
      };
1303

1304
      tree_t d = search_type_decls(cached_std(std), ident_new(names[which]));
13,300✔
1305
      if (d == NULL)
13,300✔
1306
         fatal_trace("cannot find standard type %s", names[which]);
1307

1308
      // Do not cache standard types while bootstrapping as the GC will
1309
      // move the objects after parsing
1310
      static int can_cache = -1;
13,300✔
1311
      if (can_cache == -1) can_cache = !opt_get_int(OPT_BOOTSTRAP);
13,300✔
1312

1313
      if (can_cache)
13,300✔
1314
         return (cache[which] = tree_type(d));
13,110✔
1315
      else
1316
         return tree_type(d);
190✔
1317
   }
1318
   else
1319
      return cache[which];
1320
}
1321

1322
type_t ieee_type(ieee_type_t which)
1,189✔
1323
{
1324
   static type_t cache[IEEE_STD_LOGIC + 1] = {};
1,189✔
1325
   assert(which < ARRAY_LEN(cache));
1,189✔
1326

1327
   if (cache[which] == NULL) {
1,189✔
1328
      const char *names[] = {
103✔
1329
         "STD_ULOGIC",
1330
         "STD_LOGIC",
1331
      };
1332

1333
      static tree_t ieee_cache[STD_19 + 1] = {};
103✔
1334
      tree_t unit = cached_unit(NULL, ieee_cache, W_IEEE, W_IEEE_1164);
103✔
1335

1336
      tree_t d = search_type_decls(unit, ident_new(names[which]));
103✔
1337
      if (d == NULL)
103✔
1338
         fatal_trace("cannot find IEEE type %s", names[which]);
1339

1340
      // STD.STANDARD cannot depend on IEEE
1341
      assert(!opt_get_int(OPT_BOOTSTRAP));
103✔
1342

1343
      return (cache[which] = tree_type(d));
103✔
1344
   }
1345
   else
1346
      return cache[which];
1347
}
1348

1349
static tree_t cached_verilog(void)
255✔
1350
{
1351
   static tree_t verilog_cache[STD_19 + 1] = {};
255✔
1352
   return cached_unit(NULL, verilog_cache, W_NVC, W_NVC_VERILOG);
255✔
1353
}
1354

1355
type_t verilog_type(verilog_type_t which)
417✔
1356
{
1357
   static type_t cache[VERILOG_WIRE_ARRAY + 1] = {};
417✔
1358
   assert(which < ARRAY_LEN(cache));
417✔
1359

1360
   if (cache[which] == NULL) {
417✔
1361
      const char *names[] = {
151✔
1362
         [VERILOG_LOGIC] = "T_LOGIC",
1363
         [VERILOG_LOGIC_ARRAY] = "T_LOGIC_ARRAY",
1364
         [VERILOG_INT64] = "T_INT64",
1365
         [VERILOG_NET_VALUE] = "T_NET_VALUE",
1366
         [VERILOG_NET_ARRAY] = "T_NET_ARRAY",
1367
         [VERILOG_WIRE] = "T_WIRE",
1368
         [VERILOG_WIRE_ARRAY] = "T_WIRE_ARRAY",
1369
      };
1370

1371
      tree_t d = search_type_decls(cached_verilog(), ident_new(names[which]));
151✔
1372
      if (d == NULL)
151✔
1373
         fatal_trace("cannot find NVC.VERILOG type %s", names[which]);
1374

1375
      // STD.STANDARD cannot depend on NVC.VERILOG
1376
      assert(!opt_get_int(OPT_BOOTSTRAP));
151✔
1377

1378
      return (cache[which] = tree_type(d));
151✔
1379
   }
1380
   else
1381
      return cache[which];
1382
}
1383

1384
type_t reflection_type(reflect_type_t which)
183✔
1385
{
1386
   static type_t cache[REFLECT_SUBTYPE_MIRROR + 1] = {};
183✔
1387
   assert(which < ARRAY_LEN(cache));
183✔
1388

1389
   if (cache[which] == NULL) {
183✔
1390
      const char *names[] = {
32✔
1391
         "VALUE_MIRROR",
1392
         "SUBTYPE_MIRROR",
1393
      };
1394

1395
      static tree_t reflect_cache[STD_19 + 1] = {};
32✔
1396
      tree_t unit = cached_unit(NULL, reflect_cache, W_STD, W_STD_REFLECTION);
32✔
1397

1398
      tree_t d = search_type_decls(unit, ident_new(names[which]));
32✔
1399
      if (d == NULL)
32✔
1400
         fatal_trace("cannot find REFLECTION type %s", names[which]);
1401

1402
      // STD.STANDARD cannot depend on REFLECTION
1403
      assert(!opt_get_int(OPT_BOOTSTRAP));
32✔
1404

1405
      return (cache[which] = tree_type(d));
32✔
1406
   }
1407
   else
1408
      return cache[which];
1409
}
1410

1411
bool is_open_coded_builtin(subprogram_kind_t kind)
430,387✔
1412
{
1413
   switch (kind) {
430,387✔
1414
   case S_ADD:
1415
   case S_SUB:
1416
   case S_DIV:
1417
   case S_MUL:
1418
   case S_MUL_PR:
1419
   case S_MUL_RP:
1420
   case S_MUL_PI:
1421
   case S_MUL_IP:
1422
   case S_DIV_PR:
1423
   case S_DIV_PP:
1424
   case S_DIV_PI:
1425
   case S_IDENTITY:
1426
   case S_NEGATE:
1427
   case S_SCALAR_LT:
1428
   case S_SCALAR_LE:
1429
   case S_SCALAR_GT:
1430
   case S_SCALAR_GE:
1431
   case S_SCALAR_EQ:
1432
   case S_SCALAR_NEQ:
1433
   case S_ABS:
1434
   case S_MOD:
1435
   case S_REM:
1436
   case S_EXP:
1437
   case S_MUL_RI:
1438
   case S_MUL_IR:
1439
   case S_DIV_RI:
1440
   case S_CONCAT:
1441
   case S_SCALAR_AND:
1442
   case S_SCALAR_OR:
1443
   case S_SCALAR_NOT:
1444
   case S_SCALAR_NAND:
1445
   case S_SCALAR_NOR:
1446
   case S_SCALAR_XOR:
1447
   case S_SCALAR_XNOR:
1448
   case S_FILE_OPEN1:
1449
   case S_FILE_OPEN2:
1450
   case S_FILE_READ:
1451
   case S_FILE_WRITE:
1452
   case S_DEALLOCATE:
1453
      return true;
1454
   default:
179,904✔
1455
      return false;
179,904✔
1456
   }
1457
}
1458

UNCOV
1459
tree_t std_func(ident_t mangled)
×
1460
{
UNCOV
1461
   tree_t std = cached_std(NULL);
×
1462

1463
   const int ndecls = tree_decls(std);
×
1464
   for (int i = 0; i < ndecls; i++) {
×
1465
      tree_t d = tree_decl(std, i);
×
1466
      if (is_subprogram(d) && tree_has_ident2(d) && tree_ident2(d) == mangled)
×
UNCOV
1467
         return d;
×
1468
   }
1469

1470
   return NULL;
1471
}
1472

1473
tree_t verilog_func(ident_t mangled)
104✔
1474
{
1475
   tree_t pack = cached_verilog();
104✔
1476

1477
   const int ndecls = tree_decls(pack);
104✔
1478
   for (int i = 0; i < ndecls; i++) {
9,730✔
1479
      tree_t d = tree_decl(pack, i);
9,730✔
1480
      if (is_subprogram(d) && tree_ident2(d) == mangled)
9,730✔
1481
         return d;
104✔
1482
   }
1483

1484
   fatal_trace("missing Verilog helper function %s", istr(mangled));
1485
}
1486

1487
tree_t name_to_ref(tree_t name)
95,988✔
1488
{
1489
   tree_kind_t kind;
95,988✔
1490
   while ((kind = tree_kind(name)) != T_REF) {
109,281✔
1491
      switch (kind) {
14,949✔
1492
      case T_ARRAY_REF:
13,293✔
1493
      case T_ARRAY_SLICE:
1494
      case T_RECORD_REF:
1495
      case T_ALL:
1496
         name = tree_value(name);
13,293✔
1497
         break;
13,293✔
1498
      default:
1499
         return NULL;
1500
      }
1501
   }
1502

1503
   return name;
1504
}
1505

1506
const char *port_mode_str(port_mode_t mode)
44✔
1507
{
1508
   const char *mode_str[] = {
44✔
1509
      "INVALID", "IN", "OUT", "INOUT", "BUFFER", "LINKAGE", "VIEW", "VIEW"
1510
   };
1511
   assert(mode < ARRAY_LEN(mode_str));
44✔
1512
   return mode_str[mode];
44✔
1513
}
1514

1515
void mangle_one_type(text_buf_t *buf, type_t type)
169,550✔
1516
{
1517
   ident_t ident = type_ident(type);
169,550✔
1518

1519
   char code = 0;
169,550✔
1520
   switch (is_well_known(ident)) {
169,550✔
1521
   case W_STD_INTEGER:        code = 'I'; break;
1522
   case W_STD_STRING:         code = 'S'; break;
3,379✔
1523
   case W_STD_REAL:           code = 'R'; break;
3,555✔
1524
   case W_STD_BOOL:           code = 'B'; break;
22,864✔
1525
   case W_STD_CHAR:           code = 'C'; break;
623✔
1526
   case W_STD_TIME:           code = 'T'; break;
916✔
1527
   case W_STD_NATURAL:        code = 'N'; break;
4,225✔
1528
   case W_STD_POSITIVE:       code = 'P'; break;
365✔
1529
   case W_STD_BIT:            code = 'J'; break;
2,465✔
1530
   case W_STD_BIT_VECTOR:     code = 'Q'; break;
2,597✔
1531
   case W_IEEE_LOGIC:         code = 'L'; break;
292✔
1532
   case W_IEEE_ULOGIC:        code = 'U'; break;
4,673✔
1533
   case W_IEEE_LOGIC_VECTOR:  code = 'V'; break;
1,658✔
1534
   case W_IEEE_ULOGIC_VECTOR: code = 'Y'; break;
1,397✔
1535
   default: break;
1536
   }
1537

1538
   if (code)
49,009✔
1539
      tb_append(buf, code);
61,567✔
1540
   else {
1541
      tb_printf(buf, "%zu", ident_len(ident));
107,983✔
1542
      tb_istr(buf, ident);
107,983✔
1543
   }
1544
}
169,550✔
1545

1546
tree_t primary_unit_of(tree_t unit)
25,871✔
1547
{
1548
   switch (tree_kind(unit)) {
25,871✔
1549
   case T_ENTITY:
1550
   case T_COMPONENT:
1551
   case T_PACKAGE:
1552
   case T_BLOCK:
1553
   case T_ELAB:
1554
   case T_PACK_INST:
1555
      return unit;
1556
   case T_ARCH:
15,711✔
1557
   case T_CONFIGURATION:
1558
   case T_PACK_BODY:
1559
      return tree_primary(unit);
15,711✔
UNCOV
1560
   default:
×
1561
      fatal_trace("invalid kind %s in primary_unit_of",
1562
                  tree_kind_str(tree_kind(unit)));
1563
   }
1564
}
1565

1566
unsigned get_case_choice_char(tree_t value, int depth)
8,297✔
1567
{
1568
   switch (tree_kind(value)) {
8,956✔
1569
   case T_STRING:
8,179✔
1570
      if (depth < tree_chars(value))
8,179✔
1571
         return assume_int(tree_char(value, depth));
8,178✔
1572
      else
1573
         return ~0;   // Out of bounds
1574

1575
   case T_AGGREGATE:
14✔
1576
      {
1577
         const int nassocs = tree_assocs(value);
14✔
1578
         type_t type = tree_type(value);
14✔
1579

1580
         for (int i = 0; i < nassocs; i++) {
24✔
1581
            tree_t a = tree_assoc(value, i);
23✔
1582
            switch (tree_subkind(a)) {
23✔
1583
            case A_NAMED:
×
1584
               if (rebase_index(type, 0, assume_int(tree_name(a))) == depth)
×
UNCOV
1585
                  return assume_int(tree_value(a));
×
1586
               break;
1587

1588
            case A_POS:
23✔
1589
               if (tree_pos(a) == (unsigned)depth)
23✔
1590
                  return assume_int(tree_value(a));
13✔
1591
               break;
1592

1593
            case A_OTHERS:
×
UNCOV
1594
               return assume_int(tree_value(a));
×
1595
            }
1596
         }
1597

1598
         // This will produce an error during bounds checking
1599
         return ~0;
1600
      }
1601

1602
   case T_REF:
419✔
1603
      {
1604
         tree_t decl = tree_ref(value);
419✔
1605
         assert(tree_kind(decl) == T_CONST_DECL || tree_kind(decl) == T_ALIAS);
419✔
1606
         assert(tree_has_value(decl));
419✔
1607
         return get_case_choice_char(tree_value(decl), depth);
419✔
1608
      }
1609

1610
   case T_ARRAY_SLICE:
240✔
1611
      {
1612
         tree_t base = tree_value(value);
240✔
1613
         tree_t r = tree_range(value, 0);
240✔
1614
         const int64_t rleft = assume_int(tree_left(r));
240✔
1615
         const int64_t offset = rebase_index(tree_type(base), 0, rleft);
240✔
1616
         return get_case_choice_char(base, depth + offset);
240✔
1617
      }
1618

1619
   case T_FCALL:
104✔
1620
      if (tree_subkind(tree_ref(value)) == S_CONCAT) {
104✔
1621
         const int nparams = tree_params(value);
104✔
1622
         for (int i = 0; i < nparams; i++) {
156✔
1623
            tree_t left = tree_value(tree_param(value, i));
156✔
1624

1625
            type_t left_type = tree_type(left);
156✔
1626
            if (type_is_unconstrained(left_type))
156✔
UNCOV
1627
               fatal_at(tree_loc(left), "sorry, this expression is not "
×
1628
                        "currently supported in a case choice");
1629

1630
            tree_t lr = range_of(tree_type(left), 0);
156✔
1631
            int64_t left_len;
156✔
1632
            if (!folded_length(lr, &left_len))
156✔
UNCOV
1633
               fatal_at(tree_loc(left), "cannot determine length of left hand "
×
1634
                        "side of concatenation");
1635

1636
            if (depth < left_len || i + 1 == nparams)
156✔
1637
               return get_case_choice_char(left, depth);
104✔
1638

1639
            depth -= left_len;
52✔
1640
         }
1641
      }
1642
      // Fall-through
1643

1644
   default:
UNCOV
1645
      fatal_at(tree_loc(value), "unsupported tree type %s in case choice",
×
1646
               tree_kind_str(tree_kind(value)));
1647
   }
1648
}
1649

1650
int64_t encode_case_choice(tree_t value, int length, int bits)
1,155✔
1651
{
1652
   uint64_t enc = 0;
1,155✔
1653
   for (int i = 0; i < length; i++) {
9,326✔
1654
      if (bits > 0) {
8,171✔
1655
         enc <<= bits;
1,841✔
1656
         enc |= get_case_choice_char(value, i);
1,841✔
1657
      }
1658
      else {
1659
         enc *= 0x27d4eb2d;
6,330✔
1660
         enc += get_case_choice_char(value, i);
6,330✔
1661
      }
1662
   }
1663

1664
   return enc;
1,155✔
1665
}
1666

1667
void to_string(text_buf_t *tb, type_t type, int64_t value)
578✔
1668
{
1669
   if (type_is_integer(type))
578✔
1670
      tb_printf(tb, "%"PRIi64, value);
444✔
1671
   else if (type_is_enum(type)) {
134✔
1672
      type_t base = type_base_recur(type);
62✔
1673
      if (value < 0 || value >= type_enum_literals(base))
62✔
1674
         tb_printf(tb, "%"PRIi64, value);
3✔
1675
      else
1676
         tb_cat(tb, istr(tree_ident(type_enum_literal(base, value))));
59✔
1677
   }
1678
   else if (type_is_physical(type)) {
72✔
1679
      type_t base = type_base_recur(type);
24✔
1680
      const unsigned nunits = type_units(base);
24✔
1681
      tree_t max_unit = NULL;
24✔
1682
      int64_t max_unit_value = 0;
24✔
1683

1684
      // Find the largest unit that evenly divides the given value
1685
      for (unsigned u = 0; u < nunits; u++) {
216✔
1686
         tree_t unit = type_unit(base, u);
192✔
1687
         const int64_t unit_value = assume_int(tree_value(unit));
192✔
1688
         if ((unit_value > max_unit_value) && (value % unit_value == 0)) {
192✔
1689
            max_unit = unit;
90✔
1690
            max_unit_value = unit_value;
90✔
1691
         }
1692
      }
1693
      assert(max_unit);
24✔
1694

1695
      tb_printf(tb, "%"PRIi64" %s", value / max_unit_value,
24✔
1696
                istr(tree_ident(max_unit)));
1697
   }
1698
   else if (type_is_real(type)) {
48✔
1699
      union { int64_t i; double r; } u = { .i = value };
42✔
1700
      tb_printf(tb, "%.17g", u.r);
42✔
1701
   }
1702
   else if (type_is_access(type)) {
6✔
1703
      if (value == 0)
6✔
1704
         tb_cat(tb, "NULL");
3✔
1705
      else
1706
         tb_printf(tb, "%p", (void *)value);
3✔
1707
   }
1708
}
578✔
1709

1710
static bool is_static(tree_t expr)
5,904✔
1711
{
1712
   switch (tree_kind(expr)) {
6,008✔
1713
   case T_REF:
688✔
1714
      {
1715
         tree_t decl = tree_ref(expr);
688✔
1716
         switch (tree_kind(decl)) {
688✔
1717
         case T_CONST_DECL:
179✔
1718
            return !!(tree_flags(decl) & TREE_F_GLOBALLY_STATIC);
179✔
1719
         case T_UNIT_DECL:
1720
         case T_ENUM_LIT:
1721
         case T_GENERIC_DECL:
1722
            return true;
1723
         case T_ALIAS:
×
UNCOV
1724
            return is_static(tree_value(decl));
×
1725
         default:
191✔
1726
            return false;
191✔
1727
         }
1728
      }
1729

1730
   case T_LITERAL:
1731
   case T_STRING:
1732
      return true;
1733

1734
   case T_FCALL:
402✔
1735
      return !!(tree_flags(expr) & (TREE_F_LOCALLY_STATIC
402✔
1736
                                    | TREE_F_GLOBALLY_STATIC));
1737

1738
   case T_RECORD_REF:
101✔
1739
      return is_static(tree_value(expr));
101✔
1740

1741
   case T_ARRAY_REF:
60✔
1742
      {
1743
         if (!is_static(tree_value(expr)))
60✔
1744
            return false;
1745

1746
         const int nparams = tree_params(expr);
60✔
1747
         for (int i = 0; i < nparams; i++) {
120✔
1748
            if (!is_static(tree_value(tree_param(expr, i))))
60✔
1749
               return false;
1750
         }
1751

1752
         return true;
1753
      }
1754

1755
   case T_ARRAY_SLICE:
30✔
1756
      {
1757
         if (!is_static(tree_value(expr)))
30✔
1758
            return false;
1759

1760
         assert(tree_ranges(expr) == 1);
30✔
1761

1762
         tree_t r = tree_range(expr, 0);
30✔
1763
         if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
30✔
UNCOV
1764
            return false;
×
1765

1766
         return true;
1767
      }
1768

1769
   case T_ATTR_REF:
9✔
1770
      {
1771
         switch (tree_subkind(expr)) {
9✔
1772
         case ATTR_EVENT:
1773
         case ATTR_ACTIVE:
1774
         case ATTR_LAST_EVENT:
1775
         case ATTR_LAST_ACTIVE:
1776
         case ATTR_LAST_VALUE:
1777
         case ATTR_DRIVING:
1778
         case ATTR_DRIVING_VALUE:
1779
         case ATTR_STABLE:
1780
         case ATTR_QUIET:
1781
            return false;
1782
         case ATTR_POS:
3✔
1783
         case ATTR_VAL:
1784
         case ATTR_LEFTOF:
1785
         case ATTR_RIGHTOF:
1786
         case ATTR_SUCC:
1787
         case ATTR_PRED:
1788
         case ATTR_VALUE:
1789
         case ATTR_IMAGE:
1790
            assert(tree_params(expr) == 1);
3✔
1791
            return is_static(tree_value(tree_param(expr, 0)));
3✔
1792
         case ATTR_LENGTH:
6✔
1793
         case ATTR_LEFT:
1794
         case ATTR_RIGHT:
1795
         case ATTR_LOW:
1796
         case ATTR_HIGH:
1797
            {
1798
               type_t type = tree_type(tree_name(expr));
6✔
1799
               if (type_is_unconstrained(type))
6✔
1800
                  return false;
1801

1802
               int64_t dim = 1;
3✔
1803
               if (tree_params(expr) == 1)
3✔
UNCOV
1804
                  dim = assume_int(tree_value(tree_param(expr, 0)));
×
1805

1806
               tree_t r = range_of(type, dim - 1);
3✔
1807
               if (tree_subkind(r) == RANGE_EXPR)
3✔
1808
                  return false;
1809

1810
               return is_static(tree_left(r)) && is_static(tree_right(r));
3✔
1811
            }
1812
         default:
×
UNCOV
1813
            return true;
×
1814
         }
1815
      }
1816

1817
   default:
×
UNCOV
1818
      return false;
×
1819
   }
1820
}
1821

1822
tree_t longest_static_prefix(tree_t expr)
22,432✔
1823
{
1824
   switch (tree_kind(expr)) {
22,432✔
1825
   case T_ARRAY_REF:
4,033✔
1826
      {
1827
         tree_t value = tree_value(expr);
4,033✔
1828
         tree_t prefix = longest_static_prefix(value);
4,033✔
1829

1830
         if (prefix != value)
4,033✔
1831
            return prefix;
1832

1833
         const int nparams = tree_params(expr);
4,005✔
1834
         for (int i = 0; i < nparams; i++) {
8,194✔
1835
            if (!is_static(tree_value(tree_param(expr, i))))
4,431✔
1836
               return prefix;
1837
         }
1838

1839
         return expr;
1840
      }
1841

1842
   case T_ARRAY_SLICE:
650✔
1843
      {
1844
         tree_t value = tree_value(expr);
650✔
1845
         tree_t prefix = longest_static_prefix(value);
650✔
1846

1847
         if (prefix != value)
650✔
1848
            return prefix;
1849

1850
         assert(tree_ranges(expr) == 1);
643✔
1851

1852
         tree_t r = tree_range(expr, 0);
643✔
1853
         if (tree_subkind(r) == RANGE_EXPR)
643✔
1854
            return prefix;
1855
         else if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
635✔
1856
            return prefix;
16✔
1857

1858
         return expr;
1859
      }
1860

1861
   case T_RECORD_REF:
1,095✔
1862
      {
1863
         tree_t value = tree_value(expr);
1,095✔
1864
         tree_t prefix = longest_static_prefix(value);
1,095✔
1865

1866
         if (prefix != value)
1,095✔
1867
            return prefix;
21✔
1868

1869
         return expr;
1870
      }
1871

1872
   default:
1873
      return expr;
1874
   }
1875
}
1876

1877
tree_t body_of(tree_t pack)
1,380✔
1878
{
1879
   const tree_kind_t kind = tree_kind(pack);
1,380✔
1880
   if (kind == T_PACK_INST)
1,380✔
1881
      return NULL;
1882

1883
   assert(tree_kind(pack) == T_PACKAGE);
1,380✔
1884

1885
   ident_t body_i = well_known(W_BODY);
1,380✔
1886
   ident_t body_name = ident_prefix(tree_ident(pack), body_i, '-');
1,380✔
1887
   return lib_get_qualified(body_name);
1,380✔
1888
}
1889

1890
tree_t find_generic_map(tree_t unit, int pos, tree_t g)
3,521✔
1891
{
1892
   const int ngenmaps = tree_genmaps(unit);
3,521✔
1893

1894
   if (pos < ngenmaps) {
3,521✔
1895
      tree_t m = tree_genmap(unit, pos);
3,371✔
1896
      if (tree_subkind(m) == P_POS && tree_pos(m) == pos)
3,371✔
1897
         return tree_value(m);
2,438✔
1898
   }
1899

1900
   for (int j = 0; j < ngenmaps; j++) {
4,716✔
1901
      tree_t m = tree_genmap(unit, j);
4,566✔
1902
      switch (tree_subkind(m)) {
4,566✔
1903
      case P_NAMED:
2,151✔
1904
         {
1905
            tree_t name = tree_name(m);
2,151✔
1906
            assert(tree_kind(name) == T_REF);
2,151✔
1907

1908
            if (tree_has_ref(name) && tree_ref(name) == g)
2,151✔
1909
               return tree_value(m);
466✔
1910
         }
1911
         break;
1912

1913
      case P_POS:
2,415✔
1914
         if (tree_pos(m) == pos)
2,415✔
1915
            return tree_value(m);
467✔
1916
         break;
1917

1918
      default:
1919
         break;
1920
      }
1921
   }
1922

1923
   return NULL;
1924
}
1925

1926
bool relaxed_rules(void)
542,032✔
1927
{
1928
   return opt_get_int(OPT_RELAXED);
542,032✔
1929
}
1930

1931
bool is_type_attribute(attr_kind_t kind)
68,038✔
1932
{
1933
   switch (kind) {
68,038✔
1934
   case ATTR_SUBTYPE:
1935
   case ATTR_BASE:
1936
   case ATTR_ELEMENT:
1937
   case ATTR_DESIGNATED_SUBTYPE:
1938
   case ATTR_INDEX:
1939
      return true;
1940
   default:
67,412✔
1941
      return false;
67,412✔
1942
   }
1943
}
1944

1945
bool attribute_has_param(attr_kind_t attr)
22,644✔
1946
{
1947
   switch (attr) {
22,644✔
1948
   case ATTR_IMAGE:
1949
   case ATTR_SUCC:
1950
   case ATTR_PRED:
1951
   case ATTR_DELAYED:
1952
   case ATTR_LEFTOF:
1953
   case ATTR_RIGHTOF:
1954
   case ATTR_VALUE:
1955
   case ATTR_POS:
1956
   case ATTR_LOW:
1957
   case ATTR_HIGH:
1958
   case ATTR_LEFT:
1959
   case ATTR_RIGHT:
1960
   case ATTR_LENGTH:
1961
   case ATTR_RANGE:
1962
   case ATTR_REVERSE_RANGE:
1963
   case ATTR_VAL:
1964
   case ATTR_QUIET:
1965
   case ATTR_STABLE:
1966
   case ATTR_INDEX:
1967
   case ATTR_ASCENDING:
1968
      return true;
1969
   default:
2,130✔
1970
      return false;
2,130✔
1971
   }
1972
}
1973

1974
type_t get_type_or_null(tree_t t)
2,137,052✔
1975
{
1976
   switch (tree_kind(t)) {
2,137,052✔
1977
   case T_LIBRARY:
1978
   case T_ATTR_SPEC:
1979
   case T_PACKAGE:
1980
   case T_PACK_INST:
1981
   case T_PACK_BODY:
1982
   case T_ENTITY:
1983
   case T_ARCH:
1984
   case T_PROCESS:
1985
   case T_COMPONENT:
1986
   case T_INSTANCE:
1987
   case T_CONCURRENT:
1988
   case T_BLOCK:
1989
   case T_WHILE:
1990
   case T_FOR:
1991
   case T_LOOP:
1992
   case T_GROUP_TEMPLATE:
1993
   case T_CONFIGURATION:
1994
   case T_GROUP:
1995
   case T_FOR_GENERATE:
1996
   case T_IF_GENERATE:
1997
   case T_CASE_GENERATE:
1998
   case T_USE:
1999
   case T_CONTEXT:
2000
   case T_PSL_DECL:
2001
   case T_PSL_DIRECT:
2002
   case T_WAVEFORM:
2003
      return NULL;
2004
   default:
2,049,807✔
2005
      if (tree_has_type(t))
2,049,807✔
2006
         return tree_type(t);
2,048,445✔
2007
      else
2008
         return NULL;
2009
   }
2010
}
2011

2012
type_t subtype_for_string(tree_t str, type_t base)
25,529✔
2013
{
2014
   if (type_const_bounds(base))
25,529✔
2015
      return base;    // Can be checked statically
2016
   else if (!type_is_unconstrained(base))
22,475✔
2017
      base = type_base_recur(base);
155✔
2018

2019
   // Construct a new constrained array subtype: the direction and
2020
   // bounds are the same as those for a positional array aggregate
2021
   type_t sub = type_new(T_SUBTYPE);
22,475✔
2022
   type_set_base(sub, base);
22,475✔
2023

2024
   type_t index_type = index_type_of(base, 0);
22,475✔
2025
   const bool is_enum = type_is_enum(index_type);
22,475✔
2026

2027
   // The direction is determined by the index type
2028
   range_kind_t dir = direction_of(index_type, 0);
22,475✔
2029
   tree_t index_r = range_of(index_type, 0);
22,475✔
2030

2031
   // The left bound is the left of the index type and the right bound
2032
   // is determined by the number of elements
2033

2034
   tree_t left = NULL, right = NULL;
22,475✔
2035
   const int nchars = tree_chars(str);
22,475✔
2036

2037
   if (is_enum) {
22,475✔
2038
      const int nlits = type_enum_literals(type_base_recur(index_type));
14✔
2039
      int64_t index_left = assume_int(tree_left(index_r));
14✔
2040

2041
      int64_t iright, ileft;
14✔
2042
      if (nchars == 0) {
14✔
2043
         iright = index_left;
1✔
2044
         ileft = assume_int(tree_right(index_r));
1✔
2045
      }
2046
      else if (dir == RANGE_DOWNTO) {
13✔
UNCOV
2047
         ileft = index_left;
×
UNCOV
2048
         iright = MIN(nlits - 1, MAX(0, index_left - nchars + 1));
×
2049
      }
2050
      else {
2051
         ileft = index_left;
13✔
2052
         iright = MIN(nlits - 1, MAX(0, index_left + nchars - 1));
13✔
2053
      }
2054

2055
      left = get_enum_lit(str, index_type, ileft);
14✔
2056
      right = get_enum_lit(str, index_type, iright);
14✔
2057
   }
2058
   else {
2059
      left = tree_left(index_r);
22,461✔
2060

2061
      int64_t iright;
22,461✔
2062
      if (dir == RANGE_DOWNTO)
22,461✔
UNCOV
2063
         iright = assume_int(left) - nchars + 1;
×
2064
      else
2065
         iright = assume_int(left) + nchars - 1;
22,461✔
2066

2067
      right = get_int_lit(str, index_type, iright);
22,461✔
2068
   }
2069

2070
   tree_t r = tree_new(T_RANGE);
22,475✔
2071
   tree_set_subkind(r, dir);
22,475✔
2072
   tree_set_left(r, left);
22,475✔
2073
   tree_set_right(r, right);
22,475✔
2074
   tree_set_loc(r, tree_loc(str));
22,475✔
2075
   tree_set_type(r, index_type);
22,475✔
2076

2077
   tree_t c = tree_new(T_CONSTRAINT);
22,475✔
2078
   tree_set_subkind(c, C_INDEX);
22,475✔
2079
   tree_add_range(c, r);
22,475✔
2080
   tree_set_loc(c, tree_loc(str));
22,475✔
2081

2082
   type_add_constraint(sub, c);
22,475✔
2083

2084
   return sub;
22,475✔
2085
}
2086

2087
tree_t change_ref(tree_t name, tree_t new)
2,108✔
2088
{
2089
   switch (tree_kind(name)) {
2,108✔
2090
   case T_REF:
1,486✔
2091
      return make_ref(new);
1,486✔
2092

2093
   case T_ARRAY_REF:
108✔
2094
      {
2095
         tree_t t = tree_new(T_ARRAY_REF);
108✔
2096
         tree_set_loc(t, tree_loc(name));
108✔
2097
         tree_set_value(t, change_ref(tree_value(name), new));
108✔
2098
         tree_set_type(t, tree_type(name));
108✔
2099

2100
         const int nparams = tree_params(name);
108✔
2101
         for (int i = 0; i < nparams; i++)
216✔
2102
            tree_add_param(t, tree_param(name, i));
108✔
2103

2104
         return t;
2105
      }
2106

2107
   case T_ARRAY_SLICE:
43✔
2108
      {
2109
         tree_t t = tree_new(T_ARRAY_SLICE);
43✔
2110
         tree_set_loc(t, tree_loc(name));
43✔
2111
         tree_set_value(t, change_ref(tree_value(name), new));
43✔
2112
         tree_set_type(t, tree_type(name));
43✔
2113
         tree_add_range(t, tree_range(name, 0));
43✔
2114

2115
         return t;
43✔
2116
      }
2117

2118
   case T_RECORD_REF:
366✔
2119
      {
2120
         tree_t t = tree_new(T_RECORD_REF);
366✔
2121
         tree_set_loc(t, tree_loc(name));
366✔
2122
         tree_set_value(t, change_ref(tree_value(name), new));
366✔
2123
         tree_set_type(t, tree_type(name));
366✔
2124
         tree_set_ident(t, tree_ident(name));
366✔
2125
         tree_set_ref(t, tree_ref(name));
366✔
2126

2127
         return t;
366✔
2128
      }
2129

2130
   case T_CONV_FUNC:
96✔
2131
      {
2132
         tree_t t = tree_new(T_CONV_FUNC);
96✔
2133
         tree_set_loc(t, tree_loc(name));
96✔
2134
         tree_set_value(t, change_ref(tree_value(name), new));
96✔
2135
         tree_set_ident(t, tree_ident(name));
96✔
2136
         tree_set_type(t, tree_type(name));
96✔
2137
         tree_set_ref(t, tree_ref(name));
96✔
2138

2139
         return t;
96✔
2140
      }
2141

2142
   case T_TYPE_CONV:
9✔
2143
      {
2144
         tree_t t = tree_new(T_TYPE_CONV);
9✔
2145
         tree_set_loc(t, tree_loc(name));
9✔
2146
         tree_set_type(t, tree_type(name));
9✔
2147
         tree_set_value(t, change_ref(tree_value(name), new));
9✔
2148

2149
         return t;
9✔
2150
      }
2151

UNCOV
2152
   default:
×
2153
      fatal_trace("cannot handle tree kind %s in elab_change_ref",
2154
                  tree_kind_str(tree_kind(name)));
2155
   }
2156
}
2157

2158
static void build_wait_for_target(tree_t expr, build_wait_fn_t fn, void *ctx)
2,836✔
2159
{
2160
   switch (tree_kind(expr)) {
2,836✔
2161
   case T_ARRAY_SLICE:
79✔
2162
      build_wait(tree_range(expr, 0), fn, ctx);
79✔
2163
      break;
79✔
2164

2165
   case T_ARRAY_REF:
531✔
2166
      {
2167
         const int nparams = tree_params(expr);
531✔
2168
         for (int i = 0; i < nparams; i++)
1,062✔
2169
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
531✔
2170
      }
2171
      break;
2172

2173
   default:
2174
      break;
2175
   }
2176
}
2,836✔
2177

2178
void build_wait(tree_t expr, build_wait_fn_t fn, void *ctx)
13,334✔
2179
{
2180
   // LRM 08 section 10.2 has rules for building a wait statement from a
2181
   // sensitivity list. LRM 08 section 11.3 extends these rules to
2182
   // all-sensitised processes.
2183

2184
   switch (tree_kind(expr)) {
16,547✔
2185
   case T_REF:
4,132✔
2186
      if (class_of(tree_ref(expr)) == C_SIGNAL)
4,132✔
2187
         (*fn)(expr, ctx);
2,381✔
2188
      break;
2189

2190
   case T_EXTERNAL_NAME:
8✔
2191
      if (tree_class(expr) == C_SIGNAL)
8✔
2192
         (*fn)(expr, ctx);
8✔
2193
      break;
2194

2195
   case T_WAVEFORM:
2,781✔
2196
   case T_QUALIFIED:
2197
   case T_TYPE_CONV:
2198
   case T_INERTIAL:
2199
      if (tree_has_value(expr))
2,781✔
2200
         build_wait(tree_value(expr), fn, ctx);
2,772✔
2201
      break;
2202

2203
   case T_ASSERT:
395✔
2204
      build_wait(tree_value(expr), fn, ctx);
395✔
2205
      // Fall-through
2206
   case T_REPORT:
398✔
2207
      if (tree_has_message(expr))
398✔
2208
         build_wait(tree_message(expr), fn, ctx);
274✔
2209
      break;
2210

2211
   case T_ARRAY_REF:
787✔
2212
   case T_ARRAY_SLICE:
2213
   case T_RECORD_REF:
2214
      {
2215
         tree_t ref = name_to_ref(expr);
787✔
2216
         if (ref != NULL && class_of(ref) == C_SIGNAL
787✔
2217
             && longest_static_prefix(expr) == expr)
506✔
2218
            (*fn)(expr, ctx);
427✔
2219
         else {
2220
            build_wait(tree_value(expr), fn, ctx);
360✔
2221
            build_wait_for_target(expr, fn, ctx);
360✔
2222
         }
2223
      }
2224
      break;
2225

2226
   case T_FCALL:
2,154✔
2227
   case T_PCALL:
2228
   case T_PROT_FCALL:
2229
   case T_PROT_PCALL:
2230
      {
2231
         tree_t decl = tree_ref(expr);
2,154✔
2232
         const int nparams = tree_params(expr);
2,154✔
2233
         for (int i = 0; i < nparams; i++) {
5,934✔
2234
            tree_t p = tree_param(expr, i);
3,780✔
2235
            assert(tree_subkind(p) == P_POS);
3,780✔
2236

2237
            switch (tree_subkind(tree_port(decl, tree_pos(p)))) {
3,780✔
2238
            case PORT_IN:
3,773✔
2239
            case PORT_INOUT:
2240
            case PORT_ARRAY_VIEW:
2241
            case PORT_RECORD_VIEW:
2242
               build_wait(tree_value(p), fn, ctx);
3,773✔
2243
               break;
3,773✔
2244
            default:
2245
               break;
2246
            }
2247
         }
2248
      }
2249
      break;
2250

2251
   case T_AGGREGATE:
282✔
2252
      {
2253
         const int nassocs = tree_assocs(expr);
282✔
2254
         for (int i = 0; i < nassocs; i++) {
947✔
2255
            tree_t a = tree_assoc(expr, i);
665✔
2256
            build_wait(tree_value(a), fn, ctx);
665✔
2257

2258
            switch (tree_subkind(a)) {
665✔
2259
            case A_RANGE:
53✔
2260
            case A_SLICE:
2261
               build_wait(tree_range(a, 0), fn, ctx);
53✔
2262
               break;
53✔
2263
            case A_NAMED:
66✔
2264
               build_wait(tree_name(a), fn, ctx);
66✔
2265
               break;
66✔
2266
            }
2267
         }
2268
      }
2269
      break;
2270

2271
   case T_ATTR_REF:
300✔
2272
      {
2273
         const attr_kind_t predef = tree_subkind(expr);
300✔
2274
         if (predef == ATTR_EVENT || predef == ATTR_ACTIVE)
300✔
2275
            build_wait(tree_name(expr), fn, ctx);
115✔
2276

2277
         const int nparams = tree_params(expr);
300✔
2278
         for (int i = 0; i < nparams; i++)
311✔
2279
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
11✔
2280
      }
2281
      break;
2282

2283
   case T_LITERAL:
2284
   case T_STRING:
2285
   case T_DUMMY_DRIVER:
2286
      break;
2287

2288
   case T_IF:
215✔
2289
      {
2290
         const int nconds = tree_conds(expr);
215✔
2291
         for (int i = 0; i < nconds; i++)
583✔
2292
            build_wait(tree_cond(expr, i), fn, ctx);
368✔
2293
      }
2294
      break;
2295

2296
   case T_COND_STMT:
372✔
2297
      {
2298
         if (tree_has_value(expr))
372✔
2299
            build_wait(tree_value(expr), fn, ctx);
243✔
2300

2301
         const int nstmts = tree_stmts(expr);
372✔
2302
         for (int i = 0; i < nstmts; i++)
750✔
2303
            build_wait(tree_stmt(expr, i), fn, ctx);
378✔
2304
      }
2305
      break;
2306

2307
   case T_PROCESS:
52✔
2308
   case T_SEQUENCE:
2309
   case T_PROC_BODY:
2310
      {
2311
         const int ndecls = tree_decls(expr);
52✔
2312
         for (int i = 0; i < ndecls; i++) {
70✔
2313
            tree_t d = tree_decl(expr, i);
18✔
2314
            if (tree_kind(d) == T_PROC_BODY)
18✔
2315
               build_wait(d, fn, ctx);
2✔
2316
         }
2317

2318
         const int nstmts = tree_stmts(expr);
52✔
2319
         for (int i = 0; i < nstmts; i++)
116✔
2320
            build_wait(tree_stmt(expr, i), fn, ctx);
64✔
2321
      }
2322
      break;
2323

2324
   case T_SIGNAL_ASSIGN:
2,460✔
2325
      {
2326
         build_wait_for_target(tree_target(expr), fn, ctx);
2,460✔
2327

2328
         const int nwaves = tree_waveforms(expr);
2,460✔
2329
         for (int i = 0; i < nwaves; i++)
5,085✔
2330
            build_wait(tree_waveform(expr, i), fn, ctx);
2,625✔
2331
      }
2332
      break;
2333

2334
   case T_VAR_ASSIGN:
13✔
2335
   case T_FORCE:
2336
      build_wait_for_target(tree_target(expr), fn, ctx);
13✔
2337
      build_wait(tree_value(expr), fn, ctx);
13✔
2338
      break;
13✔
2339

2340
   case T_RELEASE:
3✔
2341
      build_wait_for_target(tree_target(expr), fn, ctx);
3✔
2342
      break;
3✔
2343

2344
   case T_CASE:
45✔
2345
   case T_MATCH_CASE:
2346
      {
2347
         build_wait(tree_value(expr), fn, ctx);
45✔
2348

2349
         const int nstmts = tree_stmts(expr);
45✔
2350
         for (int i = 0; i < nstmts; i++) {
276✔
2351
            tree_t alt = tree_stmt(expr, i);
231✔
2352

2353
            const int nstmts = tree_stmts(alt);
231✔
2354
            for (int j = 0; j < nstmts; j++)
462✔
2355
               build_wait(tree_stmt(alt, j), fn, ctx);
231✔
2356
         }
2357
      }
2358
      break;
2359

2360
   case T_FOR:
16✔
2361
      {
2362
         build_wait(tree_range(expr, 0), fn, ctx);
16✔
2363

2364
         const int nstmts = tree_stmts(expr);
16✔
2365
         for (int i = 0; i < nstmts; i++)
35✔
2366
            build_wait(tree_stmt(expr, i), fn, ctx);
19✔
2367
      }
2368
      break;
2369

2370
   case T_WHILE:
1✔
2371
      build_wait(tree_value(expr), fn, ctx);
1✔
2372
      // Fall-through
2373
   case T_LOOP:
4✔
2374
      {
2375
         const int nstmts = tree_stmts(expr);
4✔
2376
         for (int i = 0; i < nstmts; i++)
20✔
2377
            build_wait(tree_stmt(expr, i), fn, ctx);
16✔
2378
      }
2379
      break;
2380

2381
   case T_NEXT:
9✔
2382
   case T_EXIT:
2383
      if (tree_has_value(expr))
9✔
2384
         build_wait(tree_value(expr), fn, ctx);
6✔
2385
      break;
2386

2387
   case T_RANGE:
148✔
2388
      if (tree_subkind(expr) == RANGE_EXPR)
148✔
2389
         build_wait(tree_value(expr), fn, ctx);
13✔
2390
      else {
2391
         build_wait(tree_left(expr), fn, ctx);
135✔
2392
         build_wait(tree_right(expr), fn, ctx);
135✔
2393
      }
2394
      break;
2395

UNCOV
2396
   default:
×
2397
      fatal_trace("Cannot handle tree kind %s in wait expression",
2398
                  tree_kind_str(tree_kind(expr)));
2399
   }
2400
}
13,334✔
2401

2402
void print_syntax(const char *fmt, ...)
1,854✔
2403
{
2404
   LOCAL_TEXT_BUF tb = tb_new();
1,854✔
2405
   bool highlighting = false;
1,854✔
2406
   static bool comment = false, last_was_newline = false;
1,854✔
2407
   for (const char *p = fmt; *p != '\0'; p++) {
10,098✔
2408
      if (comment) {
8,244✔
2409
         if (*p == '\n' || *p == '\r') {
3,166✔
2410
            comment = false;
94✔
2411
            last_was_newline = true;
94✔
2412
            tb_printf(tb, "$$\n");
94✔
2413
         }
2414
         else if (*p != '~' && *p != '#') {
3,072✔
2415
            tb_append(tb, *p);
2,912✔
2416
            last_was_newline = false;
2,912✔
2417
         }
2418
         if (p > fmt && *p == '/' && *(p - 1) == '*') {
3,166✔
2419
            tb_printf(tb, "$$");
10✔
2420
            comment = false;
10✔
2421
            last_was_newline = false;
10✔
2422
         }
2423
      }
2424
      else if (*p == '\r') {
5,078✔
2425
         if (!last_was_newline) {
21✔
UNCOV
2426
            tb_append(tb, '\n');
×
UNCOV
2427
            last_was_newline = true;
×
2428
         }
2429
      }
2430
      else if (*p == '#' && *(p + 1) != '#') {
5,057✔
2431
         tb_printf(tb, "$bold$$cyan$");
347✔
2432
         last_was_newline = false;
347✔
2433
         highlighting = true;
347✔
2434
      }
2435
      else if (*p == '~' && *(p + 1) != '~') {
4,710✔
2436
         tb_printf(tb, "$yellow$");
1✔
2437
         last_was_newline = false;
1✔
2438
         highlighting = true;
1✔
2439
      }
2440
      else if ((*p == '-' && *(p + 1) == '-')
4,709✔
2441
               || (*p == '/' && *(p + 1) == '/')
4,619✔
2442
               || (*p == '/' && *(p + 1) == '*')) {
4,615✔
2443
         tb_printf(tb, "$red$%c", *p);
104✔
2444
         last_was_newline = false;
104✔
2445
         comment = true;
104✔
2446
      }
2447
      else if (!isalnum_iso88591(*p) && *p != '_'
4,605✔
2448
               && *p != '%' && highlighting) {
2,335✔
2449
         tb_printf(tb, "$$%c", *p);
304✔
2450
         last_was_newline = false;
304✔
2451
         highlighting = false;
304✔
2452
      }
2453
      else {
2454
         tb_append(tb, *p);
4,301✔
2455
         last_was_newline = (*p == '\n');
4,301✔
2456
      }
2457
   }
2458

2459
   if (highlighting)
1,854✔
2460
      tb_cat(tb, "$$");
44✔
2461

2462
   va_list ap;
1,854✔
2463
   va_start(ap, fmt);
1,854✔
2464

2465
   if (syntax_buf != NULL) {
1,854✔
2466
      char *stripped LOCAL = strip_color(tb_get(tb), ap);
3,708✔
2467
      tb_cat(syntax_buf, stripped);
1,854✔
2468
   }
2469
   else
UNCOV
2470
      color_vprintf(tb_get(tb), ap);
×
2471

2472
   va_end(ap);
1,854✔
2473
}
1,854✔
2474

2475
void capture_syntax(text_buf_t *tb)
9✔
2476
{
2477
   assert(tb == NULL || syntax_buf == NULL);
9✔
2478
   syntax_buf = tb;
9✔
2479
}
9✔
2480

2481
void analyse_file(const char *file, jit_t *jit, unit_registry_t *ur)
3,537✔
2482
{
2483
   input_from_file(file);
3,537✔
2484

2485
   switch (source_kind()) {
3,537✔
2486
   case SOURCE_VHDL:
3,459✔
2487
      {
2488
         lib_t work = lib_work();
3,459✔
2489
         int base_errors = 0;
3,459✔
2490
         tree_t unit;
3,459✔
2491
         while (base_errors = error_count(), (unit = parse())) {
13,392✔
2492
            if (error_count() == base_errors) {
9,933✔
2493
               lib_put(work, unit);
9,932✔
2494
               unit_registry_purge(ur, tree_ident(unit));
9,932✔
2495

2496
               simplify_local(unit, jit, ur);
9,932✔
2497
               bounds_check(unit);
9,932✔
2498
            }
2499
            else
2500
               lib_put_error(work, unit);
1✔
2501
         }
2502
      }
2503
      break;
2504

2505
   case SOURCE_VERILOG:
78✔
2506
      {
2507
         LOCAL_TEXT_BUF tb = tb_new();
156✔
2508
         vlog_preprocess(tb, true);
78✔
2509

2510
         input_from_buffer(tb_get(tb), tb_len(tb), SOURCE_VERILOG);
78✔
2511

2512
         lib_t work = lib_work();
78✔
2513
         vlog_node_t module;
78✔
2514
         while ((module = vlog_parse())) {
248✔
2515
            if (error_count() == 0) {
92✔
2516
               vlog_check(module);
92✔
2517

2518
               if (error_count() == 0) {
92✔
2519
                  vlog_simp(module);
92✔
2520
                  lib_put_vlog(work, module);
92✔
2521
               }
2522
            }
2523
         }
2524
      }
2525
      break;
78✔
2526

2527
   case SOURCE_SDF:
×
2528
      {
UNCOV
2529
         sdf_file_t *sdf_file = sdf_parse(file, 0);
×
2530
         progress("analysed SDF file: %s", file);
×
2531

2532
         if (sdf_file != NULL) {
×
UNCOV
2533
            warnf("SDF is not yet supported");
×
UNCOV
2534
            sdf_file_free(sdf_file);
×
2535
         }
2536
      }
2537
      break;
2538
   }
2539
}
3,534✔
2540

2541
bool all_character_literals(type_t type)
1,871✔
2542
{
2543
   assert(type_is_enum(type));
1,871✔
2544

2545
   type_t base = type_base_recur(type);
1,871✔
2546
   const int nlits = type_enum_literals(base);
1,871✔
2547
   for (int i = 0; i < nlits; i++) {
7,391✔
2548
      if (ident_char(tree_ident(type_enum_literal(base, i)), 0) != '\'')
6,352✔
2549
         return false;
2550
   }
2551

2552
   return true;
2553
}
2554

2555
bool is_operator_symbol(ident_t ident)
27,624✔
2556
{
2557
   const int len = ident_len(ident);
27,624✔
2558
   if (len < 3)
27,624✔
2559
      return false;
2560
   else if (ident_char(ident, 0) != '"')
27,374✔
2561
      return false;
2562
   else if (ident_char(ident, len - 1) != '"')
16,002✔
2563
      return false;
2564

2565
   const well_known_t wk = is_well_known(ident);
16,002✔
2566

2567
   if (standard() < STD_08)
16,002✔
2568
      return wk >= W_OP_AND && wk <= W_OP_NOT;
3,345✔
2569
   else
2570
      return wk >= W_OP_AND && wk <= W_OP_MATCH_GREATER_EQUAL;
12,657✔
2571
}
2572

2573
bool same_tree(tree_t a, tree_t b)
7,179✔
2574
{
2575
   const tree_kind_t akind = tree_kind(a);
7,179✔
2576
   if (akind != tree_kind(b))
7,179✔
2577
      return false;
2578

2579
   switch (akind) {
7,060✔
2580
   case T_REF:
3,398✔
2581
      return tree_ref(a) == tree_ref(b);
3,398✔
2582
   case T_ARRAY_REF:
1,069✔
2583
      {
2584
         if (!same_tree(tree_value(a), tree_value(b)))
1,069✔
2585
            return false;
2586

2587
         const int nparams = tree_params(a);
1,047✔
2588
         assert(nparams == tree_params(b));
1,047✔
2589

2590
         for (int i = 0; i < nparams; i++) {
1,926✔
2591
            tree_t pa = tree_value(tree_param(a, i));
1,722✔
2592
            tree_t pb = tree_value(tree_param(b, i));
1,722✔
2593
            if (!same_tree(pa, pb))
1,722✔
2594
               return false;
2595
         }
2596

2597
         return true;
2598
      }
2599
   case T_ARRAY_SLICE:
38✔
2600
      {
2601
         if (!same_tree(tree_value(a), tree_value(b)))
38✔
2602
            return false;
2603

2604
         tree_t ra = tree_range(a, 0);
38✔
2605
         tree_t rb = tree_range(b, 0);
38✔
2606

2607
         const range_kind_t rakind = tree_subkind(ra);
38✔
2608
         if (rakind != tree_subkind(rb) || rakind == RANGE_EXPR)
38✔
2609
            return false;
2610

2611
         return same_tree(tree_left(ra), tree_left(rb))
38✔
2612
            && same_tree(tree_right(ra), tree_right(rb));
38✔
2613
      }
2614

2615
   case T_RECORD_REF:
747✔
2616
      return tree_ident(a) == tree_ident(b)
747✔
2617
         && same_tree(tree_value(a), tree_value(b));
750✔
2618

2619
   case T_LITERAL:
1,808✔
2620
      {
2621
         const literal_kind_t alkind = tree_subkind(a);
1,808✔
2622
         if (alkind != tree_subkind(b) || alkind != L_INT)
1,808✔
2623
            return false;
2624
         else
2625
            return tree_ival(a) == tree_ival(b);
1,769✔
2626
      }
2627
   default:
2628
      return false;
2629
   }
2630
}
2631

2632
void instance_name_to_path(text_buf_t *tb, const char *str)
9,632✔
2633
{
2634
   bool delete = false;
9,632✔
2635
   for (const char *p = str; *p; p++) {
602,042✔
2636
      if (*p == '@' || (*p == '(' && !isdigit_iso88591(*(p + 1))))
592,410✔
2637
         delete = true;
2638
      else if (*p == ')' && delete)
561,968✔
2639
         delete = false;
2640
      else if (*p == ':') {
541,964✔
2641
         delete = false;
35,920✔
2642
         tb_append(tb, ':');
35,920✔
2643
      }
2644
      else if (!delete)
506,044✔
2645
         tb_append(tb, *p);
302,343✔
2646
   }
2647
}
9,632✔
2648

2649
bool calculate_aggregate_bounds(tree_t expr, range_kind_t *kind,
2,621✔
2650
                                int64_t *left, int64_t *right)
2651
{
2652
   // Calculate the direction and bounds of an array aggregate using the
2653
   // rules in LRM 93 7.3.2.2
2654

2655
   type_t type = tree_type(expr);
2,621✔
2656
   type_t index_type = index_type_of(type, 0);
2,621✔
2657
   if (index_type == NULL || type_is_none(index_type))
2,621✔
2658
      return false;
1✔
2659

2660
   tree_t index_r = range_of(index_type, 0), base_r = index_r;
2,620✔
2661

2662
   int64_t low, high;
2,620✔
2663
   if (!folded_bounds(index_r, &low, &high))
2,620✔
2664
      return false;
2665

2666
   int64_t clow = INT64_MAX, chigh = INT64_MIN;  // Actual bounds computed below
2,605✔
2667

2668
   range_kind_t dir;
2,605✔
2669
   if (type_is_unconstrained(type))
2,605✔
2670
      dir = tree_subkind(index_r);
2,363✔
2671
   else {
2672
      base_r = range_of(type, 0);
242✔
2673
      dir = tree_subkind(base_r);
242✔
2674
   }
2675

2676
   const int nassocs = tree_assocs(expr);
2,605✔
2677

2678
   if (standard() >= STD_08) {
2,605✔
2679
      // VHDL-2008 range association determines index direction for
2680
      // unconstrained aggregate when the expression type matches the
2681
      // array type
2682
      for (int i = 0; i < nassocs; i++) {
3,278✔
2683
         tree_t a = tree_assoc(expr, i);
2,101✔
2684
         if (tree_subkind(a) == A_SLICE)
2,101✔
2685
            dir = tree_subkind(tree_range(a, 0));
47✔
2686
      }
2687
   }
2688

2689
   if (dir != RANGE_TO && dir != RANGE_DOWNTO)
2,605✔
2690
      return false;
2691

2692
   int64_t pos = 0;
2693
   for (int i = 0; i < nassocs; i++) {
11,997✔
2694
      tree_t a = tree_assoc(expr, i);
10,245✔
2695
      int64_t ilow = 0, ihigh = 0;
10,245✔
2696
      const assoc_kind_t akind = tree_subkind(a);
10,245✔
2697

2698
      switch (akind) {
10,245✔
2699
      case A_NAMED:
543✔
2700
         {
2701
            tree_t name = tree_name(a);
543✔
2702
            if (folded_int(name, &ilow))
543✔
2703
               ihigh = ilow;
533✔
2704
            else
2705
               return false;
816✔
2706
         }
2707
         break;
533✔
2708

2709
      case A_RANGE:
1,174✔
2710
      case A_SLICE:
2711
         {
2712
            tree_t r = tree_range(a, 0);
1,174✔
2713
            const range_kind_t rkind = tree_subkind(r);
1,174✔
2714
            if (rkind == RANGE_TO || rkind == RANGE_DOWNTO) {
1,174✔
2715
               tree_t left = tree_left(r), right = tree_right(r);
832✔
2716

2717
               int64_t ileft, iright;
832✔
2718
               if (folded_int(left, &ileft) && folded_int(right, &iright)) {
832✔
2719
                  ilow = (rkind == RANGE_TO ? ileft : iright);
402✔
2720
                  ihigh = (rkind == RANGE_TO ? iright : ileft);
402✔
2721
               }
2722
               else
2723
                  return false;
430✔
2724
            }
2725
            else
2726
               return false;
2727
         }
2728
         break;
2729

2730
      case A_OTHERS:
2731
         return false;
2732

2733
      case A_POS:
8,485✔
2734
         if (i == 0) {
8,485✔
2735
            int64_t ileft;
1,138✔
2736
            if (folded_int(tree_left(base_r), &ileft))
1,138✔
2737
               ilow = ihigh = ileft;
1,138✔
2738
            else
UNCOV
2739
               return false;
×
2740
         }
2741
         else if (dir == RANGE_TO)
7,347✔
2742
            ilow = ihigh = clow + pos;
7,345✔
2743
         else
2744
            ilow = ihigh = chigh - pos;
2✔
2745
         pos++;
8,485✔
2746
         break;
8,485✔
2747

2748
      case A_CONCAT:
41✔
2749
         {
2750
            type_t value_type = tree_type(tree_value(a));
41✔
2751

2752
            int64_t length;
41✔
2753
            if (type_is_unconstrained(value_type))
41✔
2754
               return false;
32✔
2755
            else if (folded_length(range_of(value_type, 0), &length)) {
16✔
2756
               if (i == 0) {
9✔
2757
                  int64_t ileft;
2✔
2758
                  if (folded_int(tree_left(base_r), &ileft))
2✔
2759
                     ilow = ihigh = ileft;
2✔
2760
                  else
UNCOV
2761
                     return false;
×
2762
               }
2763
               else if (dir == RANGE_TO) {
7✔
2764
                  ilow = clow + pos;
7✔
2765
                  ihigh = ilow + length - 1;
7✔
2766
               }
2767
               else {
UNCOV
2768
                  ihigh = chigh - pos;
×
UNCOV
2769
                  ilow = ihigh - length + 1;
×
2770
               }
2771
               pos += length;
9✔
2772
            }
2773
            else
2774
               return false;
2775
         }
2776
         break;
2777
      }
2778

2779
      clow = MIN(clow, ilow);
9,429✔
2780
      chigh = MAX(chigh, ihigh);
9,429✔
2781
   }
2782

2783
   if (clow < low || chigh > high)
1,752✔
2784
      return false;   // Will raise a bounds check error later
2785

2786
   *kind = dir;
1,747✔
2787
   *left = dir == RANGE_TO ? clow : chigh;
1,747✔
2788
   *right = dir == RANGE_TO ? chigh : clow;
1,747✔
2789

2790
   return true;
1,747✔
2791
}
2792

2793
type_t calculate_aggregate_subtype(tree_t expr)
2,395✔
2794
{
2795
   range_kind_t dir;
2,395✔
2796
   int64_t ileft, iright;
2,395✔
2797
   if (!calculate_aggregate_bounds(expr, &dir, &ileft, &iright))
2,395✔
2798
      return NULL;
2799

2800
   type_t type = tree_type(expr);
1,729✔
2801

2802
   const int ndims = dimension_of(type);
1,729✔
2803
   type_t a0_type = NULL;
1,729✔
2804
   if (ndims > 1) {
1,729✔
2805
      a0_type = tree_type(tree_value(tree_assoc(expr, 0)));
66✔
2806
      if (type_is_unconstrained(a0_type))
66✔
2807
         return NULL;
2808

2809
      assert(dimension_of(a0_type) == ndims - 1);
66✔
2810
   }
2811

2812
   type_t index_type = index_type_of(type, 0);
1,729✔
2813

2814
   tree_t left = get_discrete_lit(expr, index_type, ileft);
1,729✔
2815
   tree_t right = get_discrete_lit(expr, index_type, iright);
1,729✔
2816
   assert(left != NULL && right != NULL);
1,729✔
2817

2818
   type_t sub = type_new(T_SUBTYPE);
1,729✔
2819
   type_set_base(sub, type_base_recur(type));
1,729✔
2820

2821
   type_t elem = type_elem(type);
1,729✔
2822
   if (type_is_unconstrained(elem)) {
1,729✔
2823
      a0_type = tree_type(tree_value(tree_assoc(expr, 0)));
91✔
2824
      if (!type_is_unconstrained(a0_type))
91✔
2825
         elem = a0_type;
47✔
2826
   }
2827

2828
   type_set_elem(sub, elem);
1,729✔
2829

2830
   tree_t cons = tree_new(T_CONSTRAINT);
1,729✔
2831
   tree_set_subkind(cons, C_INDEX);
1,729✔
2832

2833
   tree_t r = tree_new(T_RANGE);
1,729✔
2834
   tree_set_subkind(r, dir);
1,729✔
2835
   tree_set_type(r, index_type);
1,729✔
2836
   tree_set_left(r, left);
1,729✔
2837
   tree_set_right(r, right);
1,729✔
2838

2839
   tree_add_range(cons, r);
1,729✔
2840

2841
   for (int i = 1; i < ndims; i++)
1,795✔
2842
      tree_add_range(cons, range_of(a0_type, i - 1));
66✔
2843

2844
   type_add_constraint(sub, cons);
1,729✔
2845

2846
   return sub;
1,729✔
2847
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc