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

nickg / nvc / 14229470486

02 Apr 2025 08:26PM UTC coverage: 92.323% (+0.004%) from 92.319%
14229470486

push

github

nickg
Fix incorrect handling of array-of-array aggregate

4 of 4 new or added lines in 1 file covered. (100.0%)

206 existing lines in 7 files now uncovered.

68754 of 74471 relevant lines covered (92.32%)

422127.68 hits per line

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

94.89
/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)
372,371✔
46
{
47
   int64_t value;
372,371✔
48
   if (folded_int(t, &value))
372,371✔
49
      return value;
372,371✔
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)
27,283✔
56
{
57
   assert(tree_kind(r) == T_RANGE);
27,283✔
58

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

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

66
bool folded_int(tree_t t, int64_t *l)
3,635,303✔
67
{
68
   switch (tree_kind(t)) {
3,668,417✔
69
   case T_LITERAL:
2,654,528✔
70
      switch (tree_subkind(t)) {
2,654,528✔
71
      case L_PHYSICAL:
16,729✔
72
         if (tree_has_ref(t))
16,729✔
73
            return false;
74
         // Fall-through
75
      case L_INT:
76
         *l = tree_ival(t);
2,608,029✔
77
         return true;
2,608,029✔
78
      default:
79
         return false;
80
      }
81
   case T_QUALIFIED:
342✔
82
      return folded_int(tree_value(t), l);
342✔
83
   case T_REF:
799,634✔
84
      if (tree_has_ref(t)) {
799,634✔
85
         tree_t decl = tree_ref(t);
799,633✔
86
         switch (tree_kind(decl)) {
799,633✔
87
         case T_CONST_DECL:
40,404✔
88
            if (tree_has_value(decl))
40,404✔
89
               return folded_int(tree_value(decl), l);
32,433✔
90
            else
91
               return false;
92
         case T_ENUM_LIT:
688,612✔
93
            *l = tree_pos(decl);
688,612✔
94
            return true;
688,612✔
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)
194,865✔
108
{
109
   switch (tree_kind(t)) {
194,868✔
110
   case T_LITERAL:
186,597✔
111
      if (tree_subkind(t) == L_REAL) {
186,597✔
112
         *l = tree_dval(t);
186,526✔
113
         return true;
186,526✔
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)
56,271✔
125
{
126
   int64_t low, high;
56,271✔
127
   if (folded_bounds(r, &low, &high)) {
56,271✔
128
      *l = MAX(high - low + 1, 0);
53,429✔
129
      return true;
53,429✔
130
   }
131
   else
132
      return false;
133
}
134

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

139
   const range_kind_t rkind = tree_subkind(r);
1,503,666✔
140

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

144
   int64_t left, right;
1,491,053✔
145
   if (!folded_int(tree_left(r), &left))
1,491,053✔
146
      return false;
147
   else if (!folded_int(tree_right(r), &right))
1,379,584✔
148
      return false;
149

150
   switch (rkind) {
1,344,012✔
151
   case RANGE_TO:
1,217,734✔
152
      *low  = left;
1,217,734✔
153
      *high = right;
1,217,734✔
154
      return true;
1,217,734✔
155
   case RANGE_DOWNTO:
126,278✔
156
      *low  = right;
126,278✔
157
      *high = left;
126,278✔
158
      return true;
126,278✔
159
   default:
160
      return false;
161
   }
162
}
163

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

168
   const range_kind_t rkind = tree_subkind(r);
77,776✔
169

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

173
   double left, right;
77,773✔
174
   if (folded_real(tree_left(r), &left) && folded_real(tree_right(r), &right)) {
77,773✔
175
      switch (rkind) {
77,688✔
176
      case RANGE_TO:
77,688✔
177
         *low  = left;
77,688✔
178
         *high = right;
77,688✔
179
         return true;
77,688✔
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)
41,182✔
193
{
194
   if (tree_kind(t) == T_REF) {
41,182✔
195
      tree_t decl = tree_ref(t);
10,817✔
196
      if (tree_kind(decl) == T_ENUM_LIT
10,817✔
197
          && type_ident(tree_type(decl)) == well_known(W_STD_BOOL)) {
8,405✔
198
         *b = (tree_pos(decl) == 1);
8,405✔
199
         return true;
8,405✔
200
      }
201
   }
202

203
   return false;
204
}
205

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

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

217
   return b;
7,538✔
218
}
219

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

228
   return f;
41,923✔
229
}
230

231
tree_t get_discrete_lit(tree_t t, type_t type, int64_t i)
3,508✔
232
{
233
   if (type_is_enum(type)) {
3,508✔
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,440✔
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,780✔
420
{
421
   tree_t t = tree_new(T_REF);
7,780✔
422
   tree_set_ident(t, tree_ident(to));
7,780✔
423
   tree_set_ref(t, to);
7,780✔
424
   tree_set_type(t, tree_type(to));
7,780✔
425
   return t;
7,780✔
426
}
427

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

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

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

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

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

457
tree_t find_element_mode_indication(tree_t view, tree_t field, bool *converse)
397✔
458
{
459
   switch (tree_kind(view)) {
1,255✔
460
   case T_REF:
541✔
461
      return find_element_mode_indication(tree_ref(view), field, converse);
541✔
462

463
   case T_ALIAS:
144✔
464
      return find_element_mode_indication(tree_value(view), field, converse);
144✔
465

466
   case T_ATTR_REF:
173✔
467
      assert(tree_subkind(view) == ATTR_CONVERSE);
173✔
468
      *converse = !*converse;
173✔
469
      return find_element_mode_indication(tree_name(view), field, converse);
173✔
470

471
   case T_VIEW_DECL:
397✔
472
      {
473
         type_t view_type = tree_type(view);
397✔
474
         assert(type_kind(view_type) == T_VIEW);
397✔
475

476
         const int nelems = type_fields(view_type);
397✔
477
         for (int i = 0; i < nelems; i++) {
673✔
478
            tree_t e = type_field(view_type, i);
673✔
479
            if (tree_ref(e) == field)
673✔
480
               return e;
397✔
481
         }
482

483
         return NULL;
484
      }
485

486
   default:
×
487
      fatal_trace("unhandled tree kind %s in find_element_mode_indication",
488
                  tree_kind_str(tree_kind(view)));
489
   }
490
}
491

492
port_mode_t converse_mode(tree_t port, bool converse)
265✔
493
{
494
   const port_mode_t mode = tree_subkind(port);
265✔
495
   switch (mode) {
265✔
496
   case PORT_IN: return converse ? PORT_OUT : PORT_IN;
135✔
497
   case PORT_OUT: return converse ? PORT_IN : PORT_OUT;
121✔
498
   default: return mode;
499
   }
500
}
501

502
class_t class_of(tree_t t)
1,019,928✔
503
{
504
   switch (tree_kind(t)) {
1,073,453✔
505
   case T_VAR_DECL:
506
      return C_VARIABLE;
507
   case T_SIGNAL_DECL:
45,944✔
508
   case T_IMPLICIT_SIGNAL:
509
      return C_SIGNAL;
45,944✔
510
   case T_CONST_DECL:
36,999✔
511
      return C_CONSTANT;
36,999✔
512
   case T_PORT_DECL:
152,572✔
513
   case T_GENERIC_DECL:
514
   case T_PARAM_DECL:
515
   case T_EXTERNAL_NAME:
516
      return tree_class(t);
152,572✔
517
   case T_ENUM_LIT:
589,623✔
518
   case T_LITERAL:
519
   case T_STRING:
520
      return C_LITERAL;
589,623✔
521
   case T_FIELD_DECL:
1,055✔
522
   case T_ATTR_DECL:
523
      return C_DEFAULT;
1,055✔
524
   case T_VIEW_DECL:
126✔
525
      return C_VIEW;
126✔
526
   case T_UNIT_DECL:
7,564✔
527
      return C_UNITS;
7,564✔
528
   case T_ARCH:
47✔
529
      return C_ARCHITECTURE;
47✔
530
   case T_FUNC_DECL:
5,566✔
531
   case T_FUNC_BODY:
532
   case T_FUNC_INST:
533
   case T_FCALL:
534
   case T_PROT_FCALL:
535
      return C_FUNCTION;
5,566✔
536
   case T_PROC_DECL:
10,264✔
537
   case T_PROC_BODY:
538
   case T_PROC_INST:
539
   case T_PCALL:
540
   case T_PROT_PCALL:
541
      return C_PROCEDURE;
10,264✔
542
   case T_ENTITY:
135✔
543
      return C_ENTITY;
135✔
544
   case T_SUBTYPE_DECL:
18,786✔
545
      return C_SUBTYPE;
18,786✔
546
   case T_TYPE_DECL:
72,277✔
547
   case T_PROT_DECL:
548
   case T_PROT_BODY:
549
      return C_TYPE;
72,277✔
550
   case T_FILE_DECL:
1,113✔
551
      return C_FILE;
1,113✔
552
   case T_PROCESS:
138✔
553
   case T_BLOCK:
554
   case T_FOR:
555
   case T_INSTANCE:
556
   case T_CONCURRENT:
557
   case T_ELAB:
558
   case T_PSL_DECL:
559
   case T_PSL_DIRECT:
560
   case T_FOR_GENERATE:
561
   case T_IF_GENERATE:
562
   case T_CASE_GENERATE:
563
      return C_LABEL;
138✔
564
   case T_COMPONENT:
1✔
565
      return C_COMPONENT;
1✔
566
   case T_REF:
44,748✔
567
   case T_PROT_REF:
568
      return tree_has_ref(t) ? class_of(tree_ref(t)) : C_DEFAULT;
44,748✔
569
   case T_ARRAY_REF:
8,781✔
570
   case T_ARRAY_SLICE:
571
   case T_RECORD_REF:
572
   case T_ALL:
573
   case T_ALIAS:
574
   case T_QUALIFIED:
575
      return class_of(tree_value(t));
8,781✔
576
   case T_PACKAGE:
1,227✔
577
   case T_PACK_BODY:
578
   case T_PACK_INST:
579
      return C_PACKAGE;
1,227✔
580
   case T_CONFIGURATION:
1✔
581
      return C_CONFIGURATION;
1✔
582
   case T_LIBRARY:
1✔
583
      return C_LIBRARY;
1✔
584
   case T_ATTR_REF:
82✔
585
      switch (tree_subkind(t)) {
82✔
586
      case ATTR_DELAYED:
587
      case ATTR_STABLE:
588
      case ATTR_QUIET:
589
      case ATTR_TRANSACTION:
590
         return C_SIGNAL;
591
      default:
76✔
592
         return C_DEFAULT;
76✔
593
      }
594
   case T_CONTEXT:
×
595
      return C_CONTEXT;
×
596
   default:
×
597
      fatal_trace("missing class_of for %s", tree_kind_str(tree_kind(t)));
598
   }
599
}
600

601
bool class_has_type(class_t c)
863,754✔
602
{
603
   switch (c) {
863,754✔
604
   case C_LABEL:
605
   case C_ENTITY:
606
   case C_ARCHITECTURE:
607
   case C_COMPONENT:
608
   case C_CONFIGURATION:
609
   case C_PACKAGE:
610
   case C_LIBRARY:
611
      return false;
612
   default:
862,476✔
613
      return true;
862,476✔
614
   }
615
}
616

617
const char *class_str(class_t c)
445✔
618
{
619
   static const char *strs[] = {
445✔
620
      "default", "signal", "variable", "constant", "file", "entity",
621
      "component", "configuration", "architecture", "function", "package",
622
      "type", "subtype", "label", "procedure", "literal", "units", "library",
623
      "context", "view",
624
   };
625
   assert(c < ARRAY_LEN(strs));
445✔
626
   return strs[c];
445✔
627
}
628

629
const char *assoc_kind_str(assoc_kind_t akind)
9✔
630
{
631
   switch (akind) {
9✔
632
   case A_NAMED:  return "named";
633
   case A_CONCAT:
2✔
634
   case A_POS:    return "positional";
2✔
635
   case A_OTHERS: return "others";
3✔
636
   case A_SLICE:
1✔
637
   case A_RANGE:  return "range";
1✔
638
   default:       return "??";
×
639
   }
640
}
641

642
bool is_subprogram(tree_t t)
793,234✔
643
{
644
   switch (tree_kind(t)) {
793,234✔
645
   case T_FUNC_DECL:
646
   case T_FUNC_BODY:
647
   case T_FUNC_INST:
648
   case T_PROC_DECL:
649
   case T_PROC_BODY:
650
   case T_PROC_INST:
651
      return true;
652
   case T_GENERIC_DECL:
2,867✔
653
      {
654
         const class_t class = tree_class(t);
2,867✔
655
         return class == C_FUNCTION || class == C_PROCEDURE;
2,867✔
656
      }
657
   default:
623,236✔
658
      return false;
623,236✔
659
   }
660
}
661

662
bool is_loop_stmt(tree_t t)
421✔
663
{
664
   const tree_kind_t kind = tree_kind(t);
421✔
665
   return kind == T_WHILE || kind == T_FOR || kind == T_LOOP;
421✔
666
}
667

668
bool is_container(tree_t t)
10,478✔
669
{
670
   switch (tree_kind(t)) {
10,478✔
671
   case T_FUNC_BODY:
672
   case T_PROC_BODY:
673
   case T_ENTITY:
674
   case T_ARCH:
675
   case T_PACKAGE:
676
   case T_PACK_BODY:
677
   case T_CONFIGURATION:
678
   case T_BLOCK:
679
   case T_PROT_BODY:
680
   case T_ELAB:
681
   case T_FOR:
682
   case T_PROCESS:
683
   case T_PACK_INST:
684
      return true;
685
   default:
8,134✔
686
      return false;
8,134✔
687
   }
688
}
689

690
bool is_concurrent_block(tree_t t)
1,132✔
691
{
692
   switch (tree_kind(t)) {
1,132✔
693
   case T_ARCH:
694
   case T_ENTITY:
695
   case T_BLOCK:
696
   case T_IF_GENERATE:
697
   case T_FOR_GENERATE:
698
      return true;
699
   default:
376✔
700
      return false;
376✔
701
   }
702
}
703

704
bool is_package(tree_t t)
31,742✔
705
{
706
   switch (tree_kind(t)) {
31,742✔
707
   case T_PACKAGE:
708
   case T_PACK_BODY:
709
   case T_PACK_INST:
710
      return true;
711
   default:
1,008✔
712
      return false;
1,008✔
713
   }
714
}
715

716
bool is_design_unit(tree_t t)
38,711✔
717
{
718
   switch (tree_kind(t)) {
38,711✔
719
   case T_ENTITY:
720
   case T_ARCH:
721
   case T_PACKAGE:
722
   case T_PACK_BODY:
723
   case T_CONFIGURATION:
724
   case T_CONTEXT:
725
   case T_PACK_INST:
726
      return true;
727
   default:
8,623✔
728
      return false;
8,623✔
729
   }
730
}
731

732
bool is_literal(tree_t t)
31,755✔
733
{
734
   switch (tree_kind(t)) {
31,755✔
735
   case T_REF:
3,104✔
736
      return tree_has_ref(t) && tree_kind(tree_ref(t)) == T_ENUM_LIT;
4,307✔
737
   case T_LITERAL:
738
      return true;
739
   case T_STRING:
22,753✔
740
   default:
741
      return false;
22,753✔
742
   }
743
}
744

745
bool is_body(tree_t t)
7,031✔
746
{
747
   switch (tree_kind(t)) {
7,031✔
748
   case T_FUNC_BODY:
749
   case T_PROC_BODY:
750
   case T_PACK_BODY:
751
   case T_PROT_BODY:
752
      return true;
753
   default:
43✔
754
      return false;
43✔
755
   }
756
}
757

758
bool is_guarded_signal(tree_t decl)
13,892✔
759
{
760
   switch (tree_kind(decl)) {
13,892✔
761
   case T_PORT_DECL:
13,500✔
762
   case T_SIGNAL_DECL:
763
      return !!(tree_flags(decl) & (TREE_F_BUS | TREE_F_REGISTER));
13,500✔
764
   default:
765
      return false;
766
   }
767
}
768

769
bool is_type_decl(tree_t t)
1,006,973✔
770
{
771
   switch (tree_kind(t)) {
1,006,973✔
772
   case T_TYPE_DECL:
773
   case T_SUBTYPE_DECL:
774
   case T_PROT_DECL:
775
   case T_PROT_BODY:
776
      return true;
777
   default:
827,837✔
778
      return false;
827,837✔
779
   }
780
}
781

782
tree_t aliased_type_decl(tree_t decl)
125,922✔
783
{
784
   switch (tree_kind(decl)) {
126,186✔
785
   case T_ALIAS:
266✔
786
      {
787
         tree_t value = tree_value(decl);
266✔
788
         const tree_kind_t kind = tree_kind(value);
266✔
789
         if (kind == T_REF && tree_has_ref(value))
266✔
790
            return aliased_type_decl(tree_ref(value));
264✔
791
         else if (kind == T_ATTR_REF && is_type_attribute(tree_subkind(value)))
2✔
792
             return value;
793
         else
794
            return NULL;
×
795
      }
796
   case T_TYPE_DECL:
797
   case T_SUBTYPE_DECL:
798
   case T_PROT_DECL:
799
   case T_PROT_BODY:
800
      return decl;
801
   case T_GENERIC_DECL:
1,521✔
802
      if (tree_class(decl) == C_TYPE)
1,521✔
803
         return decl;
804
      else
805
         return NULL;
740✔
806
   default:
30,319✔
807
      return NULL;
30,319✔
808
   }
809
}
810

811
tree_t add_param(tree_t call, tree_t value, param_kind_t kind, tree_t name)
159,058✔
812
{
813
   tree_t p = tree_new(T_PARAM);
159,058✔
814
   tree_set_loc(p, tree_loc(value));
159,058✔
815
   tree_set_subkind(p, kind);
159,058✔
816
   tree_set_value(p, value);
159,058✔
817

818
   switch (kind) {
159,058✔
819
   case P_NAMED:
74✔
820
      assert(name != NULL);
74✔
821
      tree_set_name(p, name);
74✔
822
      break;
74✔
823
   case P_POS:
158,984✔
824
      tree_set_pos(p, tree_params(call));
158,984✔
825
      break;
158,984✔
826
   }
827

828
   tree_add_param(call, p);
159,058✔
829
   return p;
159,058✔
830
}
831

832
type_t array_aggregate_type(type_t array, int from_dim)
291✔
833
{
834
   if (type_is_none(array))
291✔
835
      return type_new(T_NONE);
2✔
836

837
   if (type_is_unconstrained(array)) {
289✔
838
      const int nindex = type_indexes(array);
45✔
839
      assert(from_dim < nindex);
45✔
840

841
      type_t type = type_new(T_ARRAY);
45✔
842
      type_set_ident(type, type_ident(array));
45✔
843
      type_set_elem(type, type_elem(array));
45✔
844

845
      for (int i = from_dim; i < nindex; i++)
90✔
846
         type_add_index(type, type_index(array, i));
45✔
847

848
      return type;
849
   }
850
   else {
851
      const int ndims = dimension_of(array);
244✔
852
      assert(from_dim < ndims);
244✔
853

854
      type_t base = type_new(T_ARRAY);
244✔
855
      type_set_ident(base, type_ident(array));
244✔
856
      type_set_elem(base, type_elem(array));
244✔
857

858
      tree_t constraint = tree_new(T_CONSTRAINT);
244✔
859
      tree_set_subkind(constraint, C_INDEX);
244✔
860

861
      type_t sub = type_new(T_SUBTYPE);
244✔
862
      type_set_base(sub, base);
244✔
863
      type_set_constraint(sub, constraint);
244✔
864

865
      for (int i = from_dim; i < ndims; i++) {
510✔
866
         tree_t r = range_of(array, i);
266✔
867
         if (r == NULL) {
266✔
868
            // Not enough constraints were provided for the type
869
            r = tree_new(T_RANGE);
1✔
870
            tree_set_subkind(r, RANGE_ERROR);
1✔
871
            tree_set_type(r, type_new(T_NONE));
1✔
872
         }
873

874
         type_add_index(base, tree_type(r));
266✔
875
         tree_add_range(constraint, r);
266✔
876
      }
877

878
      return sub;
879
   }
880
}
881

882
unsigned bits_for_range(int64_t low, int64_t high)
1,840,426✔
883
{
884
   if (low > high)
1,840,426✔
885
      return 0;   // Null range
886
   else if (low < 0) {
1,840,425✔
887
      // Signed integers
888
      if (low >= INT8_MIN && high <= INT8_MAX)
559,533✔
889
         return 8;
890
      else if (low >= INT16_MIN && high <= INT16_MAX)
552,591✔
891
         return 16;
892
      else if (low >= INT32_MIN && high <= INT32_MAX)
552,331✔
893
         return 32;
894
      else
895
         return 64;
125,595✔
896
   }
897
   else {
898
      // Unsigned integers
899
      if (high <= 1)
1,280,892✔
900
         return 1;
901
      else if (high <= UINT8_MAX)
661,570✔
902
         return 8;
903
      else if (high <= UINT16_MAX)
197,933✔
904
         return 16;
905
      else if (high <= UINT32_MAX)
194,570✔
906
         return 32;
907
      else
908
         return 64;
57,176✔
909
   }
910
}
911

912
unsigned dimension_of(type_t type)
1,201,001✔
913
{
914
   switch (type_kind(type)) {
2,242,495✔
915
   case T_SUBTYPE:
1,041,492✔
916
      return dimension_of(type_base(type));
1,041,492✔
917
   case T_GENERIC:
133✔
918
      switch (type_subkind(type)) {
133✔
919
      case GTYPE_ARRAY:
121✔
920
         return type_indexes(type);
121✔
921
      case GTYPE_ACCESS:
×
922
         return dimension_of(type_designated(type));
×
923
      case GTYPE_FILE:
924
      case GTYPE_PRIVATE:
925
         return 0;
926
      default:
12✔
927
         return 1;
12✔
928
      }
929
   case T_ARRAY:
1,193,842✔
930
      return type_indexes(type);
1,193,842✔
931
   case T_NONE:
932
   case T_RECORD:
933
   case T_INCOMPLETE:
934
   case T_FILE:
935
      return 0;
936
   case T_INTEGER:
6,967✔
937
   case T_REAL:
938
   case T_PHYSICAL:
939
   case T_ENUM:
940
      return type_dims(type);
6,967✔
941
   case T_ACCESS:
2✔
942
      return dimension_of(type_designated(type));
2✔
943
   default:
×
944
      fatal_trace("invalid type kind %s in dimension_of",
945
                  type_kind_str(type_kind(type)));
946
   }
947
}
948

949
tree_t range_of(type_t type, unsigned dim)
1,528,001✔
950
{
951
   switch (type_kind(type)) {
1,557,961✔
952
   case T_SUBTYPE:
1,223,096✔
953
      if (type_has_constraint(type)) {
1,223,096✔
954
         tree_t c = type_constraint(type);
1,193,136✔
955
         switch (tree_subkind(c)) {
1,193,136✔
956
         case C_INDEX:
1,193,136✔
957
         case C_RANGE:
958
            if (dim < tree_ranges(c))
1,193,136✔
959
               return tree_range(c, dim);
1,193,135✔
960
            else
961
               return NULL;   // Must be an error
962
         default:
×
963
            should_not_reach_here();
964
         }
965
      }
966
      else
967
         return range_of(type_base(type), dim);
29,960✔
968
   case T_INTEGER:
334,865✔
969
   case T_REAL:
970
   case T_PHYSICAL:
971
   case T_ENUM:
972
      return type_dim(type, dim);
334,865✔
973
   default:
×
974
      fatal_trace("invalid type kind %s for %s in range_of",
975
                  type_kind_str(type_kind(type)), type_pp(type));
976
   }
977
}
978

979
range_kind_t direction_of(type_t type, unsigned dim)
24,604✔
980
{
981
   switch (type_kind(type)) {
24,684✔
982
   case T_ENUM:
983
      return RANGE_TO;
984
   case T_NONE:
×
985
      return RANGE_ERROR;
×
986
   case T_INTEGER:
24,579✔
987
   case T_REAL:
988
   case T_PHYSICAL:
989
   case T_SUBTYPE:
990
      {
991
         tree_t r = range_of(type, dim);
24,579✔
992
         const range_kind_t rkind = tree_subkind(r);
24,579✔
993
         if (rkind == RANGE_EXPR) {
24,579✔
994
            // Return a fixed direction if possible
995
            tree_t value = tree_value(r);
149✔
996
            assert(tree_kind(value) == T_ATTR_REF);
149✔
997

998
            DEBUG_ONLY({
149✔
999
                  const attr_kind_t attr = tree_subkind(value);
1000
                  assert(attr == ATTR_RANGE || attr == ATTR_REVERSE_RANGE);
1001
               });
149✔
1002

1003
            tree_t name = tree_name(value);
149✔
1004
            if (tree_kind(name) == T_REF && tree_has_ref(name)) {
149✔
1005
               tree_t decl = tree_ref(name);
148✔
1006
               if (is_type_decl(decl))
148✔
1007
                  return direction_of(tree_type(decl), 0);
80✔
1008
            }
1009
         }
1010

1011
         return rkind;
1012
      }
1013
   default:
×
1014
      fatal_trace("invalid type kind %s in direction_of",
1015
                  type_kind_str(type_kind(type)));
1016
   }
1017
}
1018

1019
type_t index_type_of(type_t type, unsigned dim)
212,749✔
1020
{
1021
   if (dim >= dimension_of(type))
212,751✔
1022
      return NULL;
1023

1024
   type_t base = type_base_recur(type);
212,722✔
1025
   type_kind_t base_kind = type_kind(base);
212,722✔
1026
   if (base_kind == T_ARRAY)
212,722✔
1027
      return type_index(base, dim);
209,398✔
1028
   else if (base_kind == T_ENUM || base_kind == T_NONE)
3,324✔
1029
      return type;
1030
   else if (base_kind == T_GENERIC && type_subkind(base) == GTYPE_ARRAY)
3,170✔
1031
      return type_index(base, dim);
74✔
1032
   else if (base_kind == T_RECORD || base_kind == T_GENERIC)
3,096✔
1033
      return NULL;
1034
   else if (base_kind == T_ACCESS)
3,090✔
1035
      return index_type_of(type_designated(type), dim);
2✔
1036
   else
1037
      return tree_type(range_of(base, dim));
3,088✔
1038
}
1039

1040
int64_t rebase_index(type_t array_type, int dim, int64_t value)
384✔
1041
{
1042
   // Convert value which is in the range of array_type to a zero-based index
1043
   tree_t r = range_of(array_type, dim);
384✔
1044
   const int64_t left = assume_int(tree_left(r));
384✔
1045
   return (tree_subkind(r) == RANGE_TO) ? value - left : left - value;
384✔
1046
}
1047

1048
ident_t well_known(well_known_t id)
405,076✔
1049
{
1050
   assert(id < NUM_WELL_KNOWN);
405,076✔
1051
   return id_cache[id];
405,076✔
1052
}
1053

1054
well_known_t is_well_known(ident_t ident)
270,853✔
1055
{
1056
   well_known_t pos = 0;
270,853✔
1057
   for (; pos < NUM_WELL_KNOWN; pos++) {
14,847,851✔
1058
      if (id_cache[pos] == ident)
14,708,391✔
1059
         break;
1060
   }
1061

1062
   return pos;
270,853✔
1063
}
1064

1065
void intern_strings(void)
5,174✔
1066
{
1067
   id_cache[W_STD_STANDARD]    = ident_new("STD.STANDARD");
5,174✔
1068
   id_cache[W_ALL]             = ident_new("all");
5,174✔
1069
   id_cache[W_STD_BIT]         = ident_new("STD.STANDARD.BIT");
5,174✔
1070
   id_cache[W_STD_BOOL]        = ident_new("STD.STANDARD.BOOLEAN");
5,174✔
1071
   id_cache[W_STD_CHAR]        = ident_new("STD.STANDARD.CHARACTER");
5,174✔
1072
   id_cache[W_STD_NATURAL]     = ident_new("STD.STANDARD.NATURAL");
5,174✔
1073
   id_cache[W_STD_POSITIVE]    = ident_new("STD.STANDARD.POSITIVE");
5,174✔
1074
   id_cache[W_STD_INTEGER]     = ident_new("STD.STANDARD.INTEGER");
5,174✔
1075
   id_cache[W_STD_STRING]      = ident_new("STD.STANDARD.STRING");
5,174✔
1076
   id_cache[W_STD_REAL]        = ident_new("STD.STANDARD.REAL");
5,174✔
1077
   id_cache[W_STD_TIME]        = ident_new("STD.STANDARD.TIME");
5,174✔
1078
   id_cache[W_STD_BIT_VECTOR]  = ident_new("STD.STANDARD.BIT_VECTOR");
5,174✔
1079
   id_cache[W_IEEE_SIGNED]     = ident_new("IEEE.NUMERIC_STD.SIGNED");
5,174✔
1080
   id_cache[W_IEEE_UNSIGNED]   = ident_new("IEEE.NUMERIC_STD.UNSIGNED");
5,174✔
1081
   id_cache[W_IEEE_LOGIC]      = ident_new("IEEE.STD_LOGIC_1164.STD_LOGIC");
5,174✔
1082
   id_cache[W_IEEE_ULOGIC]     = ident_new("IEEE.STD_LOGIC_1164.STD_ULOGIC");
5,174✔
1083
   id_cache[W_IEEE_1164_AND]   = ident_new("IEEE.STD_LOGIC_1164.\"and\"");
5,174✔
1084
   id_cache[W_IEEE_1164_NAND]  = ident_new("IEEE.STD_LOGIC_1164.\"nand\"");
5,174✔
1085
   id_cache[W_IEEE_1164_OR]    = ident_new("IEEE.STD_LOGIC_1164.\"or\"");
5,174✔
1086
   id_cache[W_IEEE_1164_NOR]   = ident_new("IEEE.STD_LOGIC_1164.\"nor\"");
5,174✔
1087
   id_cache[W_IEEE_1164_XOR]   = ident_new("IEEE.STD_LOGIC_1164.\"xor\"");
5,174✔
1088
   id_cache[W_IEEE_1164_XNOR]  = ident_new("IEEE.STD_LOGIC_1164.\"xnor\"");
5,174✔
1089
   id_cache[W_FOREIGN]         = ident_new("FOREIGN");
5,174✔
1090
   id_cache[W_WORK]            = ident_new("WORK");
5,174✔
1091
   id_cache[W_STD]             = ident_new("STD");
5,174✔
1092
   id_cache[W_THUNK]           = ident_new("thunk");
5,174✔
1093
   id_cache[W_BODY]            = ident_new("body");
5,174✔
1094
   id_cache[W_CARET]           = ident_new("^");
5,174✔
1095
   id_cache[W_IEEE]            = ident_new("IEEE");
5,174✔
1096
   id_cache[W_IEEE_1164]       = ident_new("IEEE.STD_LOGIC_1164");
5,174✔
1097
   id_cache[W_ERROR]           = ident_new("$error");
5,174✔
1098
   id_cache[W_ELAB]            = ident_new("elab");
5,174✔
1099
   id_cache[W_NUMERIC_STD]     = ident_new("IEEE.NUMERIC_STD");
5,174✔
1100
   id_cache[W_NUMERIC_BIT]     = ident_new("IEEE.NUMERIC_BIT");
5,174✔
1101
   id_cache[W_NVC]             = ident_new("NVC");
5,174✔
1102
   id_cache[W_DEFAULT_CLOCK]   = ident_new("default clock");
5,174✔
1103
   id_cache[W_STD_REFLECTION]  = ident_new("STD.REFLECTION");
5,174✔
1104
   id_cache[W_NEVER_WAITS]     = ident_new("NEVER_WAITS");
5,174✔
1105
   id_cache[W_NVC_VERILOG]     = ident_new("NVC.VERILOG");
5,174✔
1106
   id_cache[W_NVC_PSL_SUPPORT] = ident_new("NVC.PSL_SUPPORT");
5,174✔
1107
   id_cache[W_SHAPE]           = ident_new("shape");
5,174✔
1108
   id_cache[W_INSTANCE_NAME]   = ident_new("instance_name");
5,174✔
1109
   id_cache[W_PATH_NAME]       = ident_new("path_name");
5,174✔
1110
   id_cache[W_VITAL]           = ident_new("VITAL");
5,174✔
1111
   id_cache[W_RESOLUTION]      = ident_new("resolution");
5,174✔
1112
   id_cache[W_TEXT_UTIL]       = ident_new("NVC.TEXT_UTIL");
5,174✔
1113
   id_cache[W_IEEE_SUPPORT]    = ident_new("NVC.IEEE_SUPPORT");
5,174✔
1114

1115
   id_cache[W_IEEE_LOGIC_VECTOR] =
10,348✔
1116
      ident_new("IEEE.STD_LOGIC_1164.STD_LOGIC_VECTOR");
5,174✔
1117
   id_cache[W_IEEE_ULOGIC_VECTOR] =
10,348✔
1118
      ident_new("IEEE.STD_LOGIC_1164.STD_ULOGIC_VECTOR");
5,174✔
1119
   id_cache[W_IEEE_1164_RISING_EDGE] =
10,348✔
1120
      ident_new("IEEE.STD_LOGIC_1164.RISING_EDGE(sU)B");
5,174✔
1121
   id_cache[W_IEEE_1164_FALLING_EDGE] =
10,348✔
1122
      ident_new("IEEE.STD_LOGIC_1164.FALLING_EDGE(sU)B");
5,174✔
1123

1124
   id_cache[W_NUMERIC_STD_UNSIGNED] = ident_new("IEEE.NUMERIC_STD_UNSIGNED");
5,174✔
1125
   id_cache[W_NUMERIC_BIT_UNSIGNED] = ident_new("IEEE.NUMERIC_BIT_UNSIGNED");
5,174✔
1126

1127
   id_cache[W_OP_CCONV]               = ident_new("\"??\"");
5,174✔
1128
   id_cache[W_OP_AND]                 = ident_new("\"and\"");
5,174✔
1129
   id_cache[W_OP_OR]                  = ident_new("\"or\"");
5,174✔
1130
   id_cache[W_OP_NAND]                = ident_new("\"nand\"");
5,174✔
1131
   id_cache[W_OP_NOR]                 = ident_new("\"nor\"");
5,174✔
1132
   id_cache[W_OP_XOR]                 = ident_new("\"xor\"");
5,174✔
1133
   id_cache[W_OP_XNOR]                = ident_new("\"xnor\"");
5,174✔
1134
   id_cache[W_OP_EQUAL]               = ident_new("\"=\"");
5,174✔
1135
   id_cache[W_OP_NOT_EQUAL]           = ident_new("\"/=\"");
5,174✔
1136
   id_cache[W_OP_LESS_THAN]           = ident_new("\"<\"");
5,174✔
1137
   id_cache[W_OP_LESS_EQUAL]          = ident_new("\"<=\"");
5,174✔
1138
   id_cache[W_OP_GREATER_THAN]        = ident_new("\">\"");
5,174✔
1139
   id_cache[W_OP_GREATER_EQUAL]       = ident_new("\">=\"");
5,174✔
1140
   id_cache[W_OP_MATCH_EQUAL]         = ident_new("\"?=\"");
5,174✔
1141
   id_cache[W_OP_MATCH_NOT_EQUAL]     = ident_new("\"?/=\"");
5,174✔
1142
   id_cache[W_OP_MATCH_LESS_THAN]     = ident_new("\"?<\"");
5,174✔
1143
   id_cache[W_OP_MATCH_LESS_EQUAL]    = ident_new("\"?<=\"");
5,174✔
1144
   id_cache[W_OP_MATCH_GREATER_THAN]  = ident_new("\"?>\"");
5,174✔
1145
   id_cache[W_OP_MATCH_GREATER_EQUAL] = ident_new("\"?>=\"");
5,174✔
1146
   id_cache[W_OP_SLL]                 = ident_new("\"sll\"");
5,174✔
1147
   id_cache[W_OP_SRL]                 = ident_new("\"srl\"");
5,174✔
1148
   id_cache[W_OP_SLA]                 = ident_new("\"sla\"");
5,174✔
1149
   id_cache[W_OP_SRA]                 = ident_new("\"sra\"");
5,174✔
1150
   id_cache[W_OP_ROL]                 = ident_new("\"rol\"");
5,174✔
1151
   id_cache[W_OP_ROR]                 = ident_new("\"ror\"");
5,174✔
1152
   id_cache[W_OP_ADD]                 = ident_new("\"+\"");
5,174✔
1153
   id_cache[W_OP_MINUS]               = ident_new("\"-\"");
5,174✔
1154
   id_cache[W_OP_CONCAT]              = ident_new("\"&\"");
5,174✔
1155
   id_cache[W_OP_TIMES]               = ident_new("\"*\"");
5,174✔
1156
   id_cache[W_OP_DIVIDE]              = ident_new("\"/\"");
5,174✔
1157
   id_cache[W_OP_MOD]                 = ident_new("\"mod\"");
5,174✔
1158
   id_cache[W_OP_REM]                 = ident_new("\"rem\"");
5,174✔
1159
   id_cache[W_OP_EXPONENT]            = ident_new("\"**\"");
5,174✔
1160
   id_cache[W_OP_ABS]                 = ident_new("\"abs\"");
5,174✔
1161
   id_cache[W_OP_NOT]                 = ident_new("\"not\"");
5,174✔
1162
}
5,174✔
1163

1164
bool is_uninstantiated_package(tree_t pack)
20,430✔
1165
{
1166
   return tree_kind(pack) == T_PACKAGE
20,430✔
1167
      && tree_generics(pack) > 0
20,116✔
1168
      && tree_genmaps(pack) == 0;
22,249✔
1169
}
1170

1171
bool is_uninstantiated_subprogram(tree_t decl)
98,918✔
1172
{
1173
   switch (tree_kind(decl)) {
98,918✔
1174
   case T_FUNC_DECL:
98,386✔
1175
   case T_FUNC_BODY:
1176
   case T_PROC_DECL:
1177
   case T_PROC_BODY:
1178
      return tree_generics(decl) > 0;
98,386✔
1179
   default:
1180
      return false;
1181
   }
1182
}
1183

1184
bool is_anonymous_subtype(type_t type)
184,851✔
1185
{
1186
   return type_kind(type) == T_SUBTYPE && !type_has_ident(type);
184,851✔
1187
}
1188

1189
bool unit_needs_cgen(tree_t unit)
198✔
1190
{
1191
   switch (tree_kind(unit)) {
198✔
1192
   case T_PACK_INST:
1193
      return true;
1194
   case T_PACK_BODY:
×
1195
      {
1196
         tree_t pack = tree_primary(unit);
×
1197
         return package_needs_body(pack) && !is_uninstantiated_package(pack);
×
1198
      }
1199
   case T_PACKAGE:
12✔
1200
      return !package_needs_body(unit) && !is_uninstantiated_package(unit);
24✔
1201
   default:
×
1202
      return false;
×
1203
   }
1204
}
1205

1206
bool package_needs_body(tree_t pack)
1,923✔
1207
{
1208
   assert(tree_kind(pack) == T_PACKAGE);
1,923✔
1209

1210
   const int ndecls = tree_decls(pack);
1,923✔
1211
   for (int i = 0; i < ndecls; i++) {
86,485✔
1212
      tree_t d = tree_decl(pack, i);
85,982✔
1213
      const tree_kind_t dkind = tree_kind(d);
85,982✔
1214
      if ((dkind == T_FUNC_DECL || dkind == T_PROC_DECL)
85,982✔
1215
          && !(tree_flags(d) & TREE_F_PREDEFINED))
75,303✔
1216
         return true;
1217
      else if (dkind == T_CONST_DECL && !tree_has_value(d))
84,718✔
1218
         return true;
1219
      else if (dkind == T_PROT_DECL)
84,653✔
1220
         return true;
1221
   }
1222

1223
   return false;
1224
}
1225

1226
static tree_t cached_unit(tree_t hint, tree_t *cache, well_known_t lib_name,
13,886✔
1227
                          well_known_t unit_name)
1228
{
1229
   const vhdl_standard_t curr = standard();
13,886✔
1230

1231
   if (cache[curr] == NULL) {
13,886✔
1232
      if (hint != NULL)
4,348✔
1233
         cache[curr] = hint;
1,396✔
1234
      else {
1235
         lib_t std = lib_require(well_known(lib_name));
2,952✔
1236
         cache[curr] = lib_get(std, well_known(unit_name));
2,952✔
1237
         assert(cache[curr] != NULL);
2,952✔
1238
      }
1239
   }
1240

1241
   assert(hint == NULL || hint == cache[curr]);
13,886✔
1242
   return cache[curr];
13,886✔
1243
}
1244

1245
static tree_t cached_std(tree_t hint)
13,484✔
1246
{
1247
   static tree_t standard_cache[STD_19 + 1] = {};
13,484✔
1248
   return cached_unit(hint, standard_cache, W_STD, W_STD_STANDARD);
13,484✔
1249
}
1250

1251
static tree_t search_type_decls(tree_t container, ident_t name)
13,782✔
1252
{
1253
   const int ndecls = tree_decls(container);
13,782✔
1254

1255
   for (int i = 0; i < ndecls; i++) {
890,236✔
1256
      tree_t d = tree_decl(container, i);
890,236✔
1257
      if (is_type_decl(d) && tree_ident(d) == name)
890,236✔
1258
         return d;
13,782✔
1259
   }
1260

1261
   return NULL;
1262
}
1263

1264
type_t std_type(tree_t std, std_type_t which)
940,341✔
1265
{
1266
   static type_t cache[STD_FILE_OPEN_STATE + 1] = {};
940,341✔
1267
   assert(which < ARRAY_LEN(cache));
940,341✔
1268

1269
   if (cache[which] == NULL) {
940,341✔
1270
      const char *names[] = {
13,484✔
1271
         "universal_integer",
1272
         "universal_real",
1273
         "INTEGER",
1274
         "REAL",
1275
         "BOOLEAN",
1276
         "STRING",
1277
         "TIME",
1278
         "BIT",
1279
         "FILE_OPEN_KIND",
1280
         "FILE_OPEN_STATUS",
1281
         "NATURAL",
1282
         "BIT_VECTOR",
1283
         "SEVERITY_LEVEL",
1284
         "FILE_ORIGIN_KIND",
1285
         "FILE_OPEN_STATE",
1286
      };
1287

1288
      tree_t d = search_type_decls(cached_std(std), ident_new(names[which]));
13,484✔
1289
      if (d == NULL)
13,484✔
1290
         fatal_trace("cannot find standard type %s", names[which]);
1291

1292
      // Do not cache standard types while bootstrapping as the GC will
1293
      // move the objects after parsing
1294
      static int can_cache = -1;
13,484✔
1295
      if (can_cache == -1) can_cache = !opt_get_int(OPT_BOOTSTRAP);
13,484✔
1296

1297
      if (can_cache)
13,484✔
1298
         return (cache[which] = tree_type(d));
13,294✔
1299
      else
1300
         return tree_type(d);
190✔
1301
   }
1302
   else
1303
      return cache[which];
1304
}
1305

1306
type_t ieee_type(ieee_type_t which)
1,260✔
1307
{
1308
   static type_t cache[IEEE_STD_LOGIC + 1] = {};
1,260✔
1309
   assert(which < ARRAY_LEN(cache));
1,260✔
1310

1311
   if (cache[which] == NULL) {
1,260✔
1312
      const char *names[] = {
115✔
1313
         "STD_ULOGIC",
1314
         "STD_LOGIC",
1315
      };
1316

1317
      static tree_t ieee_cache[STD_19 + 1] = {};
115✔
1318
      tree_t unit = cached_unit(NULL, ieee_cache, W_IEEE, W_IEEE_1164);
115✔
1319

1320
      tree_t d = search_type_decls(unit, ident_new(names[which]));
115✔
1321
      if (d == NULL)
115✔
1322
         fatal_trace("cannot find IEEE type %s", names[which]);
1323

1324
      // STD.STANDARD cannot depend on IEEE
1325
      assert(!opt_get_int(OPT_BOOTSTRAP));
115✔
1326

1327
      return (cache[which] = tree_type(d));
115✔
1328
   }
1329
   else
1330
      return cache[which];
1331
}
1332

1333
static tree_t cached_verilog(void)
255✔
1334
{
1335
   static tree_t verilog_cache[STD_19 + 1] = {};
255✔
1336
   return cached_unit(NULL, verilog_cache, W_NVC, W_NVC_VERILOG);
255✔
1337
}
1338

1339
type_t verilog_type(verilog_type_t which)
417✔
1340
{
1341
   static type_t cache[VERILOG_WIRE_ARRAY + 1] = {};
417✔
1342
   assert(which < ARRAY_LEN(cache));
417✔
1343

1344
   if (cache[which] == NULL) {
417✔
1345
      const char *names[] = {
151✔
1346
         [VERILOG_LOGIC] = "T_LOGIC",
1347
         [VERILOG_LOGIC_ARRAY] = "T_LOGIC_ARRAY",
1348
         [VERILOG_INT64] = "T_INT64",
1349
         [VERILOG_NET_VALUE] = "T_NET_VALUE",
1350
         [VERILOG_NET_ARRAY] = "T_NET_ARRAY",
1351
         [VERILOG_WIRE] = "T_WIRE",
1352
         [VERILOG_WIRE_ARRAY] = "T_WIRE_ARRAY",
1353
      };
1354

1355
      tree_t d = search_type_decls(cached_verilog(), ident_new(names[which]));
151✔
1356
      if (d == NULL)
151✔
1357
         fatal_trace("cannot find NVC.VERILOG type %s", names[which]);
1358

1359
      // STD.STANDARD cannot depend on NVC.VERILOG
1360
      assert(!opt_get_int(OPT_BOOTSTRAP));
151✔
1361

1362
      return (cache[which] = tree_type(d));
151✔
1363
   }
1364
   else
1365
      return cache[which];
1366
}
1367

1368
type_t reflection_type(reflect_type_t which)
189✔
1369
{
1370
   static type_t cache[REFLECT_SUBTYPE_MIRROR + 1] = {};
189✔
1371
   assert(which < ARRAY_LEN(cache));
189✔
1372

1373
   if (cache[which] == NULL) {
189✔
1374
      const char *names[] = {
32✔
1375
         "VALUE_MIRROR",
1376
         "SUBTYPE_MIRROR",
1377
      };
1378

1379
      static tree_t reflect_cache[STD_19 + 1] = {};
32✔
1380
      tree_t unit = cached_unit(NULL, reflect_cache, W_STD, W_STD_REFLECTION);
32✔
1381

1382
      tree_t d = search_type_decls(unit, ident_new(names[which]));
32✔
1383
      if (d == NULL)
32✔
1384
         fatal_trace("cannot find REFLECTION type %s", names[which]);
1385

1386
      // STD.STANDARD cannot depend on REFLECTION
1387
      assert(!opt_get_int(OPT_BOOTSTRAP));
32✔
1388

1389
      return (cache[which] = tree_type(d));
32✔
1390
   }
1391
   else
1392
      return cache[which];
1393
}
1394

1395
bool is_open_coded_builtin(subprogram_kind_t kind)
434,281✔
1396
{
1397
   switch (kind) {
434,281✔
1398
   case S_ADD:
1399
   case S_SUB:
1400
   case S_DIV:
1401
   case S_MUL:
1402
   case S_MUL_PR:
1403
   case S_MUL_RP:
1404
   case S_MUL_PI:
1405
   case S_MUL_IP:
1406
   case S_DIV_PR:
1407
   case S_DIV_PP:
1408
   case S_DIV_PI:
1409
   case S_IDENTITY:
1410
   case S_NEGATE:
1411
   case S_SCALAR_LT:
1412
   case S_SCALAR_LE:
1413
   case S_SCALAR_GT:
1414
   case S_SCALAR_GE:
1415
   case S_SCALAR_EQ:
1416
   case S_SCALAR_NEQ:
1417
   case S_ABS:
1418
   case S_MOD:
1419
   case S_REM:
1420
   case S_EXP:
1421
   case S_MUL_RI:
1422
   case S_MUL_IR:
1423
   case S_DIV_RI:
1424
   case S_CONCAT:
1425
   case S_SCALAR_AND:
1426
   case S_SCALAR_OR:
1427
   case S_SCALAR_NOT:
1428
   case S_SCALAR_NAND:
1429
   case S_SCALAR_NOR:
1430
   case S_SCALAR_XOR:
1431
   case S_SCALAR_XNOR:
1432
   case S_FILE_OPEN1:
1433
   case S_FILE_OPEN2:
1434
   case S_FILE_READ:
1435
   case S_FILE_WRITE:
1436
   case S_DEALLOCATE:
1437
      return true;
1438
   default:
182,196✔
1439
      return false;
182,196✔
1440
   }
1441
}
1442

1443
tree_t std_func(ident_t mangled)
×
1444
{
1445
   tree_t std = cached_std(NULL);
×
1446

1447
   const int ndecls = tree_decls(std);
×
1448
   for (int i = 0; i < ndecls; i++) {
×
1449
      tree_t d = tree_decl(std, i);
×
1450
      if (is_subprogram(d) && tree_has_ident2(d) && tree_ident2(d) == mangled)
×
1451
         return d;
×
1452
   }
1453

1454
   return NULL;
1455
}
1456

1457
tree_t verilog_func(ident_t mangled)
104✔
1458
{
1459
   tree_t pack = cached_verilog();
104✔
1460

1461
   const int ndecls = tree_decls(pack);
104✔
1462
   for (int i = 0; i < ndecls; i++) {
9,730✔
1463
      tree_t d = tree_decl(pack, i);
9,730✔
1464
      if (is_subprogram(d) && tree_ident2(d) == mangled)
9,730✔
1465
         return d;
104✔
1466
   }
1467

1468
   fatal_trace("missing Verilog helper function %s", istr(mangled));
1469
}
1470

1471
tree_t name_to_ref(tree_t name)
96,673✔
1472
{
1473
   tree_kind_t kind;
96,673✔
1474
   while ((kind = tree_kind(name)) != T_REF) {
110,136✔
1475
      switch (kind) {
15,137✔
1476
      case T_ARRAY_REF:
13,463✔
1477
      case T_ARRAY_SLICE:
1478
      case T_RECORD_REF:
1479
      case T_ALL:
1480
         name = tree_value(name);
13,463✔
1481
         break;
13,463✔
1482
      default:
1483
         return NULL;
1484
      }
1485
   }
1486

1487
   return name;
1488
}
1489

1490
const char *port_mode_str(port_mode_t mode)
44✔
1491
{
1492
   const char *mode_str[] = {
44✔
1493
      "INVALID", "IN", "OUT", "INOUT", "BUFFER", "LINKAGE", "VIEW", "VIEW"
1494
   };
1495
   assert(mode < ARRAY_LEN(mode_str));
44✔
1496
   return mode_str[mode];
44✔
1497
}
1498

1499
void mangle_one_type(text_buf_t *buf, type_t type)
171,387✔
1500
{
1501
   ident_t ident = type_ident(type);
171,387✔
1502

1503
   char code = 0;
171,387✔
1504
   switch (is_well_known(ident)) {
171,387✔
1505
   case W_STD_INTEGER:        code = 'I'; break;
1506
   case W_STD_STRING:         code = 'S'; break;
3,443✔
1507
   case W_STD_REAL:           code = 'R'; break;
3,555✔
1508
   case W_STD_BOOL:           code = 'B'; break;
23,033✔
1509
   case W_STD_CHAR:           code = 'C'; break;
625✔
1510
   case W_STD_TIME:           code = 'T'; break;
916✔
1511
   case W_STD_NATURAL:        code = 'N'; break;
4,231✔
1512
   case W_STD_POSITIVE:       code = 'P'; break;
365✔
1513
   case W_STD_BIT:            code = 'J'; break;
2,625✔
1514
   case W_STD_BIT_VECTOR:     code = 'Q'; break;
2,693✔
1515
   case W_IEEE_LOGIC:         code = 'L'; break;
292✔
1516
   case W_IEEE_ULOGIC:        code = 'U'; break;
4,673✔
1517
   case W_IEEE_LOGIC_VECTOR:  code = 'V'; break;
1,658✔
1518
   case W_IEEE_ULOGIC_VECTOR: code = 'Y'; break;
1,397✔
1519
   default: break;
1520
   }
1521

1522
   if (code)
49,506✔
1523
      tb_append(buf, code);
62,117✔
1524
   else {
1525
      tb_printf(buf, "%zu", ident_len(ident));
109,270✔
1526
      tb_istr(buf, ident);
109,270✔
1527
   }
1528
}
171,387✔
1529

1530
ident_t get_call_context(ident_t mangled)
22,722✔
1531
{
1532
   const char *str = istr(mangled), *p = str, *end = NULL;
22,722✔
1533
   for (; *p; p++) {
615,078✔
1534
      if (*p == '(') break;
587,286✔
1535
      if (*p == '.') end = p;
569,634✔
1536
   }
1537
   assert(end != NULL);
22,722✔
1538

1539
   return ident_new_n(str, end - str);
22,722✔
1540
}
1541

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

1562
unsigned get_case_choice_char(tree_t value, int depth)
8,285✔
1563
{
1564
   switch (tree_kind(value)) {
9,016✔
1565
   case T_STRING:
8,071✔
1566
      if (depth < tree_chars(value))
8,071✔
1567
         return assume_int(tree_char(value, depth));
8,070✔
1568
      else
1569
         return ~0;   // Out of bounds
1570

1571
   case T_AGGREGATE:
110✔
1572
      {
1573
         const int nassocs = tree_assocs(value);
110✔
1574
         type_t type = tree_type(value);
110✔
1575

1576
         for (int i = 0, pos = 0; i < nassocs; i++) {
168✔
1577
            tree_t a = tree_assoc(value, i);
167✔
1578
            switch (tree_subkind(a)) {
167✔
1579
            case A_NAMED:
×
1580
               if (rebase_index(type, 0, assume_int(tree_name(a))) == depth)
×
1581
                  return assume_int(tree_value(a));
×
1582
               break;
1583

1584
            case A_POS:
23✔
1585
               if (pos++ == (unsigned)depth)
23✔
1586
                  return assume_int(tree_value(a));
13✔
1587
               break;
1588

1589
            case A_CONCAT:
72✔
1590
               {
1591
                  tree_t left = tree_value(a);
72✔
1592

1593
                  type_t left_type = tree_type(left);
72✔
1594
                  if (type_is_unconstrained(left_type))
72✔
UNCOV
1595
                     fatal_at(tree_loc(left), "sorry, this expression is not "
×
1596
                              "currently supported in a case choice");
1597

1598
                  tree_t lr = range_of(tree_type(left), 0);
72✔
1599
                  int64_t left_len;
72✔
1600
                  if (!folded_length(lr, &left_len))
72✔
UNCOV
1601
                     fatal_at(tree_loc(left), "cannot determine length of "
×
1602
                              "aggregate element");
1603

1604
                  if (depth < pos + left_len)
72✔
1605
                     return get_case_choice_char(left, depth - pos);
48✔
1606

1607
                  pos += left_len;
24✔
1608
               }
1609
               break;
24✔
1610

UNCOV
1611
            case A_OTHERS:
×
UNCOV
1612
               return assume_int(tree_value(a));
×
1613

1614
            case A_SLICE:
72✔
1615
               {
1616
                  tree_t base = tree_value(a);
72✔
1617
                  tree_t r = tree_range(a, 0);
72✔
1618

1619
                  const int64_t rleft = assume_int(tree_left(r));
72✔
1620
                  const int64_t rright = assume_int(tree_right(r));
72✔
1621

1622
                  const int64_t loffset = rebase_index(type, 0, rleft);
72✔
1623
                  const int64_t roffset = rebase_index(type, 0, rright);
72✔
1624

1625
                  if (depth >= loffset && depth <= roffset)
72✔
1626
                     return get_case_choice_char(base, depth - loffset);
48✔
1627
               }
1628
            }
1629
         }
1630

1631
         // This will produce an error during bounds checking
1632
         return ~0;
1633
      }
1634

1635
   case T_REF:
491✔
1636
      {
1637
         tree_t decl = tree_ref(value);
491✔
1638
         assert(tree_kind(decl) == T_CONST_DECL || tree_kind(decl) == T_ALIAS);
491✔
1639
         assert(tree_has_value(decl));
491✔
1640
         return get_case_choice_char(tree_value(decl), depth);
491✔
1641
      }
1642

1643
   case T_ARRAY_SLICE:
240✔
1644
      {
1645
         tree_t base = tree_value(value);
240✔
1646
         tree_t r = tree_range(value, 0);
240✔
1647
         const int64_t rleft = assume_int(tree_left(r));
240✔
1648
         const int64_t offset = rebase_index(tree_type(base), 0, rleft);
240✔
1649
         return get_case_choice_char(base, depth + offset);
240✔
1650
      }
1651

1652
   case T_FCALL:
104✔
1653
      if (tree_subkind(tree_ref(value)) == S_CONCAT) {
104✔
1654
         const int nparams = tree_params(value);
104✔
1655
         for (int i = 0; i < nparams; i++) {
156✔
1656
            tree_t left = tree_value(tree_param(value, i));
156✔
1657

1658
            type_t left_type = tree_type(left);
156✔
1659
            if (type_is_unconstrained(left_type))
156✔
UNCOV
1660
               fatal_at(tree_loc(left), "sorry, this expression is not "
×
1661
                        "currently supported in a case choice");
1662

1663
            tree_t lr = range_of(tree_type(left), 0);
156✔
1664
            int64_t left_len;
156✔
1665
            if (!folded_length(lr, &left_len))
156✔
UNCOV
1666
               fatal_at(tree_loc(left), "cannot determine length of left hand "
×
1667
                        "side of concatenation");
1668

1669
            if (depth < left_len || i + 1 == nparams)
156✔
1670
               return get_case_choice_char(left, depth);
104✔
1671

1672
            depth -= left_len;
52✔
1673
         }
1674
      }
1675
      // Fall-through
1676

1677
   default:
UNCOV
1678
      fatal_at(tree_loc(value), "unsupported tree type %s in case choice",
×
1679
               tree_kind_str(tree_kind(value)));
1680
   }
1681
}
1682

1683
int64_t encode_case_choice(tree_t value, int length, int bits)
1,116✔
1684
{
1685
   uint64_t enc = 0;
1,116✔
1686
   for (int i = 0; i < length; i++) {
9,179✔
1687
      if (bits > 0) {
8,063✔
1688
         enc <<= bits;
1,685✔
1689
         enc |= get_case_choice_char(value, i);
1,685✔
1690
      }
1691
      else {
1692
         enc *= 0x27d4eb2d;
6,378✔
1693
         enc += get_case_choice_char(value, i);
6,378✔
1694
      }
1695
   }
1696

1697
   return enc;
1,116✔
1698
}
1699

1700
void to_string(text_buf_t *tb, type_t type, int64_t value)
578✔
1701
{
1702
   if (type_is_integer(type))
578✔
1703
      tb_printf(tb, "%"PRIi64, value);
444✔
1704
   else if (type_is_enum(type)) {
134✔
1705
      type_t base = type_base_recur(type);
62✔
1706
      if (value < 0 || value >= type_enum_literals(base))
62✔
1707
         tb_printf(tb, "%"PRIi64, value);
3✔
1708
      else
1709
         tb_cat(tb, istr(tree_ident(type_enum_literal(base, value))));
59✔
1710
   }
1711
   else if (type_is_physical(type)) {
72✔
1712
      type_t base = type_base_recur(type);
24✔
1713
      const unsigned nunits = type_units(base);
24✔
1714
      tree_t max_unit = NULL;
24✔
1715
      int64_t max_unit_value = 0;
24✔
1716

1717
      // Find the largest unit that evenly divides the given value
1718
      for (unsigned u = 0; u < nunits; u++) {
216✔
1719
         tree_t unit = type_unit(base, u);
192✔
1720
         const int64_t unit_value = assume_int(tree_value(unit));
192✔
1721
         if ((unit_value > max_unit_value) && (value % unit_value == 0)) {
192✔
1722
            max_unit = unit;
90✔
1723
            max_unit_value = unit_value;
90✔
1724
         }
1725
      }
1726
      assert(max_unit);
24✔
1727

1728
      tb_printf(tb, "%"PRIi64" %s", value / max_unit_value,
24✔
1729
                istr(tree_ident(max_unit)));
1730
   }
1731
   else if (type_is_real(type)) {
48✔
1732
      union { int64_t i; double r; } u = { .i = value };
42✔
1733
      tb_printf(tb, "%.17g", u.r);
42✔
1734
   }
1735
   else if (type_is_access(type)) {
6✔
1736
      if (value == 0)
6✔
1737
         tb_cat(tb, "NULL");
3✔
1738
      else
1739
         tb_printf(tb, "%p", (void *)value);
3✔
1740
   }
1741
}
578✔
1742

1743
static bool is_static(tree_t expr)
5,904✔
1744
{
1745
   switch (tree_kind(expr)) {
6,008✔
1746
   case T_REF:
688✔
1747
      {
1748
         tree_t decl = tree_ref(expr);
688✔
1749
         switch (tree_kind(decl)) {
688✔
1750
         case T_CONST_DECL:
179✔
1751
            return !!(tree_flags(decl) & TREE_F_GLOBALLY_STATIC);
179✔
1752
         case T_UNIT_DECL:
1753
         case T_ENUM_LIT:
1754
         case T_GENERIC_DECL:
1755
            return true;
UNCOV
1756
         case T_ALIAS:
×
UNCOV
1757
            return is_static(tree_value(decl));
×
1758
         default:
191✔
1759
            return false;
191✔
1760
         }
1761
      }
1762

1763
   case T_LITERAL:
1764
   case T_STRING:
1765
      return true;
1766

1767
   case T_FCALL:
402✔
1768
      return !!(tree_flags(expr) & (TREE_F_LOCALLY_STATIC
402✔
1769
                                    | TREE_F_GLOBALLY_STATIC));
1770

1771
   case T_RECORD_REF:
101✔
1772
      return is_static(tree_value(expr));
101✔
1773

1774
   case T_ARRAY_REF:
60✔
1775
      {
1776
         if (!is_static(tree_value(expr)))
60✔
1777
            return false;
1778

1779
         const int nparams = tree_params(expr);
60✔
1780
         for (int i = 0; i < nparams; i++) {
120✔
1781
            if (!is_static(tree_value(tree_param(expr, i))))
60✔
1782
               return false;
1783
         }
1784

1785
         return true;
1786
      }
1787

1788
   case T_ARRAY_SLICE:
30✔
1789
      {
1790
         if (!is_static(tree_value(expr)))
30✔
1791
            return false;
1792

1793
         assert(tree_ranges(expr) == 1);
30✔
1794

1795
         tree_t r = tree_range(expr, 0);
30✔
1796
         if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
30✔
UNCOV
1797
            return false;
×
1798

1799
         return true;
1800
      }
1801

1802
   case T_ATTR_REF:
9✔
1803
      {
1804
         switch (tree_subkind(expr)) {
9✔
1805
         case ATTR_EVENT:
1806
         case ATTR_ACTIVE:
1807
         case ATTR_LAST_EVENT:
1808
         case ATTR_LAST_ACTIVE:
1809
         case ATTR_LAST_VALUE:
1810
         case ATTR_DRIVING:
1811
         case ATTR_DRIVING_VALUE:
1812
         case ATTR_STABLE:
1813
         case ATTR_QUIET:
1814
            return false;
1815
         case ATTR_POS:
3✔
1816
         case ATTR_VAL:
1817
         case ATTR_LEFTOF:
1818
         case ATTR_RIGHTOF:
1819
         case ATTR_SUCC:
1820
         case ATTR_PRED:
1821
         case ATTR_VALUE:
1822
         case ATTR_IMAGE:
1823
            assert(tree_params(expr) == 1);
3✔
1824
            return is_static(tree_value(tree_param(expr, 0)));
3✔
1825
         case ATTR_LENGTH:
6✔
1826
         case ATTR_LEFT:
1827
         case ATTR_RIGHT:
1828
         case ATTR_LOW:
1829
         case ATTR_HIGH:
1830
            {
1831
               type_t type = tree_type(tree_name(expr));
6✔
1832
               if (type_is_unconstrained(type))
6✔
1833
                  return false;
1834

1835
               int64_t dim = 1;
3✔
1836
               if (tree_params(expr) == 1)
3✔
UNCOV
1837
                  dim = assume_int(tree_value(tree_param(expr, 0)));
×
1838

1839
               tree_t r = range_of(type, dim - 1);
3✔
1840
               if (tree_subkind(r) == RANGE_EXPR)
3✔
1841
                  return false;
1842

1843
               return is_static(tree_left(r)) && is_static(tree_right(r));
3✔
1844
            }
UNCOV
1845
         default:
×
UNCOV
1846
            return true;
×
1847
         }
1848
      }
1849

UNCOV
1850
   default:
×
UNCOV
1851
      return false;
×
1852
   }
1853
}
1854

1855
tree_t longest_static_prefix(tree_t expr)
22,534✔
1856
{
1857
   switch (tree_kind(expr)) {
22,534✔
1858
   case T_ARRAY_REF:
4,033✔
1859
      {
1860
         tree_t value = tree_value(expr);
4,033✔
1861
         tree_t prefix = longest_static_prefix(value);
4,033✔
1862

1863
         if (prefix != value)
4,033✔
1864
            return prefix;
1865

1866
         const int nparams = tree_params(expr);
4,005✔
1867
         for (int i = 0; i < nparams; i++) {
8,194✔
1868
            if (!is_static(tree_value(tree_param(expr, i))))
4,431✔
1869
               return prefix;
1870
         }
1871

1872
         return expr;
1873
      }
1874

1875
   case T_ARRAY_SLICE:
648✔
1876
      {
1877
         tree_t value = tree_value(expr);
648✔
1878
         tree_t prefix = longest_static_prefix(value);
648✔
1879

1880
         if (prefix != value)
648✔
1881
            return prefix;
1882

1883
         assert(tree_ranges(expr) == 1);
641✔
1884

1885
         tree_t r = tree_range(expr, 0);
641✔
1886
         if (tree_subkind(r) == RANGE_EXPR)
641✔
1887
            return prefix;
1888
         else if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
635✔
1889
            return prefix;
16✔
1890

1891
         return expr;
1892
      }
1893

1894
   case T_RECORD_REF:
1,107✔
1895
      {
1896
         tree_t value = tree_value(expr);
1,107✔
1897
         tree_t prefix = longest_static_prefix(value);
1,107✔
1898

1899
         if (prefix != value)
1,107✔
1900
            return prefix;
21✔
1901

1902
         return expr;
1903
      }
1904

1905
   default:
1906
      return expr;
1907
   }
1908
}
1909

1910
tree_t body_of(tree_t pack)
1,641✔
1911
{
1912
   const tree_kind_t kind = tree_kind(pack);
1,641✔
1913
   if (kind == T_PACK_INST)
1,641✔
1914
      return NULL;
1915

1916
   assert(tree_kind(pack) == T_PACKAGE);
1,641✔
1917

1918
   ident_t body_i = well_known(W_BODY);
1,641✔
1919
   ident_t body_name = ident_prefix(tree_ident(pack), body_i, '-');
1,641✔
1920
   return lib_get_qualified(body_name);
1,641✔
1921
}
1922

1923
tree_t find_generic_map(tree_t unit, int pos, tree_t g)
587✔
1924
{
1925
   const int ngenmaps = tree_genmaps(unit);
587✔
1926

1927
   if (pos < ngenmaps) {
587✔
1928
      tree_t m = tree_genmap(unit, pos);
449✔
1929
      if (tree_subkind(m) == P_POS && tree_pos(m) == pos)
449✔
1930
         return tree_value(m);
303✔
1931
   }
1932

1933
   for (int j = 0; j < ngenmaps; j++) {
998✔
1934
      tree_t m = tree_genmap(unit, j);
860✔
1935
      switch (tree_subkind(m)) {
860✔
1936
      case P_NAMED:
440✔
1937
         {
1938
            tree_t name = tree_name(m);
440✔
1939
            assert(tree_kind(name) == T_REF);
440✔
1940

1941
            if (tree_has_ref(name) && tree_ref(name) == g)
440✔
1942
               return tree_value(m);
15✔
1943
         }
1944
         break;
1945

1946
      case P_POS:
420✔
1947
         if (tree_pos(m) == pos)
420✔
1948
            return tree_value(m);
131✔
1949
         break;
1950

1951
      default:
1952
         break;
1953
      }
1954
   }
1955

1956
   return NULL;
1957
}
1958

1959
bool relaxed_rules(void)
542,501✔
1960
{
1961
   return opt_get_int(OPT_RELAXED);
542,501✔
1962
}
1963

1964
bool is_type_attribute(attr_kind_t kind)
68,977✔
1965
{
1966
   switch (kind) {
68,977✔
1967
   case ATTR_SUBTYPE:
1968
   case ATTR_BASE:
1969
   case ATTR_ELEMENT:
1970
   case ATTR_DESIGNATED_SUBTYPE:
1971
   case ATTR_INDEX:
1972
      return true;
1973
   default:
68,330✔
1974
      return false;
68,330✔
1975
   }
1976
}
1977

1978
bool attribute_has_param(attr_kind_t attr)
22,955✔
1979
{
1980
   switch (attr) {
22,955✔
1981
   case ATTR_IMAGE:
1982
   case ATTR_SUCC:
1983
   case ATTR_PRED:
1984
   case ATTR_DELAYED:
1985
   case ATTR_LEFTOF:
1986
   case ATTR_RIGHTOF:
1987
   case ATTR_VALUE:
1988
   case ATTR_POS:
1989
   case ATTR_LOW:
1990
   case ATTR_HIGH:
1991
   case ATTR_LEFT:
1992
   case ATTR_RIGHT:
1993
   case ATTR_LENGTH:
1994
   case ATTR_RANGE:
1995
   case ATTR_REVERSE_RANGE:
1996
   case ATTR_VAL:
1997
   case ATTR_QUIET:
1998
   case ATTR_STABLE:
1999
   case ATTR_INDEX:
2000
   case ATTR_ASCENDING:
2001
      return true;
2002
   default:
2,176✔
2003
      return false;
2,176✔
2004
   }
2005
}
2006

2007
type_t get_type_or_null(tree_t t)
2,151,893✔
2008
{
2009
   switch (tree_kind(t)) {
2,151,893✔
2010
   case T_LIBRARY:
2011
   case T_ATTR_SPEC:
2012
   case T_PACKAGE:
2013
   case T_PACK_INST:
2014
   case T_PACK_BODY:
2015
   case T_ENTITY:
2016
   case T_ARCH:
2017
   case T_PROCESS:
2018
   case T_COMPONENT:
2019
   case T_INSTANCE:
2020
   case T_CONCURRENT:
2021
   case T_BLOCK:
2022
   case T_WHILE:
2023
   case T_FOR:
2024
   case T_LOOP:
2025
   case T_GROUP_TEMPLATE:
2026
   case T_CONFIGURATION:
2027
   case T_GROUP:
2028
   case T_FOR_GENERATE:
2029
   case T_IF_GENERATE:
2030
   case T_CASE_GENERATE:
2031
   case T_USE:
2032
   case T_CONTEXT:
2033
   case T_PSL_DECL:
2034
   case T_PSL_DIRECT:
2035
   case T_WAVEFORM:
2036
      return NULL;
2037
   default:
2,063,436✔
2038
      if (tree_has_type(t))
2,063,436✔
2039
         return tree_type(t);
2,062,068✔
2040
      else
2041
         return NULL;
2042
   }
2043
}
2044

2045
type_t subtype_for_string(tree_t str, type_t base)
25,627✔
2046
{
2047
   if (type_const_bounds(base))
25,627✔
2048
      return base;    // Can be checked statically
2049
   else if (!type_is_unconstrained(base))
22,502✔
2050
      base = type_base_recur(base);
149✔
2051

2052
   // Construct a new constrained array subtype: the direction and
2053
   // bounds are the same as those for a positional array aggregate
2054
   type_t sub = type_new(T_SUBTYPE);
22,502✔
2055
   type_set_base(sub, base);
22,502✔
2056

2057
   type_t index_type = index_type_of(base, 0);
22,502✔
2058
   const bool is_enum = type_is_enum(index_type);
22,502✔
2059

2060
   // The direction is determined by the index type
2061
   range_kind_t dir = direction_of(index_type, 0);
22,502✔
2062
   tree_t index_r = range_of(index_type, 0);
22,502✔
2063

2064
   // The left bound is the left of the index type and the right bound
2065
   // is determined by the number of elements
2066

2067
   tree_t left = NULL, right = NULL;
22,502✔
2068
   const int nchars = tree_chars(str);
22,502✔
2069

2070
   if (is_enum) {
22,502✔
2071
      const int nlits = type_enum_literals(type_base_recur(index_type));
14✔
2072
      int64_t index_left = assume_int(tree_left(index_r));
14✔
2073

2074
      int64_t iright, ileft;
14✔
2075
      if (nchars == 0) {
14✔
2076
         iright = index_left;
1✔
2077
         ileft = assume_int(tree_right(index_r));
1✔
2078
      }
2079
      else if (dir == RANGE_DOWNTO) {
13✔
UNCOV
2080
         ileft = index_left;
×
UNCOV
2081
         iright = MIN(nlits - 1, MAX(0, index_left - nchars + 1));
×
2082
      }
2083
      else {
2084
         ileft = index_left;
13✔
2085
         iright = MIN(nlits - 1, MAX(0, index_left + nchars - 1));
13✔
2086
      }
2087

2088
      left = get_enum_lit(str, index_type, ileft);
14✔
2089
      right = get_enum_lit(str, index_type, iright);
14✔
2090
   }
2091
   else {
2092
      left = tree_left(index_r);
22,488✔
2093

2094
      int64_t iright;
22,488✔
2095
      if (dir == RANGE_DOWNTO)
22,488✔
UNCOV
2096
         iright = assume_int(left) - nchars + 1;
×
2097
      else
2098
         iright = assume_int(left) + nchars - 1;
22,488✔
2099

2100
      right = get_int_lit(str, index_type, iright);
22,488✔
2101
   }
2102

2103
   tree_t r = tree_new(T_RANGE);
22,502✔
2104
   tree_set_subkind(r, dir);
22,502✔
2105
   tree_set_left(r, left);
22,502✔
2106
   tree_set_right(r, right);
22,502✔
2107
   tree_set_loc(r, tree_loc(str));
22,502✔
2108
   tree_set_type(r, index_type);
22,502✔
2109

2110
   tree_t c = tree_new(T_CONSTRAINT);
22,502✔
2111
   tree_set_subkind(c, C_INDEX);
22,502✔
2112
   tree_add_range(c, r);
22,502✔
2113
   tree_set_loc(c, tree_loc(str));
22,502✔
2114

2115
   type_set_constraint(sub, c);
22,502✔
2116

2117
   return sub;
22,502✔
2118
}
2119

2120
tree_t change_ref(tree_t name, tree_t new)
2,148✔
2121
{
2122
   switch (tree_kind(name)) {
2,148✔
2123
   case T_REF:
1,506✔
2124
      return make_ref(new);
1,506✔
2125

2126
   case T_ARRAY_REF:
108✔
2127
      {
2128
         tree_t t = tree_new(T_ARRAY_REF);
108✔
2129
         tree_set_loc(t, tree_loc(name));
108✔
2130
         tree_set_value(t, change_ref(tree_value(name), new));
108✔
2131
         tree_set_type(t, tree_type(name));
108✔
2132

2133
         const int nparams = tree_params(name);
108✔
2134
         for (int i = 0; i < nparams; i++)
216✔
2135
            tree_add_param(t, tree_param(name, i));
108✔
2136

2137
         return t;
2138
      }
2139

2140
   case T_ARRAY_SLICE:
46✔
2141
      {
2142
         tree_t t = tree_new(T_ARRAY_SLICE);
46✔
2143
         tree_set_loc(t, tree_loc(name));
46✔
2144
         tree_set_value(t, change_ref(tree_value(name), new));
46✔
2145
         tree_set_type(t, tree_type(name));
46✔
2146
         tree_add_range(t, tree_range(name, 0));
46✔
2147

2148
         return t;
46✔
2149
      }
2150

2151
   case T_RECORD_REF:
380✔
2152
      {
2153
         tree_t t = tree_new(T_RECORD_REF);
380✔
2154
         tree_set_loc(t, tree_loc(name));
380✔
2155
         tree_set_value(t, change_ref(tree_value(name), new));
380✔
2156
         tree_set_type(t, tree_type(name));
380✔
2157
         tree_set_ident(t, tree_ident(name));
380✔
2158
         tree_set_ref(t, tree_ref(name));
380✔
2159

2160
         return t;
380✔
2161
      }
2162

2163
   case T_CONV_FUNC:
99✔
2164
      {
2165
         tree_t t = tree_new(T_CONV_FUNC);
99✔
2166
         tree_set_loc(t, tree_loc(name));
99✔
2167
         tree_set_value(t, change_ref(tree_value(name), new));
99✔
2168
         tree_set_ident(t, tree_ident(name));
99✔
2169
         tree_set_type(t, tree_type(name));
99✔
2170
         tree_set_ref(t, tree_ref(name));
99✔
2171

2172
         return t;
99✔
2173
      }
2174

2175
   case T_TYPE_CONV:
9✔
2176
      {
2177
         tree_t t = tree_new(T_TYPE_CONV);
9✔
2178
         tree_set_loc(t, tree_loc(name));
9✔
2179
         tree_set_type(t, tree_type(name));
9✔
2180
         tree_set_value(t, change_ref(tree_value(name), new));
9✔
2181

2182
         return t;
9✔
2183
      }
2184

UNCOV
2185
   default:
×
2186
      fatal_trace("cannot handle tree kind %s in elab_change_ref",
2187
                  tree_kind_str(tree_kind(name)));
2188
   }
2189
}
2190

2191
static void build_wait_for_target(tree_t expr, build_wait_fn_t fn, void *ctx)
2,879✔
2192
{
2193
   switch (tree_kind(expr)) {
2,879✔
2194
   case T_ARRAY_SLICE:
77✔
2195
      build_wait(tree_range(expr, 0), fn, ctx);
77✔
2196
      break;
77✔
2197

2198
   case T_ARRAY_REF:
546✔
2199
      {
2200
         const int nparams = tree_params(expr);
546✔
2201
         for (int i = 0; i < nparams; i++)
1,092✔
2202
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
546✔
2203
      }
2204
      break;
2205

2206
   default:
2207
      break;
2208
   }
2209
}
2,879✔
2210

2211
void build_wait(tree_t expr, build_wait_fn_t fn, void *ctx)
13,533✔
2212
{
2213
   // LRM 08 section 10.2 has rules for building a wait statement from a
2214
   // sensitivity list. LRM 08 section 11.3 extends these rules to
2215
   // all-sensitised processes.
2216

2217
   switch (tree_kind(expr)) {
16,767✔
2218
   case T_REF:
4,220✔
2219
      if (class_of(tree_ref(expr)) == C_SIGNAL)
4,220✔
2220
         (*fn)(expr, ctx);
2,453✔
2221
      break;
2222

2223
   case T_EXTERNAL_NAME:
7✔
2224
      if (tree_class(expr) == C_SIGNAL)
7✔
2225
         (*fn)(expr, ctx);
7✔
2226
      break;
2227

2228
   case T_WAVEFORM:
2,807✔
2229
   case T_QUALIFIED:
2230
   case T_TYPE_CONV:
2231
   case T_INERTIAL:
2232
      if (tree_has_value(expr))
2,807✔
2233
         build_wait(tree_value(expr), fn, ctx);
2,798✔
2234
      break;
2235

2236
   case T_ASSERT:
397✔
2237
      build_wait(tree_value(expr), fn, ctx);
397✔
2238
      // Fall-through
2239
   case T_REPORT:
398✔
2240
      if (tree_has_message(expr))
398✔
2241
         build_wait(tree_message(expr), fn, ctx);
271✔
2242
      break;
2243

2244
   case T_ARRAY_REF:
806✔
2245
   case T_ARRAY_SLICE:
2246
   case T_RECORD_REF:
2247
      {
2248
         tree_t ref = name_to_ref(expr);
806✔
2249
         if (ref != NULL && class_of(ref) == C_SIGNAL
806✔
2250
             && longest_static_prefix(expr) == expr)
510✔
2251
            (*fn)(expr, ctx);
433✔
2252
         else {
2253
            build_wait(tree_value(expr), fn, ctx);
373✔
2254
            build_wait_for_target(expr, fn, ctx);
373✔
2255
         }
2256
      }
2257
      break;
2258

2259
   case T_FCALL:
2,160✔
2260
   case T_PCALL:
2261
   case T_PROT_FCALL:
2262
   case T_PROT_PCALL:
2263
      {
2264
         tree_t decl = tree_ref(expr);
2,160✔
2265
         const int nparams = tree_params(expr);
2,160✔
2266
         for (int i = 0; i < nparams; i++) {
5,950✔
2267
            tree_t p = tree_param(expr, i);
3,790✔
2268
            assert(tree_subkind(p) == P_POS);
3,790✔
2269

2270
            switch (tree_subkind(tree_port(decl, tree_pos(p)))) {
3,790✔
2271
            case PORT_IN:
3,783✔
2272
            case PORT_INOUT:
2273
            case PORT_ARRAY_VIEW:
2274
            case PORT_RECORD_VIEW:
2275
               build_wait(tree_value(p), fn, ctx);
3,783✔
2276
               break;
3,783✔
2277
            default:
2278
               break;
2279
            }
2280
         }
2281
      }
2282
      break;
2283

2284
   case T_AGGREGATE:
285✔
2285
      {
2286
         const int nassocs = tree_assocs(expr);
285✔
2287
         for (int i = 0; i < nassocs; i++) {
953✔
2288
            tree_t a = tree_assoc(expr, i);
668✔
2289
            build_wait(tree_value(a), fn, ctx);
668✔
2290

2291
            switch (tree_subkind(a)) {
668✔
2292
            case A_RANGE:
53✔
2293
            case A_SLICE:
2294
               build_wait(tree_range(a, 0), fn, ctx);
53✔
2295
               break;
53✔
2296
            case A_NAMED:
66✔
2297
               build_wait(tree_name(a), fn, ctx);
66✔
2298
               break;
66✔
2299
            }
2300
         }
2301
      }
2302
      break;
2303

2304
   case T_ATTR_REF:
334✔
2305
      {
2306
         const attr_kind_t predef = tree_subkind(expr);
334✔
2307
         if (predef == ATTR_EVENT || predef == ATTR_ACTIVE)
334✔
2308
            build_wait(tree_name(expr), fn, ctx);
151✔
2309

2310
         const int nparams = tree_params(expr);
334✔
2311
         for (int i = 0; i < nparams; i++)
345✔
2312
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
11✔
2313
      }
2314
      break;
2315

2316
   case T_LITERAL:
2317
   case T_STRING:
2318
   case T_DUMMY_DRIVER:
2319
      break;
2320

2321
   case T_IF:
220✔
2322
      {
2323
         const int nconds = tree_conds(expr);
220✔
2324
         for (int i = 0; i < nconds; i++)
593✔
2325
            build_wait(tree_cond(expr, i), fn, ctx);
373✔
2326
      }
2327
      break;
2328

2329
   case T_COND_STMT:
377✔
2330
      {
2331
         if (tree_has_value(expr))
377✔
2332
            build_wait(tree_value(expr), fn, ctx);
248✔
2333

2334
         const int nstmts = tree_stmts(expr);
377✔
2335
         for (int i = 0; i < nstmts; i++)
756✔
2336
            build_wait(tree_stmt(expr, i), fn, ctx);
379✔
2337
      }
2338
      break;
2339

2340
   case T_PROCESS:
50✔
2341
   case T_SEQUENCE:
2342
   case T_PROC_BODY:
2343
      {
2344
         const int ndecls = tree_decls(expr);
50✔
2345
         for (int i = 0; i < ndecls; i++) {
68✔
2346
            tree_t d = tree_decl(expr, i);
18✔
2347
            if (tree_kind(d) == T_PROC_BODY)
18✔
2348
               build_wait(d, fn, ctx);
2✔
2349
         }
2350

2351
         const int nstmts = tree_stmts(expr);
50✔
2352
         for (int i = 0; i < nstmts; i++)
112✔
2353
            build_wait(tree_stmt(expr, i), fn, ctx);
62✔
2354
      }
2355
      break;
2356

2357
   case T_SIGNAL_ASSIGN:
2,490✔
2358
      {
2359
         build_wait_for_target(tree_target(expr), fn, ctx);
2,490✔
2360

2361
         const int nwaves = tree_waveforms(expr);
2,490✔
2362
         for (int i = 0; i < nwaves; i++)
5,143✔
2363
            build_wait(tree_waveform(expr, i), fn, ctx);
2,653✔
2364
      }
2365
      break;
2366

2367
   case T_VAR_ASSIGN:
13✔
2368
   case T_FORCE:
2369
      build_wait_for_target(tree_target(expr), fn, ctx);
13✔
2370
      build_wait(tree_value(expr), fn, ctx);
13✔
2371
      break;
13✔
2372

2373
   case T_RELEASE:
3✔
2374
      build_wait_for_target(tree_target(expr), fn, ctx);
3✔
2375
      break;
3✔
2376

2377
   case T_CASE:
45✔
2378
   case T_MATCH_CASE:
2379
      {
2380
         build_wait(tree_value(expr), fn, ctx);
45✔
2381

2382
         const int nstmts = tree_stmts(expr);
45✔
2383
         for (int i = 0; i < nstmts; i++) {
276✔
2384
            tree_t alt = tree_stmt(expr, i);
231✔
2385

2386
            const int nstmts = tree_stmts(alt);
231✔
2387
            for (int j = 0; j < nstmts; j++)
462✔
2388
               build_wait(tree_stmt(alt, j), fn, ctx);
231✔
2389
         }
2390
      }
2391
      break;
2392

2393
   case T_FOR:
16✔
2394
      {
2395
         build_wait(tree_range(expr, 0), fn, ctx);
16✔
2396

2397
         const int nstmts = tree_stmts(expr);
16✔
2398
         for (int i = 0; i < nstmts; i++)
35✔
2399
            build_wait(tree_stmt(expr, i), fn, ctx);
19✔
2400
      }
2401
      break;
2402

2403
   case T_WHILE:
1✔
2404
      build_wait(tree_value(expr), fn, ctx);
1✔
2405
      // Fall-through
2406
   case T_LOOP:
4✔
2407
      {
2408
         const int nstmts = tree_stmts(expr);
4✔
2409
         for (int i = 0; i < nstmts; i++)
20✔
2410
            build_wait(tree_stmt(expr, i), fn, ctx);
16✔
2411
      }
2412
      break;
2413

2414
   case T_NEXT:
9✔
2415
   case T_EXIT:
2416
      if (tree_has_value(expr))
9✔
2417
         build_wait(tree_value(expr), fn, ctx);
6✔
2418
      break;
2419

2420
   case T_RANGE:
146✔
2421
      if (tree_subkind(expr) == RANGE_EXPR)
146✔
2422
         build_wait(tree_value(expr), fn, ctx);
11✔
2423
      else {
2424
         build_wait(tree_left(expr), fn, ctx);
135✔
2425
         build_wait(tree_right(expr), fn, ctx);
135✔
2426
      }
2427
      break;
2428

UNCOV
2429
   default:
×
2430
      fatal_trace("Cannot handle tree kind %s in wait expression",
2431
                  tree_kind_str(tree_kind(expr)));
2432
   }
2433
}
13,533✔
2434

2435
void print_syntax(const char *fmt, ...)
1,898✔
2436
{
2437
   LOCAL_TEXT_BUF tb = tb_new();
1,898✔
2438
   bool highlighting = false;
1,898✔
2439
   static bool comment = false, last_was_newline = false;
1,898✔
2440
   for (const char *p = fmt; *p != '\0'; p++) {
10,265✔
2441
      if (comment) {
8,367✔
2442
         if (*p == '\n' || *p == '\r') {
3,166✔
2443
            comment = false;
94✔
2444
            last_was_newline = true;
94✔
2445
            tb_printf(tb, "$$\n");
94✔
2446
         }
2447
         else if (*p != '~' && *p != '#') {
3,072✔
2448
            tb_append(tb, *p);
2,912✔
2449
            last_was_newline = false;
2,912✔
2450
         }
2451
         if (p > fmt && *p == '/' && *(p - 1) == '*') {
3,166✔
2452
            tb_printf(tb, "$$");
10✔
2453
            comment = false;
10✔
2454
            last_was_newline = false;
10✔
2455
         }
2456
      }
2457
      else if (*p == '\r') {
5,201✔
2458
         if (!last_was_newline) {
21✔
UNCOV
2459
            tb_append(tb, '\n');
×
UNCOV
2460
            last_was_newline = true;
×
2461
         }
2462
      }
2463
      else if (*p == '#' && *(p + 1) != '#') {
5,180✔
2464
         tb_printf(tb, "$bold$$cyan$");
353✔
2465
         last_was_newline = false;
353✔
2466
         highlighting = true;
353✔
2467
      }
2468
      else if (*p == '~' && *(p + 1) != '~') {
4,827✔
2469
         tb_printf(tb, "$yellow$");
1✔
2470
         last_was_newline = false;
1✔
2471
         highlighting = true;
1✔
2472
      }
2473
      else if ((*p == '-' && *(p + 1) == '-')
4,826✔
2474
               || (*p == '/' && *(p + 1) == '/')
4,736✔
2475
               || (*p == '/' && *(p + 1) == '*')) {
4,732✔
2476
         tb_printf(tb, "$red$%c", *p);
104✔
2477
         last_was_newline = false;
104✔
2478
         comment = true;
104✔
2479
      }
2480
      else if (!isalnum_iso88591(*p) && *p != '_'
4,722✔
2481
               && *p != '%' && highlighting) {
2,396✔
2482
         tb_printf(tb, "$$%c", *p);
307✔
2483
         last_was_newline = false;
307✔
2484
         highlighting = false;
307✔
2485
      }
2486
      else {
2487
         tb_append(tb, *p);
4,415✔
2488
         last_was_newline = (*p == '\n');
4,415✔
2489
      }
2490
   }
2491

2492
   if (highlighting)
1,898✔
2493
      tb_cat(tb, "$$");
47✔
2494

2495
   va_list ap;
1,898✔
2496
   va_start(ap, fmt);
1,898✔
2497

2498
   if (syntax_buf != NULL) {
1,898✔
2499
      char *stripped LOCAL = strip_color(tb_get(tb), ap);
3,796✔
2500
      tb_cat(syntax_buf, stripped);
1,898✔
2501
   }
2502
   else
UNCOV
2503
      color_vprintf(tb_get(tb), ap);
×
2504

2505
   va_end(ap);
1,898✔
2506
}
1,898✔
2507

2508
void capture_syntax(text_buf_t *tb)
9✔
2509
{
2510
   assert(tb == NULL || syntax_buf == NULL);
9✔
2511
   syntax_buf = tb;
9✔
2512
}
9✔
2513

2514
void analyse_file(const char *file, jit_t *jit, unit_registry_t *ur)
3,586✔
2515
{
2516
   input_from_file(file);
3,586✔
2517

2518
   switch (source_kind()) {
3,586✔
2519
   case SOURCE_VHDL:
3,508✔
2520
      {
2521
         lib_t work = lib_work();
3,508✔
2522
         int base_errors = 0;
3,508✔
2523
         tree_t unit;
3,508✔
2524
         while (base_errors = error_count(), (unit = parse())) {
13,585✔
2525
            if (error_count() == base_errors) {
10,077✔
2526
               lib_put(work, unit);
10,077✔
2527
               unit_registry_purge(ur, tree_ident(unit));
10,077✔
2528

2529
               simplify_local(unit, jit, ur);
10,077✔
2530
               bounds_check(unit);
10,077✔
2531
            }
2532
            else
UNCOV
2533
               lib_put_error(work, unit);
×
2534
         }
2535
      }
2536
      break;
2537

2538
   case SOURCE_VERILOG:
78✔
2539
      {
2540
         LOCAL_TEXT_BUF tb = tb_new();
156✔
2541
         vlog_preprocess(tb, true);
78✔
2542

2543
         input_from_buffer(tb_get(tb), tb_len(tb), SOURCE_VERILOG);
78✔
2544

2545
         lib_t work = lib_work();
78✔
2546
         vlog_node_t module;
78✔
2547
         while ((module = vlog_parse())) {
248✔
2548
            if (error_count() == 0) {
92✔
2549
               vlog_check(module);
92✔
2550

2551
               if (error_count() == 0) {
92✔
2552
                  vlog_simp(module);
92✔
2553
                  lib_put_vlog(work, module);
92✔
2554
               }
2555
            }
2556
         }
2557
      }
2558
      break;
78✔
2559

UNCOV
2560
   case SOURCE_SDF:
×
2561
      {
UNCOV
2562
         sdf_file_t *sdf_file = sdf_parse(file, 0);
×
UNCOV
2563
         progress("analysed SDF file: %s", file);
×
2564

UNCOV
2565
         if (sdf_file != NULL) {
×
UNCOV
2566
            warnf("SDF is not yet supported");
×
UNCOV
2567
            sdf_file_free(sdf_file);
×
2568
         }
2569
      }
2570
      break;
2571
   }
2572
}
3,583✔
2573

2574
bool all_character_literals(type_t type)
1,990✔
2575
{
2576
   assert(type_is_enum(type));
1,990✔
2577

2578
   type_t base = type_base_recur(type);
1,990✔
2579
   const int nlits = type_enum_literals(base);
1,990✔
2580
   for (int i = 0; i < nlits; i++) {
8,056✔
2581
      if (ident_char(tree_ident(type_enum_literal(base, i)), 0) != '\'')
6,941✔
2582
         return false;
2583
   }
2584

2585
   return true;
2586
}
2587

2588
bool is_operator_symbol(ident_t ident)
27,724✔
2589
{
2590
   const int len = ident_len(ident);
27,724✔
2591
   if (len < 3)
27,724✔
2592
      return false;
2593
   else if (ident_char(ident, 0) != '"')
27,474✔
2594
      return false;
2595
   else if (ident_char(ident, len - 1) != '"')
16,014✔
2596
      return false;
2597

2598
   const well_known_t wk = is_well_known(ident);
16,014✔
2599

2600
   if (standard() < STD_08)
16,014✔
2601
      return wk >= W_OP_AND && wk <= W_OP_NOT;
3,349✔
2602
   else
2603
      return wk >= W_OP_AND && wk <= W_OP_MATCH_GREATER_EQUAL;
12,665✔
2604
}
2605

2606
bool same_tree(tree_t a, tree_t b)
7,160✔
2607
{
2608
   const tree_kind_t akind = tree_kind(a);
7,160✔
2609
   if (akind != tree_kind(b))
7,160✔
2610
      return false;
2611

2612
   switch (akind) {
7,041✔
2613
   case T_REF:
3,379✔
2614
      return tree_ref(a) == tree_ref(b);
3,379✔
2615
   case T_ARRAY_REF:
1,069✔
2616
      {
2617
         if (!same_tree(tree_value(a), tree_value(b)))
1,069✔
2618
            return false;
2619

2620
         const int nparams = tree_params(a);
1,047✔
2621
         assert(nparams == tree_params(b));
1,047✔
2622

2623
         for (int i = 0; i < nparams; i++) {
1,926✔
2624
            tree_t pa = tree_value(tree_param(a, i));
1,722✔
2625
            tree_t pb = tree_value(tree_param(b, i));
1,722✔
2626
            if (!same_tree(pa, pb))
1,722✔
2627
               return false;
2628
         }
2629

2630
         return true;
2631
      }
2632
   case T_ARRAY_SLICE:
38✔
2633
      {
2634
         if (!same_tree(tree_value(a), tree_value(b)))
38✔
2635
            return false;
2636

2637
         tree_t ra = tree_range(a, 0);
38✔
2638
         tree_t rb = tree_range(b, 0);
38✔
2639

2640
         const range_kind_t rakind = tree_subkind(ra);
38✔
2641
         if (rakind != tree_subkind(rb) || rakind == RANGE_EXPR)
38✔
2642
            return false;
2643

2644
         return same_tree(tree_left(ra), tree_left(rb))
38✔
2645
            && same_tree(tree_right(ra), tree_right(rb));
38✔
2646
      }
2647

2648
   case T_RECORD_REF:
747✔
2649
      return tree_ident(a) == tree_ident(b)
747✔
2650
         && same_tree(tree_value(a), tree_value(b));
750✔
2651

2652
   case T_LITERAL:
1,808✔
2653
      {
2654
         const literal_kind_t alkind = tree_subkind(a);
1,808✔
2655
         if (alkind != tree_subkind(b) || alkind != L_INT)
1,808✔
2656
            return false;
2657
         else
2658
            return tree_ival(a) == tree_ival(b);
1,769✔
2659
      }
2660
   default:
2661
      return false;
2662
   }
2663
}
2664

2665
void instance_name_to_path(text_buf_t *tb, const char *str)
9,511✔
2666
{
2667
   bool delete = false;
9,511✔
2668
   for (const char *p = str; *p; p++) {
629,438✔
2669
      if (*p == '@' || (*p == '(' && !isdigit_iso88591(*(p + 1))))
619,927✔
2670
         delete = true;
2671
      else if (*p == ')' && delete)
588,354✔
2672
         delete = false;
2673
      else if (*p == ':') {
567,845✔
2674
         delete = false;
36,513✔
2675
         tb_append(tb, ':');
36,513✔
2676
      }
2677
      else if (!delete)
531,332✔
2678
         tb_append(tb, *p);
324,749✔
2679
   }
2680
}
9,511✔
2681

2682
bool calculate_aggregate_bounds(tree_t expr, range_kind_t *kind,
2,649✔
2683
                                int64_t *left, int64_t *right)
2684
{
2685
   // Calculate the direction and bounds of an array aggregate using the
2686
   // rules in LRM 93 7.3.2.2
2687

2688
   type_t type = tree_type(expr);
2,649✔
2689
   type_t index_type = index_type_of(type, 0);
2,649✔
2690
   if (index_type == NULL || type_is_none(index_type))
2,649✔
2691
      return false;
1✔
2692

2693
   tree_t index_r = range_of(index_type, 0), base_r = index_r;
2,648✔
2694

2695
   int64_t low, high;
2,648✔
2696
   if (!folded_bounds(index_r, &low, &high))
2,648✔
2697
      return false;
2698

2699
   int64_t clow = INT64_MAX, chigh = INT64_MIN;  // Actual bounds computed below
2,633✔
2700

2701
   range_kind_t dir;
2,633✔
2702
   if (type_is_unconstrained(type))
2,633✔
2703
      dir = tree_subkind(index_r);
2,387✔
2704
   else {
2705
      base_r = range_of(type, 0);
246✔
2706
      dir = tree_subkind(base_r);
246✔
2707
   }
2708

2709
   const int nassocs = tree_assocs(expr);
2,633✔
2710

2711
   if (standard() >= STD_08) {
2,633✔
2712
      // VHDL-2008 range association determines index direction for
2713
      // unconstrained aggregate when the expression type matches the
2714
      // array type
2715
      for (int i = 0; i < nassocs; i++) {
3,362✔
2716
         tree_t a = tree_assoc(expr, i);
2,157✔
2717
         if (tree_subkind(a) == A_SLICE)
2,157✔
2718
            dir = tree_subkind(tree_range(a, 0));
54✔
2719
      }
2720
   }
2721

2722
   if (dir != RANGE_TO && dir != RANGE_DOWNTO)
2,633✔
2723
      return false;
2724

2725
   int64_t pos = 0;
2726
   for (int i = 0; i < nassocs; i++) {
12,078✔
2727
      tree_t a = tree_assoc(expr, i);
10,301✔
2728
      int64_t ilow = 0, ihigh = 0;
10,301✔
2729
      const assoc_kind_t akind = tree_subkind(a);
10,301✔
2730

2731
      switch (akind) {
10,301✔
2732
      case A_NAMED:
544✔
2733
         {
2734
            tree_t name = tree_name(a);
544✔
2735
            if (folded_int(name, &ilow))
544✔
2736
               ihigh = ilow;
534✔
2737
            else
2738
               return false;
819✔
2739
         }
2740
         break;
534✔
2741

2742
      case A_RANGE:
1,184✔
2743
      case A_SLICE:
2744
         {
2745
            tree_t r = tree_range(a, 0);
1,184✔
2746
            const range_kind_t rkind = tree_subkind(r);
1,184✔
2747
            if (rkind == RANGE_TO || rkind == RANGE_DOWNTO) {
1,184✔
2748
               tree_t left = tree_left(r), right = tree_right(r);
842✔
2749

2750
               int64_t ileft, iright;
842✔
2751
               if (folded_int(left, &ileft) && folded_int(right, &iright)) {
842✔
2752
                  ilow = (rkind == RANGE_TO ? ileft : iright);
409✔
2753
                  ihigh = (rkind == RANGE_TO ? iright : ileft);
409✔
2754
               }
2755
               else
2756
                  return false;
433✔
2757
            }
2758
            else
2759
               return false;
2760
         }
2761
         break;
2762

2763
      case A_OTHERS:
2764
         return false;
2765

2766
      case A_POS:
8,494✔
2767
         if (i == 0) {
8,494✔
2768
            int64_t ileft;
1,141✔
2769
            if (folded_int(tree_left(base_r), &ileft))
1,141✔
2770
               ilow = ihigh = ileft;
1,141✔
2771
            else
UNCOV
2772
               return false;
×
2773
         }
2774
         else if (dir == RANGE_TO)
7,353✔
2775
            ilow = ihigh = clow + pos;
7,351✔
2776
         else
2777
            ilow = ihigh = chigh - pos;
2✔
2778
         pos++;
8,494✔
2779
         break;
8,494✔
2780

2781
      case A_CONCAT:
77✔
2782
         {
2783
            type_t value_type = tree_type(tree_value(a));
77✔
2784

2785
            int64_t length;
77✔
2786
            if (type_is_unconstrained(value_type))
77✔
2787
               return false;
32✔
2788
            else if (folded_length(range_of(value_type, 0), &length)) {
52✔
2789
               if (i == 0) {
45✔
2790
                  int64_t ileft;
20✔
2791
                  if (folded_int(tree_left(base_r), &ileft))
20✔
2792
                     ilow = ihigh = ileft;
20✔
2793
                  else
UNCOV
2794
                     return false;
×
2795
               }
2796
               else if (dir == RANGE_TO) {
25✔
2797
                  ilow = clow + pos;
16✔
2798
                  ihigh = ilow + length - 1;
16✔
2799
               }
2800
               else {
2801
                  ihigh = chigh - pos;
9✔
2802
                  ilow = ihigh - length + 1;
9✔
2803
               }
2804
               pos += length;
45✔
2805
            }
2806
            else
2807
               return false;
2808
         }
2809
         break;
2810
      }
2811

2812
      clow = MIN(clow, ilow);
9,482✔
2813
      chigh = MAX(chigh, ihigh);
9,482✔
2814
   }
2815

2816
   if (clow < low || chigh > high)
1,777✔
2817
      return false;   // Will raise a bounds check error later
2818

2819
   *kind = dir;
1,772✔
2820
   *left = dir == RANGE_TO ? clow : chigh;
1,772✔
2821
   *right = dir == RANGE_TO ? chigh : clow;
1,772✔
2822

2823
   return true;
1,772✔
2824
}
2825

2826
type_t calculate_aggregate_subtype(tree_t expr)
2,422✔
2827
{
2828
   range_kind_t dir;
2,422✔
2829
   int64_t ileft, iright;
2,422✔
2830
   if (!calculate_aggregate_bounds(expr, &dir, &ileft, &iright))
2,422✔
2831
      return NULL;
2832

2833
   type_t type = tree_type(expr);
1,754✔
2834

2835
   const int ndims = dimension_of(type);
1,754✔
2836
   type_t a0_type = NULL;
1,754✔
2837
   if (ndims > 1) {
1,754✔
2838
      a0_type = tree_type(tree_value(tree_assoc(expr, 0)));
66✔
2839
      if (type_is_unconstrained(a0_type))
66✔
2840
         return NULL;
2841

2842
      assert(dimension_of(a0_type) == ndims - 1);
66✔
2843
   }
2844

2845
   type_t index_type = index_type_of(type, 0);
1,754✔
2846

2847
   tree_t left = get_discrete_lit(expr, index_type, ileft);
1,754✔
2848
   tree_t right = get_discrete_lit(expr, index_type, iright);
1,754✔
2849
   assert(left != NULL && right != NULL);
1,754✔
2850

2851
   type_t sub = type_new(T_SUBTYPE);
1,754✔
2852
   type_set_base(sub, type_base_recur(type));
1,754✔
2853

2854
   type_t elem = type_elem(type);
1,754✔
2855
   if (type_is_unconstrained(elem)) {
1,754✔
2856
      a0_type = tree_type(tree_value(tree_assoc(expr, 0)));
91✔
2857
      if (!type_is_unconstrained(a0_type))
91✔
2858
         elem = a0_type;
47✔
2859
   }
2860

2861
   type_set_elem(sub, elem);
1,754✔
2862

2863
   tree_t cons = tree_new(T_CONSTRAINT);
1,754✔
2864
   tree_set_subkind(cons, C_INDEX);
1,754✔
2865

2866
   tree_t r = tree_new(T_RANGE);
1,754✔
2867
   tree_set_subkind(r, dir);
1,754✔
2868
   tree_set_type(r, index_type);
1,754✔
2869
   tree_set_left(r, left);
1,754✔
2870
   tree_set_right(r, right);
1,754✔
2871

2872
   tree_add_range(cons, r);
1,754✔
2873

2874
   for (int i = 1; i < ndims; i++)
1,820✔
2875
      tree_add_range(cons, range_of(a0_type, i - 1));
66✔
2876

2877
   type_set_constraint(sub, cons);
1,754✔
2878

2879
   return sub;
1,754✔
2880
}
2881

2882
bool can_be_signal(type_t type)
10,725✔
2883
{
2884
   switch (type_kind(type)) {
21,142✔
2885
   case T_RECORD:
2,453✔
2886
      {
2887
         const int nfields = type_fields(type);
2,453✔
2888
         for (int i = 0; i < nfields; i++) {
10,655✔
2889
            if (!can_be_signal(tree_type(type_field(type, i))))
8,279✔
2890
               return false;
2891
         }
2892

2893
         return true;
2894
      }
2895
   case T_ARRAY:
4,368✔
2896
      return can_be_signal(type_elem(type));
4,368✔
2897
   case T_SUBTYPE:
6,049✔
2898
      return can_be_signal(type_base(type));
6,049✔
2899
   case T_ACCESS:
2900
   case T_FILE:
2901
   case T_PROTECTED:
2902
   case T_INCOMPLETE:
2903
      return false;
2904
   default:
7,697✔
2905
      return true;
7,697✔
2906
   }
2907
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc