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

nickg / nvc / 16709537316

03 Aug 2025 09:18PM UTC coverage: 92.559% (-0.05%) from 92.613%
16709537316

push

github

nickg
Refactor mixed language elaboration

91 of 92 new or added lines in 1 file covered. (98.91%)

42 existing lines in 2 files now uncovered.

71735 of 77502 relevant lines covered (92.56%)

557141.8 hits per line

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

94.86
/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)
749,634✔
46
{
47
   int64_t value;
749,634✔
48
   if (folded_int(t, &value))
749,634✔
49
      return value;
749,634✔
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)
118,161✔
56
{
57
   assert(tree_kind(r) == T_RANGE);
118,161✔
58

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

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

66
bool folded_int(tree_t t, int64_t *l)
6,167,196✔
67
{
68
   switch (tree_kind(t)) {
6,222,559✔
69
   case T_LITERAL:
3,987,507✔
70
      switch (tree_subkind(t)) {
3,987,507✔
71
      case L_PHYSICAL:
22,418✔
72
         if (tree_has_ref(t))
22,418✔
73
            return false;
74
         // Fall-through
75
      case L_INT:
76
         *l = tree_ival(t);
3,891,643✔
77
         return true;
3,891,643✔
78
      default:
79
         return false;
80
      }
81
   case T_QUALIFIED:
434✔
82
      return folded_int(tree_value(t), l);
434✔
83
   case T_REF:
1,944,756✔
84
      if (tree_has_ref(t)) {
1,944,756✔
85
         tree_t decl = tree_ref(t);
1,944,755✔
86
         switch (tree_kind(decl)) {
1,944,755✔
87
         case T_CONST_DECL:
65,336✔
88
            if (tree_has_value(decl))
65,336✔
89
               return folded_int(tree_value(decl), l);
54,475✔
90
            else
91
               return false;
92
         case T_ENUM_LIT:
1,793,220✔
93
            *l = tree_pos(decl);
1,793,220✔
94
            return true;
1,793,220✔
95
         case T_ALIAS:
454✔
96
            return folded_int(tree_value(decl), l);
454✔
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)
333,683✔
108
{
109
   switch (tree_kind(t)) {
333,692✔
110
   case T_LITERAL:
323,689✔
111
      if (tree_subkind(t) == L_REAL) {
323,689✔
112
         *l = tree_dval(t);
323,590✔
113
         return true;
323,590✔
114
      }
115
      else
116
         return false;
117
   case T_QUALIFIED:
9✔
118
      return folded_real(tree_value(t), l);
9✔
119
   default:
120
      return false;
121
   }
122
}
123

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

135
bool folded_bounds(tree_t r, int64_t *low, int64_t *high)
2,531,944✔
136
{
137
   assert(tree_kind(r) == T_RANGE);
2,531,944✔
138

139
   const range_kind_t rkind = tree_subkind(r);
2,531,944✔
140

141
   if (rkind != RANGE_TO && rkind != RANGE_DOWNTO)
2,531,944✔
142
      return false;
143

144
   int64_t left, right;
2,522,228✔
145
   if (!folded_int(tree_left(r), &left))
2,522,228✔
146
      return false;
147
   else if (!folded_int(tree_right(r), &right))
2,354,501✔
148
      return false;
149

150
   switch (rkind) {
2,295,388✔
151
   case RANGE_TO:
2,122,655✔
152
      *low  = left;
2,122,655✔
153
      *high = right;
2,122,655✔
154
      return true;
2,122,655✔
155
   case RANGE_DOWNTO:
172,733✔
156
      *low  = right;
172,733✔
157
      *high = left;
172,733✔
158
      return true;
172,733✔
159
   default:
160
      return false;
161
   }
162
}
163

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

168
   const range_kind_t rkind = tree_subkind(r);
123,159✔
169

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

173
   double left, right;
123,155✔
174
   if (folded_real(tree_left(r), &left) && folded_real(tree_right(r), &right)) {
123,155✔
175
      switch (rkind) {
123,047✔
176
      case RANGE_TO:
123,047✔
177
         *low  = left;
123,047✔
178
         *high = right;
123,047✔
179
         return true;
123,047✔
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;
108✔
190
}
191

192
bool folded_bool(tree_t t, bool *b)
51,165✔
193
{
194
   if (tree_kind(t) == T_REF) {
51,165✔
195
      tree_t decl = tree_ref(t);
14,175✔
196
      if (tree_kind(decl) == T_ENUM_LIT
14,175✔
197
          && type_ident(tree_type(decl)) == well_known(W_STD_BOOL)) {
11,559✔
198
         *b = (tree_pos(decl) == 1);
11,559✔
199
         return true;
11,559✔
200
      }
201
   }
202

203
   return false;
204
}
205

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

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

217
   return b;
10,926✔
218
}
219

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

228
   return f;
54,051✔
229
}
230

231
tree_t get_discrete_lit(tree_t t, type_t type, int64_t i)
5,564✔
232
{
233
   if (type_is_enum(type)) {
5,564✔
234
      type_t base = type_base_recur(type);
78✔
235
      const int maxlit = type_enum_literals(base);
78✔
236
      if (i >= maxlit)
78✔
237
         return NULL;
238
      else
239
         return get_enum_lit(t, type, i);
78✔
240
   }
241
   else
242
      return get_int_lit(t, type, i);
5,486✔
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)
121✔
257
{
258
   type_t base = type_base_recur(type);
121✔
259
   const type_kind_t basek = type_kind(base);
121✔
260

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

264
      int map[256];
23✔
265
      for (int i = 0; i < ARRAY_LEN(map); i++)
5,911✔
266
         map[i] = INT_MAX;
5,888✔
267

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

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

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

280
      int base = 0, dbits = 1;
23✔
281
      bool quoted = false;
23✔
282
      if (map['\"'] == INT_MAX) {
23✔
283
         if (str[0] == '\"') {
11✔
284
            quoted = true;
2✔
285
            str++;
2✔
286
         }
287
         else if (str[1] == '\"' && toupper_iso88591(str[0]) == 'X') {
9✔
288
            quoted = true;
3✔
289
            base = 16;
3✔
290
            dbits = 4;
3✔
291
            str += 2;
3✔
292
         }
293
      }
294

295
      const size_t max = strlen(str) * dbits;
23✔
296
      enum_array_t *array = xmalloc_flex(sizeof(enum_array_t), max, 1);
23✔
297

298
      int n = 0, m;
23✔
299
      for (; *str != '\0'; str++, n += dbits) {
122✔
300
         if (base > 0) {
84✔
301
            const bool extended = (isdigit_iso88591(*str) && *str < '0' + base)
20✔
302
               || (base > 10 && *str >= 'A' && *str < 'A' + base - 10)
4✔
303
               || (base > 10 && *str >= 'a' && *str < 'a' + base - 10);
15✔
304

305
            if (!extended)
12✔
306
               break;
307

308
            int digit = isdigit_iso88591(*str)
9✔
309
               ? (*str - '0')
8✔
310
               : 10 + (toupper_iso88591(*str) - 'A');
9✔
311

312
            bool valid = true;
9✔
313
            for (int i = dbits - 1; i >= 0; i--) {
45✔
314
               const uint8_t bit = (digit >> i) & 1 ? '1' : '0';
36✔
315
               valid &= (m = map[bit]) != INT_MAX;
36✔
316
               array->values[n + dbits - i - 1] = m;
36✔
317
            }
318

319
            if (!valid)
9✔
320
               break;
321
         }
322
         else if ((m = map[(uint8_t)*str]) == INT_MAX)
72✔
323
            break;
324
         else
325
            array->values[n] = m;
67✔
326
      }
327

328
      assert(n <= max);
23✔
329
      array->count = n;
23✔
330

331
      if (quoted && *str++ != '\"') {
23✔
332
         free(array);
2✔
333
         return false;
2✔
334
      }
335

336
      for (; *str; str++) {
29✔
337
         if (!isspace_iso88591(*str)) {
10✔
338
            free(array);
2✔
339
            return false;
2✔
340
         }
341
      }
342

343
      value->enums = array;
19✔
344
      return true;
19✔
345
   }
346

347
   while (isspace_iso88591(*str))
108✔
348
      ++str;
10✔
349

350
   switch (basek) {
98✔
351
   case T_INTEGER:
71✔
352
      {
353
         const bool is_negative = *str == '-';
71✔
354
         int num_digits = 0;
71✔
355

356
         if (is_negative) ++str;
71✔
357

358
         int64_t sum = 0;
359
         for (; isdigit_iso88591(*str) || (*str == '_'); str++) {
187✔
360
            if (*str != '_') {
116✔
361
               sum *= 10;
114✔
362
               sum += (*str - '0');
114✔
363
               num_digits++;
114✔
364
            }
365
         }
366

367
         value->integer = is_negative ? -sum : sum;
71✔
368

369
         if (num_digits == 0)
71✔
370
            return false;
371
      }
372
      break;
373

374
   case T_ENUM:
16✔
375
      {
376
         bool upcase = true;
16✔
377
         char *copy LOCAL = xstrdup(str), *p;
31✔
378
         for (p = copy; (*p != '\0') && !isspace_iso88591(*p); p++, str++) {
63✔
379
            if (*p == '\'')
47✔
380
               upcase = false;
381
            if (upcase)
25✔
382
               *p = toupper_iso88591(*p);
14✔
383
         }
384
         *p = '\0';
16✔
385

386
         ident_t id = ident_new(copy);
16✔
387

388
         value->integer = -1;
16✔
389

390
         const int nlits = type_enum_literals(base);
16✔
391
         for (int i = 0; i < nlits; i++) {
45✔
392
            if (tree_ident(type_enum_literal(base, i)) == id) {
44✔
393
               value->integer = i;
15✔
394
               break;
15✔
395
            }
396
         }
397

398
         if (value->integer == -1)
16✔
399
            return false;
1✔
400
      }
401
      break;
402

403
   case T_REAL:
6✔
404
      {
405
         char *eptr = NULL;
6✔
406
         value->real = strtod(str, &eptr);
6✔
407
         str = eptr;
6✔
408
      }
409
      break;
6✔
410

411
   case T_PHYSICAL:
5✔
412
      {
413
         char *eptr = NULL;
5✔
414
         double scale = strtod(str, &eptr);
5✔
415
         str = eptr;
5✔
416

417
         while (isspace_iso88591(*str)) ++str;
10✔
418

419
         char *copy LOCAL = xstrdup(str), *p;
10✔
420
         for (p = copy; *p && !isspace_iso88591(*p); p++, str++)
13✔
421
            *p = toupper_iso88591(*p);
8✔
422
         *p = '\0';
5✔
423

424
         if (p == copy)
5✔
425
            return false;
426

427
         ident_t id = ident_new(copy);
4✔
428

429
         value->integer = -1;
4✔
430

431
         const int nunits = type_units(base);
4✔
432
         for (int i = 0; i < nunits; i++) {
11✔
433
            tree_t u = type_unit(base, i);
11✔
434
            if (tree_ident(u) == id) {
11✔
435
               value->integer = scale * assume_int(tree_value(u));
4✔
436
               break;
4✔
437
            }
438
         }
439

440
         if (value->integer == -1)
4✔
441
            return false;
442
      }
443
      break;
444

445
   default:
446
      return false;
447
   }
448

449
   for (; *str; str++) {
107✔
450
      if (!isspace_iso88591(*str))
11✔
451
         return false;
452
   }
453

454
   return true;
455
}
456

457
tree_t make_ref(tree_t to)
9,544✔
458
{
459
   tree_t t = tree_new(T_REF);
9,544✔
460
   tree_set_ident(t, tree_ident(to));
9,544✔
461
   tree_set_ref(t, to);
9,544✔
462
   tree_set_type(t, tree_type(to));
9,544✔
463
   return t;
9,544✔
464
}
465

466
vhdl_standard_t standard(void)
3,587,085✔
467
{
468
   return current_std;
3,587,085✔
469
}
470

471
void set_standard(vhdl_standard_t s)
6,485✔
472
{
473
   current_std = s;
6,485✔
474
   have_set_std = true;
6,485✔
475
}
6,485✔
476

477
void set_default_standard(vhdl_standard_t s)
631✔
478
{
479
   if (!have_set_std)
631✔
480
      set_standard(s);
136✔
481
}
631✔
482

483
const char *standard_text(vhdl_standard_t s)
5,910✔
484
{
485
   static const char *text[] = {
5,910✔
486
      "1987", "1993", "2000", "2002", "2008", "2019"
487
   };
488

489
   if ((unsigned)s < ARRAY_LEN(text))
5,910✔
490
      return text[s];
5,910✔
491
   else
492
      return "????";
493
}
494

495
tree_t find_element_mode_indication(tree_t view, tree_t field, bool *converse)
592✔
496
{
497
   switch (tree_kind(view)) {
1,831✔
498
   case T_REF:
795✔
499
      return find_element_mode_indication(tree_ref(view), field, converse);
795✔
500

501
   case T_ALIAS:
203✔
502
      return find_element_mode_indication(tree_value(view), field, converse);
203✔
503

504
   case T_ATTR_REF:
241✔
505
      assert(tree_subkind(view) == ATTR_CONVERSE);
241✔
506
      *converse = !*converse;
241✔
507
      return find_element_mode_indication(tree_name(view), field, converse);
241✔
508

509
   case T_VIEW_DECL:
592✔
510
      {
511
         type_t view_type = tree_type(view);
592✔
512
         assert(type_kind(view_type) == T_VIEW);
592✔
513

514
         const int nelems = type_fields(view_type);
592✔
515
         for (int i = 0; i < nelems; i++) {
988✔
516
            tree_t e = type_field(view_type, i);
988✔
517
            if (tree_ref(e) == field)
988✔
518
               return e;
592✔
519
         }
520

521
         return NULL;
522
      }
523

524
   default:
×
525
      fatal_trace("unhandled tree kind %s in find_element_mode_indication",
526
                  tree_kind_str(tree_kind(view)));
527
   }
528
}
529

530
port_mode_t converse_mode(tree_t port, bool converse)
386✔
531
{
532
   const port_mode_t mode = tree_subkind(port);
386✔
533
   switch (mode) {
386✔
534
   case PORT_IN: return converse ? PORT_OUT : PORT_IN;
184✔
535
   case PORT_OUT: return converse ? PORT_IN : PORT_OUT;
170✔
536
   default: return mode;
537
   }
538
}
539

540
class_t class_of(tree_t t)
1,245,978✔
541
{
542
   switch (tree_kind(t)) {
1,355,251✔
543
   case T_VAR_DECL:
544
      return C_VARIABLE;
545
   case T_SIGNAL_DECL:
61,095✔
546
   case T_IMPLICIT_SIGNAL:
547
      return C_SIGNAL;
61,095✔
548
   case T_CONST_DECL:
42,911✔
549
      return C_CONSTANT;
42,911✔
550
   case T_PORT_DECL:
175,436✔
551
   case T_GENERIC_DECL:
552
   case T_PARAM_DECL:
553
   case T_EXTERNAL_NAME:
554
      return tree_class(t);
175,436✔
555
   case T_ENUM_LIT:
704,651✔
556
   case T_LITERAL:
557
   case T_STRING:
558
      return C_LITERAL;
704,651✔
559
   case T_FIELD_DECL:
1,358✔
560
   case T_ATTR_DECL:
561
      return C_DEFAULT;
1,358✔
562
   case T_VIEW_DECL:
181✔
563
      return C_VIEW;
181✔
564
   case T_UNIT_DECL:
10,073✔
565
      return C_UNITS;
10,073✔
566
   case T_ARCH:
56✔
567
      return C_ARCHITECTURE;
56✔
568
   case T_FUNC_DECL:
26,258✔
569
   case T_FUNC_BODY:
570
   case T_FUNC_INST:
571
   case T_FCALL:
572
   case T_PROT_FCALL:
573
      return C_FUNCTION;
26,258✔
574
   case T_PROC_DECL:
28,808✔
575
   case T_PROC_BODY:
576
   case T_PROC_INST:
577
   case T_PCALL:
578
   case T_PROT_PCALL:
579
      return C_PROCEDURE;
28,808✔
580
   case T_ENTITY:
167✔
581
      return C_ENTITY;
167✔
582
   case T_SUBTYPE_DECL:
23,158✔
583
      return C_SUBTYPE;
23,158✔
584
   case T_TYPE_DECL:
82,663✔
585
   case T_PROT_DECL:
586
   case T_PROT_BODY:
587
      return C_TYPE;
82,663✔
588
   case T_FILE_DECL:
1,445✔
589
      return C_FILE;
1,445✔
590
   case T_PROCESS:
178✔
591
   case T_BLOCK:
592
   case T_FOR:
593
   case T_INSTANCE:
594
   case T_CONCURRENT:
595
   case T_ELAB:
596
   case T_PSL_DECL:
597
   case T_PSL_DIRECT:
598
   case T_FOR_GENERATE:
599
   case T_IF_GENERATE:
600
   case T_CASE_GENERATE:
601
      return C_LABEL;
178✔
602
   case T_COMPONENT:
1✔
603
      return C_COMPONENT;
1✔
604
   case T_REF:
96,468✔
605
   case T_PROT_REF:
606
      return tree_has_ref(t) ? class_of(tree_ref(t)) : C_DEFAULT;
96,468✔
607
   case T_ARRAY_REF:
12,809✔
608
   case T_ARRAY_SLICE:
609
   case T_RECORD_REF:
610
   case T_ALL:
611
   case T_ALIAS:
612
   case T_QUALIFIED:
613
      return class_of(tree_value(t));
12,809✔
614
   case T_PACKAGE:
1,428✔
615
   case T_PACK_BODY:
616
   case T_PACK_INST:
617
      return C_PACKAGE;
1,428✔
618
   case T_CONFIGURATION:
1✔
619
      return C_CONFIGURATION;
1✔
620
   case T_LIBRARY:
1✔
621
      return C_LIBRARY;
1✔
622
   case T_ATTR_REF:
115✔
623
      switch (tree_subkind(t)) {
115✔
624
      case ATTR_DELAYED:
625
      case ATTR_STABLE:
626
      case ATTR_QUIET:
627
      case ATTR_TRANSACTION:
628
         return C_SIGNAL;
629
      default:
107✔
630
         return C_DEFAULT;
107✔
631
      }
632
   case T_CONTEXT:
×
633
      return C_CONTEXT;
×
634
   default:
×
635
      fatal_trace("missing class_of for %s", tree_kind_str(tree_kind(t)));
636
   }
637
}
638

639
bool class_has_type(class_t c)
1,022,259✔
640
{
641
   switch (c) {
1,022,259✔
642
   case C_LABEL:
643
   case C_ENTITY:
644
   case C_ARCHITECTURE:
645
   case C_COMPONENT:
646
   case C_CONFIGURATION:
647
   case C_PACKAGE:
648
   case C_LIBRARY:
649
      return false;
650
   default:
1,020,779✔
651
      return true;
1,020,779✔
652
   }
653
}
654

655
const char *class_str(class_t c)
369✔
656
{
657
   static const char *strs[] = {
369✔
658
      "default", "signal", "variable", "constant", "file", "entity",
659
      "component", "configuration", "architecture", "function", "package",
660
      "type", "subtype", "label", "procedure", "literal", "units", "library",
661
      "context", "view",
662
   };
663
   assert(c < ARRAY_LEN(strs));
369✔
664
   return strs[c];
369✔
665
}
666

667
const char *assoc_kind_str(assoc_kind_t akind)
9✔
668
{
669
   switch (akind) {
9✔
670
   case A_NAMED:  return "named";
671
   case A_CONCAT:
2✔
672
   case A_POS:    return "positional";
2✔
673
   case A_OTHERS: return "others";
3✔
674
   case A_SLICE:
1✔
675
   case A_RANGE:  return "range";
1✔
676
   default:       return "??";
×
677
   }
678
}
679

680
bool is_subprogram(tree_t t)
975,807✔
681
{
682
   switch (tree_kind(t)) {
975,807✔
683
   case T_FUNC_DECL:
684
   case T_FUNC_BODY:
685
   case T_FUNC_INST:
686
   case T_PROC_DECL:
687
   case T_PROC_BODY:
688
   case T_PROC_INST:
689
      return true;
690
   case T_GENERIC_DECL:
3,696✔
691
      {
692
         const class_t class = tree_class(t);
3,696✔
693
         return class == C_FUNCTION || class == C_PROCEDURE;
3,696✔
694
      }
695
   default:
776,559✔
696
      return false;
776,559✔
697
   }
698
}
699

700
bool is_loop_stmt(tree_t t)
462✔
701
{
702
   const tree_kind_t kind = tree_kind(t);
462✔
703
   return kind == T_WHILE || kind == T_FOR || kind == T_LOOP;
462✔
704
}
705

706
bool is_container(tree_t t)
12,650✔
707
{
708
   switch (tree_kind(t)) {
12,650✔
709
   case T_FUNC_BODY:
710
   case T_PROC_BODY:
711
   case T_ENTITY:
712
   case T_ARCH:
713
   case T_PACKAGE:
714
   case T_PACK_BODY:
715
   case T_CONFIGURATION:
716
   case T_BLOCK:
717
   case T_PROT_BODY:
718
   case T_ELAB:
719
   case T_FOR:
720
   case T_PROCESS:
721
   case T_PACK_INST:
722
      return true;
723
   default:
9,706✔
724
      return false;
9,706✔
725
   }
726
}
727

728
bool is_concurrent_block(tree_t t)
2,997✔
729
{
730
   switch (tree_kind(t)) {
2,997✔
731
   case T_ARCH:
732
   case T_ENTITY:
733
   case T_BLOCK:
734
   case T_IF_GENERATE:
735
   case T_FOR_GENERATE:
736
   case T_CASE_GENERATE:
737
      return true;
738
   default:
504✔
739
      return false;
504✔
740
   }
741
}
742

743
bool is_package(tree_t t)
53,299✔
744
{
745
   switch (tree_kind(t)) {
53,299✔
746
   case T_PACKAGE:
747
   case T_PACK_BODY:
748
   case T_PACK_INST:
749
      return true;
750
   default:
3,267✔
751
      return false;
3,267✔
752
   }
753
}
754

755
bool is_design_unit(tree_t t)
51,949✔
756
{
757
   switch (tree_kind(t)) {
51,949✔
758
   case T_ENTITY:
759
   case T_ARCH:
760
   case T_PACKAGE:
761
   case T_PACK_BODY:
762
   case T_CONFIGURATION:
763
   case T_CONTEXT:
764
   case T_PACK_INST:
765
      return true;
766
   default:
11,671✔
767
      return false;
11,671✔
768
   }
769
}
770

771
bool is_literal(tree_t t)
74,756✔
772
{
773
   switch (tree_kind(t)) {
74,756✔
774
   case T_REF:
26,151✔
775
      return tree_has_ref(t) && tree_kind(tree_ref(t)) == T_ENUM_LIT;
28,769✔
776
   case T_LITERAL:
777
      return true;
778
   case T_STRING:
26,314✔
779
   default:
780
      return false;
26,314✔
781
   }
782
}
783

784
bool is_body(tree_t t)
12,258✔
785
{
786
   switch (tree_kind(t)) {
12,258✔
787
   case T_FUNC_BODY:
788
   case T_PROC_BODY:
789
   case T_PACK_BODY:
790
   case T_PROT_BODY:
791
      return true;
792
   default:
4,112✔
793
      return false;
4,112✔
794
   }
795
}
796

797
bool is_guarded_signal(tree_t decl)
18,317✔
798
{
799
   switch (tree_kind(decl)) {
18,317✔
800
   case T_PORT_DECL:
17,854✔
801
   case T_SIGNAL_DECL:
802
      return !!(tree_flags(decl) & (TREE_F_BUS | TREE_F_REGISTER));
17,854✔
803
   default:
804
      return false;
805
   }
806
}
807

808
bool is_type_decl(tree_t t)
1,325,184✔
809
{
810
   switch (tree_kind(t)) {
1,325,184✔
811
   case T_TYPE_DECL:
812
   case T_SUBTYPE_DECL:
813
   case T_PROT_DECL:
814
   case T_PROT_BODY:
815
      return true;
816
   default:
1,091,431✔
817
      return false;
1,091,431✔
818
   }
819
}
820

821
tree_t aliased_type_decl(tree_t decl)
143,795✔
822
{
823
   switch (tree_kind(decl)) {
144,084✔
824
   case T_ALIAS:
291✔
825
      {
826
         tree_t value = tree_value(decl);
291✔
827
         const tree_kind_t kind = tree_kind(value);
291✔
828
         if (kind == T_REF && tree_has_ref(value))
291✔
829
            return aliased_type_decl(tree_ref(value));
289✔
830
         else if (kind == T_ATTR_REF && is_type_attribute(tree_subkind(value)))
2✔
831
             return value;
832
         else
833
            return NULL;
×
834
      }
835
   case T_TYPE_DECL:
836
   case T_SUBTYPE_DECL:
837
   case T_PROT_DECL:
838
   case T_PROT_BODY:
839
      return decl;
840
   case T_GENERIC_DECL:
1,989✔
841
      if (tree_class(decl) == C_TYPE)
1,989✔
842
         return decl;
843
      else
844
         return NULL;
987✔
845
   default:
33,777✔
846
      return NULL;
33,777✔
847
   }
848
}
849

850
tree_t add_param(tree_t call, tree_t value, param_kind_t kind, tree_t name)
188,716✔
851
{
852
   tree_t p = tree_new(T_PARAM);
188,716✔
853
   tree_set_loc(p, tree_loc(value));
188,716✔
854
   tree_set_subkind(p, kind);
188,716✔
855
   tree_set_value(p, value);
188,716✔
856

857
   switch (kind) {
188,716✔
858
   case P_NAMED:
96✔
859
      assert(name != NULL);
96✔
860
      tree_set_name(p, name);
96✔
861
      break;
96✔
862
   case P_POS:
188,620✔
863
      tree_set_pos(p, tree_params(call));
188,620✔
864
      break;
188,620✔
865
   }
866

867
   tree_add_param(call, p);
188,716✔
868
   return p;
188,716✔
869
}
870

871
type_t array_aggregate_type(type_t array, int from_dim)
339✔
872
{
873
   if (type_is_none(array))
339✔
874
      return type_new(T_NONE);
3✔
875

876
   if (type_is_unconstrained(array)) {
336✔
877
      const int nindex = type_indexes(array);
57✔
878
      assert(from_dim < nindex);
57✔
879

880
      type_t type = type_new(T_ARRAY);
57✔
881
      type_set_ident(type, type_ident(array));
57✔
882
      type_set_elem(type, type_elem(array));
57✔
883

884
      for (int i = from_dim; i < nindex; i++)
114✔
885
         type_add_index(type, type_index(array, i));
57✔
886

887
      return type;
888
   }
889
   else {
890
      const int ndims = dimension_of(array);
279✔
891
      assert(from_dim < ndims);
279✔
892

893
      type_t base = type_new(T_ARRAY);
279✔
894
      type_set_ident(base, type_ident(array));
279✔
895
      type_set_elem(base, type_elem(array));
279✔
896

897
      tree_t constraint = tree_new(T_CONSTRAINT);
279✔
898
      tree_set_subkind(constraint, C_INDEX);
279✔
899

900
      type_t sub = type_new(T_SUBTYPE);
279✔
901
      type_set_base(sub, base);
279✔
902
      type_set_constraint(sub, constraint);
279✔
903

904
      for (int i = from_dim; i < ndims; i++) {
582✔
905
         tree_t r = range_of(array, i);
303✔
906
         if (r == NULL) {
303✔
907
            // Not enough constraints were provided for the type
908
            r = tree_new(T_RANGE);
1✔
909
            tree_set_subkind(r, RANGE_ERROR);
1✔
910
            tree_set_type(r, type_new(T_NONE));
1✔
911
         }
912

913
         type_add_index(base, tree_type(r));
303✔
914
         tree_add_range(constraint, r);
303✔
915
      }
916

917
      return sub;
918
   }
919
}
920

921
unsigned bits_for_range(int64_t low, int64_t high)
3,214,610✔
922
{
923
   if (low > high)
3,214,610✔
924
      return 0;   // Null range
925
   else if (low < 0) {
3,214,609✔
926
      // Signed integers
927
      if (low >= INT8_MIN && high <= INT8_MAX)
793,283✔
928
         return 8;
929
      else if (low >= INT16_MIN && high <= INT16_MAX)
785,514✔
930
         return 16;
931
      else if (low >= INT32_MIN && high <= INT32_MAX)
785,130✔
932
         return 32;
933
      else
934
         return 64;
126,315✔
935
   }
936
   else {
937
      // Unsigned integers
938
      if (high <= 1)
2,421,326✔
939
         return 1;
940
      else if (high <= UINT8_MAX)
1,490,582✔
941
         return 8;
942
      else if (high <= UINT16_MAX)
308,988✔
943
         return 16;
944
      else if (high <= UINT32_MAX)
303,540✔
945
         return 32;
946
      else
947
         return 64;
61,668✔
948
   }
949
}
950

951
unsigned dimension_of(type_t type)
1,861,028✔
952
{
953
   switch (type_kind(type)) {
3,510,182✔
954
   case T_SUBTYPE:
1,649,152✔
955
      return dimension_of(type_base(type));
1,649,152✔
956
   case T_GENERIC:
183✔
957
      switch (type_subkind(type)) {
183✔
958
      case GTYPE_ARRAY:
167✔
959
         return type_indexes(type);
167✔
960
      case GTYPE_ACCESS:
×
961
         return dimension_of(type_designated(type));
×
962
      case GTYPE_FILE:
963
      case GTYPE_PRIVATE:
964
         return 0;
965
      default:
16✔
966
         return 1;
16✔
967
      }
968
   case T_ARRAY:
1,852,512✔
969
      return type_indexes(type);
1,852,512✔
970
   case T_NONE:
971
   case T_RECORD:
972
   case T_INCOMPLETE:
973
   case T_FILE:
974
   case T_SIGNATURE:
975
      return 0;
976
   case T_INTEGER:
8,251✔
977
   case T_REAL:
978
   case T_PHYSICAL:
979
   case T_ENUM:
980
      return type_dims(type);
8,251✔
981
   case T_ACCESS:
2✔
982
      return dimension_of(type_designated(type));
2✔
983
   default:
×
984
      fatal_trace("invalid type kind %s in dimension_of",
985
                  type_kind_str(type_kind(type)));
986
   }
987
}
988

989
tree_t range_of(type_t type, unsigned dim)
2,739,806✔
990
{
991
   switch (type_kind(type)) {
2,787,093✔
992
   case T_SUBTYPE:
2,174,925✔
993
      if (type_has_constraint(type)) {
2,174,925✔
994
         tree_t c = type_constraint(type);
2,127,638✔
995
         switch (tree_subkind(c)) {
2,127,638✔
996
         case C_INDEX:
2,127,638✔
997
         case C_RANGE:
998
            if (dim < tree_ranges(c))
2,127,638✔
999
               return tree_range(c, dim);
2,127,637✔
1000
            else
1001
               return NULL;   // Must be an error
1002
         default:
×
1003
            should_not_reach_here();
1004
         }
1005
      }
1006
      else
1007
         return range_of(type_base(type), dim);
47,287✔
1008
   case T_INTEGER:
612,168✔
1009
   case T_REAL:
1010
   case T_PHYSICAL:
1011
   case T_ENUM:
1012
      return type_dim(type, dim);
612,168✔
1013
   default:
×
1014
      fatal_trace("invalid type kind %s for %s in range_of",
1015
                  type_kind_str(type_kind(type)), type_pp(type));
1016
   }
1017
}
1018

1019
range_kind_t direction_of(type_t type, unsigned dim)
29,865✔
1020
{
1021
   switch (type_kind(type)) {
29,969✔
1022
   case T_ENUM:
1023
      return RANGE_TO;
1024
   case T_NONE:
×
1025
      return RANGE_ERROR;
×
1026
   case T_INTEGER:
29,859✔
1027
   case T_REAL:
1028
   case T_PHYSICAL:
1029
   case T_SUBTYPE:
1030
      {
1031
         tree_t r = range_of(type, dim);
29,859✔
1032
         const range_kind_t rkind = tree_subkind(r);
29,859✔
1033
         if (rkind == RANGE_EXPR) {
29,859✔
1034
            // Return a fixed direction if possible
1035
            tree_t value = tree_value(r);
176✔
1036
            assert(tree_kind(value) == T_ATTR_REF);
176✔
1037

1038
            DEBUG_ONLY({
176✔
1039
                  const attr_kind_t attr = tree_subkind(value);
1040
                  assert(attr == ATTR_RANGE || attr == ATTR_REVERSE_RANGE);
1041
               });
176✔
1042

1043
            tree_t name = tree_name(value);
176✔
1044
            if (tree_kind(name) == T_REF && tree_has_ref(name)) {
176✔
1045
               tree_t decl = tree_ref(name);
175✔
1046
               if (is_type_decl(decl))
175✔
1047
                  return direction_of(tree_type(decl), 0);
104✔
1048
            }
1049
         }
1050

1051
         return rkind;
1052
      }
1053
   default:
×
1054
      fatal_trace("invalid type kind %s in direction_of",
1055
                  type_kind_str(type_kind(type)));
1056
   }
1057
}
1058

1059
type_t index_type_of(type_t type, unsigned dim)
284,936✔
1060
{
1061
   if (dim >= dimension_of(type))
284,938✔
1062
      return NULL;
1063

1064
   type_t base = type_base_recur(type);
284,898✔
1065
   type_kind_t base_kind = type_kind(base);
284,898✔
1066
   if (base_kind == T_ARRAY)
284,898✔
1067
      return type_index(base, dim);
280,974✔
1068
   else if (base_kind == T_ENUM || base_kind == T_NONE)
3,924✔
1069
      return type;
1070
   else if (base_kind == T_GENERIC && type_subkind(base) == GTYPE_ARRAY)
3,738✔
1071
      return type_index(base, dim);
103✔
1072
   else if (base_kind == T_RECORD || base_kind == T_GENERIC)
3,635✔
1073
      return NULL;
1074
   else if (base_kind == T_ACCESS)
3,627✔
1075
      return index_type_of(type_designated(type), dim);
2✔
1076
   else
1077
      return tree_type(range_of(base, dim));
3,625✔
1078
}
1079

1080
int64_t rebase_index(type_t array_type, int dim, int64_t value)
512✔
1081
{
1082
   // Convert value which is in the range of array_type to a zero-based index
1083
   tree_t r = range_of(array_type, dim);
512✔
1084
   const int64_t left = assume_int(tree_left(r));
512✔
1085
   return (tree_subkind(r) == RANGE_TO) ? value - left : left - value;
512✔
1086
}
1087

1088
ident_t well_known(well_known_t id)
620,553✔
1089
{
1090
   assert(id < NUM_WELL_KNOWN);
620,553✔
1091
   return id_cache[id];
620,553✔
1092
}
1093

1094
well_known_t is_well_known(ident_t ident)
321,451✔
1095
{
1096
   well_known_t pos = 0;
321,451✔
1097
   for (; pos < NUM_WELL_KNOWN; pos++) {
17,594,301✔
1098
      if (id_cache[pos] == ident)
17,428,153✔
1099
         break;
1100
   }
1101

1102
   return pos;
321,451✔
1103
}
1104

1105
void intern_strings(void)
6,762✔
1106
{
1107
   id_cache[W_STD_STANDARD]    = ident_new("STD.STANDARD");
6,762✔
1108
   id_cache[W_ALL]             = ident_new("all");
6,762✔
1109
   id_cache[W_STD_BIT]         = ident_new("STD.STANDARD.BIT");
6,762✔
1110
   id_cache[W_STD_BOOL]        = ident_new("STD.STANDARD.BOOLEAN");
6,762✔
1111
   id_cache[W_STD_CHAR]        = ident_new("STD.STANDARD.CHARACTER");
6,762✔
1112
   id_cache[W_STD_NATURAL]     = ident_new("STD.STANDARD.NATURAL");
6,762✔
1113
   id_cache[W_STD_POSITIVE]    = ident_new("STD.STANDARD.POSITIVE");
6,762✔
1114
   id_cache[W_STD_INTEGER]     = ident_new("STD.STANDARD.INTEGER");
6,762✔
1115
   id_cache[W_STD_STRING]      = ident_new("STD.STANDARD.STRING");
6,762✔
1116
   id_cache[W_STD_REAL]        = ident_new("STD.STANDARD.REAL");
6,762✔
1117
   id_cache[W_STD_TIME]        = ident_new("STD.STANDARD.TIME");
6,762✔
1118
   id_cache[W_STD_BIT_VECTOR]  = ident_new("STD.STANDARD.BIT_VECTOR");
6,762✔
1119
   id_cache[W_IEEE_SIGNED]     = ident_new("IEEE.NUMERIC_STD.SIGNED");
6,762✔
1120
   id_cache[W_IEEE_UNSIGNED]   = ident_new("IEEE.NUMERIC_STD.UNSIGNED");
6,762✔
1121
   id_cache[W_IEEE_LOGIC]      = ident_new("IEEE.STD_LOGIC_1164.STD_LOGIC");
6,762✔
1122
   id_cache[W_IEEE_ULOGIC]     = ident_new("IEEE.STD_LOGIC_1164.STD_ULOGIC");
6,762✔
1123
   id_cache[W_IEEE_1164_AND]   = ident_new("IEEE.STD_LOGIC_1164.\"and\"");
6,762✔
1124
   id_cache[W_IEEE_1164_NAND]  = ident_new("IEEE.STD_LOGIC_1164.\"nand\"");
6,762✔
1125
   id_cache[W_IEEE_1164_OR]    = ident_new("IEEE.STD_LOGIC_1164.\"or\"");
6,762✔
1126
   id_cache[W_IEEE_1164_NOR]   = ident_new("IEEE.STD_LOGIC_1164.\"nor\"");
6,762✔
1127
   id_cache[W_IEEE_1164_XOR]   = ident_new("IEEE.STD_LOGIC_1164.\"xor\"");
6,762✔
1128
   id_cache[W_IEEE_1164_XNOR]  = ident_new("IEEE.STD_LOGIC_1164.\"xnor\"");
6,762✔
1129
   id_cache[W_FOREIGN]         = ident_new("FOREIGN");
6,762✔
1130
   id_cache[W_WORK]            = ident_new("WORK");
6,762✔
1131
   id_cache[W_STD]             = ident_new("STD");
6,762✔
1132
   id_cache[W_THUNK]           = ident_new("thunk");
6,762✔
1133
   id_cache[W_BODY]            = ident_new("body");
6,762✔
1134
   id_cache[W_CARET]           = ident_new("^");
6,762✔
1135
   id_cache[W_IEEE]            = ident_new("IEEE");
6,762✔
1136
   id_cache[W_IEEE_1164]       = ident_new("IEEE.STD_LOGIC_1164");
6,762✔
1137
   id_cache[W_ERROR]           = ident_new("$error");
6,762✔
1138
   id_cache[W_ELAB]            = ident_new("elab");
6,762✔
1139
   id_cache[W_NUMERIC_STD]     = ident_new("IEEE.NUMERIC_STD");
6,762✔
1140
   id_cache[W_NUMERIC_BIT]     = ident_new("IEEE.NUMERIC_BIT");
6,762✔
1141
   id_cache[W_NVC]             = ident_new("NVC");
6,762✔
1142
   id_cache[W_DEFAULT_CLOCK]   = ident_new("default clock");
6,762✔
1143
   id_cache[W_STD_REFLECTION]  = ident_new("STD.REFLECTION");
6,762✔
1144
   id_cache[W_NEVER_WAITS]     = ident_new("NEVER_WAITS");
6,762✔
1145
   id_cache[W_NVC_VERILOG]     = ident_new("NVC.VERILOG");
6,762✔
1146
   id_cache[W_NVC_PSL_SUPPORT] = ident_new("NVC.PSL_SUPPORT");
6,762✔
1147
   id_cache[W_INSTANCE_NAME]   = ident_new("instance_name");
6,762✔
1148
   id_cache[W_PATH_NAME]       = ident_new("path_name");
6,762✔
1149
   id_cache[W_VITAL]           = ident_new("VITAL");
6,762✔
1150
   id_cache[W_RESOLUTION]      = ident_new("resolution");
6,762✔
1151
   id_cache[W_TEXT_UTIL]       = ident_new("NVC.TEXT_UTIL");
6,762✔
1152
   id_cache[W_VERILOG_LOGIC]   = ident_new("NVC.VERILOG.T_LOGIC");
6,762✔
1153

1154
   id_cache[W_IEEE_LOGIC_VECTOR] =
13,524✔
1155
      ident_new("IEEE.STD_LOGIC_1164.STD_LOGIC_VECTOR");
6,762✔
1156
   id_cache[W_IEEE_ULOGIC_VECTOR] =
13,524✔
1157
      ident_new("IEEE.STD_LOGIC_1164.STD_ULOGIC_VECTOR");
6,762✔
1158
   id_cache[W_IEEE_1164_RISING_EDGE] =
13,524✔
1159
      ident_new("IEEE.STD_LOGIC_1164.RISING_EDGE(sU)B");
6,762✔
1160
   id_cache[W_IEEE_1164_FALLING_EDGE] =
13,524✔
1161
      ident_new("IEEE.STD_LOGIC_1164.FALLING_EDGE(sU)B");
6,762✔
1162

1163
   id_cache[W_NUMERIC_STD_UNSIGNED] = ident_new("IEEE.NUMERIC_STD_UNSIGNED");
6,762✔
1164
   id_cache[W_NUMERIC_BIT_UNSIGNED] = ident_new("IEEE.NUMERIC_BIT_UNSIGNED");
6,762✔
1165
   id_cache[W_VERILOG_NET_VALUE]    = ident_new("NVC.VERILOG.T_NET_VALUE");
6,762✔
1166
   id_cache[W_VERILOG_WIRE_ARRAY]   = ident_new("NVC.VERILOG.T_WIRE_ARRAY");
6,762✔
1167

1168
   id_cache[W_OP_CCONV]               = ident_new("\"??\"");
6,762✔
1169
   id_cache[W_OP_AND]                 = ident_new("\"and\"");
6,762✔
1170
   id_cache[W_OP_OR]                  = ident_new("\"or\"");
6,762✔
1171
   id_cache[W_OP_NAND]                = ident_new("\"nand\"");
6,762✔
1172
   id_cache[W_OP_NOR]                 = ident_new("\"nor\"");
6,762✔
1173
   id_cache[W_OP_XOR]                 = ident_new("\"xor\"");
6,762✔
1174
   id_cache[W_OP_XNOR]                = ident_new("\"xnor\"");
6,762✔
1175
   id_cache[W_OP_EQUAL]               = ident_new("\"=\"");
6,762✔
1176
   id_cache[W_OP_NOT_EQUAL]           = ident_new("\"/=\"");
6,762✔
1177
   id_cache[W_OP_LESS_THAN]           = ident_new("\"<\"");
6,762✔
1178
   id_cache[W_OP_LESS_EQUAL]          = ident_new("\"<=\"");
6,762✔
1179
   id_cache[W_OP_GREATER_THAN]        = ident_new("\">\"");
6,762✔
1180
   id_cache[W_OP_GREATER_EQUAL]       = ident_new("\">=\"");
6,762✔
1181
   id_cache[W_OP_MATCH_EQUAL]         = ident_new("\"?=\"");
6,762✔
1182
   id_cache[W_OP_MATCH_NOT_EQUAL]     = ident_new("\"?/=\"");
6,762✔
1183
   id_cache[W_OP_MATCH_LESS_THAN]     = ident_new("\"?<\"");
6,762✔
1184
   id_cache[W_OP_MATCH_LESS_EQUAL]    = ident_new("\"?<=\"");
6,762✔
1185
   id_cache[W_OP_MATCH_GREATER_THAN]  = ident_new("\"?>\"");
6,762✔
1186
   id_cache[W_OP_MATCH_GREATER_EQUAL] = ident_new("\"?>=\"");
6,762✔
1187
   id_cache[W_OP_SLL]                 = ident_new("\"sll\"");
6,762✔
1188
   id_cache[W_OP_SRL]                 = ident_new("\"srl\"");
6,762✔
1189
   id_cache[W_OP_SLA]                 = ident_new("\"sla\"");
6,762✔
1190
   id_cache[W_OP_SRA]                 = ident_new("\"sra\"");
6,762✔
1191
   id_cache[W_OP_ROL]                 = ident_new("\"rol\"");
6,762✔
1192
   id_cache[W_OP_ROR]                 = ident_new("\"ror\"");
6,762✔
1193
   id_cache[W_OP_ADD]                 = ident_new("\"+\"");
6,762✔
1194
   id_cache[W_OP_MINUS]               = ident_new("\"-\"");
6,762✔
1195
   id_cache[W_OP_CONCAT]              = ident_new("\"&\"");
6,762✔
1196
   id_cache[W_OP_TIMES]               = ident_new("\"*\"");
6,762✔
1197
   id_cache[W_OP_DIVIDE]              = ident_new("\"/\"");
6,762✔
1198
   id_cache[W_OP_MOD]                 = ident_new("\"mod\"");
6,762✔
1199
   id_cache[W_OP_REM]                 = ident_new("\"rem\"");
6,762✔
1200
   id_cache[W_OP_EXPONENT]            = ident_new("\"**\"");
6,762✔
1201
   id_cache[W_OP_ABS]                 = ident_new("\"abs\"");
6,762✔
1202
   id_cache[W_OP_NOT]                 = ident_new("\"not\"");
6,762✔
1203
}
6,762✔
1204

1205
bool is_uninstantiated_package(tree_t pack)
46,515✔
1206
{
1207
   return tree_kind(pack) == T_PACKAGE
46,515✔
1208
      && tree_generics(pack) > 0
44,212✔
1209
      && tree_genmaps(pack) == 0;
48,965✔
1210
}
1211

1212
bool is_uninstantiated_subprogram(tree_t decl)
119,853✔
1213
{
1214
   switch (tree_kind(decl)) {
119,853✔
1215
   case T_FUNC_DECL:
119,161✔
1216
   case T_FUNC_BODY:
1217
   case T_PROC_DECL:
1218
   case T_PROC_BODY:
1219
      return tree_generics(decl) > 0;
119,161✔
1220
   default:
1221
      return false;
1222
   }
1223
}
1224

1225
bool is_anonymous_subtype(type_t type)
236,692✔
1226
{
1227
   return type_kind(type) == T_SUBTYPE && !type_has_ident(type);
236,692✔
1228
}
1229

1230
bool unit_needs_cgen(tree_t unit)
259✔
1231
{
1232
   switch (tree_kind(unit)) {
259✔
1233
   case T_PACK_INST:
1234
      return true;
1235
   case T_PACK_BODY:
×
1236
      {
1237
         tree_t pack = tree_primary(unit);
×
1238
         return package_needs_body(pack) && !is_uninstantiated_package(pack);
×
1239
      }
1240
   case T_PACKAGE:
16✔
1241
      return !package_needs_body(unit) && !is_uninstantiated_package(unit);
32✔
1242
   default:
×
1243
      return false;
×
1244
   }
1245
}
1246

1247
bool package_needs_body(tree_t pack)
15,840✔
1248
{
1249
   assert(tree_kind(pack) == T_PACKAGE);
15,840✔
1250

1251
   const int ndecls = tree_decls(pack);
15,840✔
1252
   for (int i = 0; i < ndecls; i++) {
1,473,702✔
1253
      tree_t d = tree_decl(pack, i);
1,471,813✔
1254
      const tree_kind_t dkind = tree_kind(d);
1,471,813✔
1255
      if ((dkind == T_FUNC_DECL || dkind == T_PROC_DECL)
1,471,813✔
1256
          && !(tree_flags(d) & TREE_F_PREDEFINED))
1,344,047✔
1257
         return true;
1258
      else if (dkind == T_CONST_DECL && !tree_has_value(d))
1,458,475✔
1259
         return true;
1260
      else if (dkind == T_PROT_DECL)
1,458,001✔
1261
         return true;
1262
   }
1263

1264
   return false;
1265
}
1266

1267
static tree_t cached_unit(tree_t hint, tree_t *cache, well_known_t lib_name,
18,480✔
1268
                          well_known_t unit_name)
1269
{
1270
   const vhdl_standard_t curr = standard();
18,480✔
1271

1272
   if (cache[curr] == NULL) {
18,480✔
1273
      if (hint != NULL)
5,827✔
1274
         cache[curr] = hint;
1,793✔
1275
      else {
1276
         lib_t std = lib_require(well_known(lib_name));
4,034✔
1277
         cache[curr] = lib_get(std, well_known(unit_name));
4,034✔
1278
         assert(cache[curr] != NULL);
4,034✔
1279
      }
1280
   }
1281

1282
   assert(hint == NULL || hint == cache[curr]);
18,480✔
1283
   return cache[curr];
18,480✔
1284
}
1285

1286
static tree_t cached_std(tree_t hint)
17,629✔
1287
{
1288
   static tree_t standard_cache[STD_19 + 1] = {};
17,629✔
1289
   return cached_unit(hint, standard_cache, W_STD, W_STD_STANDARD);
17,629✔
1290
}
1291

1292
static tree_t search_type_decls(tree_t container, ident_t name)
18,264✔
1293
{
1294
   const int ndecls = tree_decls(container);
18,264✔
1295

1296
   for (int i = 0; i < ndecls; i++) {
1,176,777✔
1297
      tree_t d = tree_decl(container, i);
1,176,777✔
1298
      if (is_type_decl(d) && tree_ident(d) == name)
1,176,777✔
1299
         return d;
18,264✔
1300
   }
1301

1302
   return NULL;
1303
}
1304

1305
type_t std_type(tree_t std, std_type_t which)
1,209,776✔
1306
{
1307
   static type_t cache[STD_FILE_OPEN_STATE + 1] = {};
1,209,776✔
1308
   assert(which < ARRAY_LEN(cache));
1,209,776✔
1309

1310
   if (cache[which] == NULL) {
1,209,776✔
1311
      const char *names[] = {
17,629✔
1312
         "universal_integer",
1313
         "universal_real",
1314
         "INTEGER",
1315
         "REAL",
1316
         "BOOLEAN",
1317
         "STRING",
1318
         "TIME",
1319
         "BIT",
1320
         "FILE_OPEN_KIND",
1321
         "FILE_OPEN_STATUS",
1322
         "NATURAL",
1323
         "BIT_VECTOR",
1324
         "SEVERITY_LEVEL",
1325
         "FILE_ORIGIN_KIND",
1326
         "FILE_OPEN_STATE",
1327
      };
1328

1329
      tree_t d = search_type_decls(cached_std(std), ident_new(names[which]));
17,629✔
1330
      if (d == NULL)
17,629✔
1331
         fatal_trace("cannot find standard type %s", names[which]);
1332

1333
      // Do not cache standard types while bootstrapping as the GC will
1334
      // move the objects after parsing
1335
      static int can_cache = -1;
17,629✔
1336
      if (can_cache == -1) can_cache = !opt_get_int(OPT_BOOTSTRAP);
17,629✔
1337

1338
      if (can_cache)
17,629✔
1339
         return (cache[which] = tree_type(d));
17,439✔
1340
      else
1341
         return tree_type(d);
190✔
1342
   }
1343
   else
1344
      return cache[which];
1345
}
1346

1347
type_t ieee_type(ieee_type_t which)
1,824✔
1348
{
1349
   static type_t cache[IEEE_STD_LOGIC_VECTOR + 1] = {};
1,824✔
1350
   assert(which < ARRAY_LEN(cache));
1,824✔
1351

1352
   if (cache[which] == NULL) {
1,824✔
1353
      static const char *const names[] = {
216✔
1354
         [IEEE_STD_ULOGIC] = "STD_ULOGIC",
1355
         [IEEE_STD_LOGIC] = "STD_LOGIC",
1356
         [IEEE_STD_ULOGIC_VECTOR] = "STD_ULOGIC_VECTOR",
1357
         [IEEE_STD_LOGIC_VECTOR] = "STD_LOGIC_VECTOR",
1358
      };
1359

1360
      static tree_t ieee_cache[STD_19 + 1] = {};
216✔
1361
      tree_t unit = cached_unit(NULL, ieee_cache, W_IEEE, W_IEEE_1164);
216✔
1362

1363
      tree_t d = search_type_decls(unit, ident_new(names[which]));
216✔
1364
      if (d == NULL)
216✔
1365
         fatal_trace("cannot find IEEE type %s", names[which]);
1366

1367
      // STD.STANDARD cannot depend on IEEE
1368
      assert(!opt_get_int(OPT_BOOTSTRAP));
216✔
1369

1370
      return (cache[which] = tree_type(d));
216✔
1371
   }
1372
   else
1373
      return cache[which];
1374
}
1375

1376
static tree_t cached_verilog(void)
593✔
1377
{
1378
   static tree_t verilog_cache[STD_19 + 1] = {};
593✔
1379
   return cached_unit(NULL, verilog_cache, W_NVC, W_NVC_VERILOG);
593✔
1380
}
1381

1382
type_t verilog_type(verilog_type_t which)
1,172✔
1383
{
1384
   static type_t cache[VERILOG_WIRE_ARRAY + 1] = {};
1,172✔
1385
   assert(which < ARRAY_LEN(cache));
1,172✔
1386

1387
   if (cache[which] == NULL) {
1,172✔
1388
      static const char *const names[] = {
377✔
1389
         [VERILOG_LOGIC] = "T_LOGIC",
1390
         [VERILOG_LOGIC_ARRAY] = "T_LOGIC_ARRAY",
1391
         [VERILOG_INT64] = "T_INT64",
1392
         [VERILOG_NET_VALUE] = "T_NET_VALUE",
1393
         [VERILOG_NET_ARRAY] = "T_NET_ARRAY",
1394
         [VERILOG_WIRE] = "T_WIRE",
1395
         [VERILOG_WIRE_ARRAY] = "T_WIRE_ARRAY",
1396
      };
1397

1398
      tree_t d = search_type_decls(cached_verilog(), ident_new(names[which]));
377✔
1399
      if (d == NULL)
377✔
1400
         fatal_trace("cannot find NVC.VERILOG type %s", names[which]);
1401

1402
      // STD.STANDARD cannot depend on NVC.VERILOG
1403
      assert(!opt_get_int(OPT_BOOTSTRAP));
377✔
1404

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

1411
type_t reflection_type(reflect_type_t which)
249✔
1412
{
1413
   static type_t cache[REFLECT_SUBTYPE_MIRROR + 1] = {};
249✔
1414
   assert(which < ARRAY_LEN(cache));
249✔
1415

1416
   if (cache[which] == NULL) {
249✔
1417
      static const char *const names[] = {
42✔
1418
         [REFLECT_VALUE_MIRROR] = "VALUE_MIRROR",
1419
         [REFLECT_SUBTYPE_MIRROR] = "SUBTYPE_MIRROR",
1420
      };
1421

1422
      static tree_t reflect_cache[STD_19 + 1] = {};
42✔
1423
      tree_t unit = cached_unit(NULL, reflect_cache, W_STD, W_STD_REFLECTION);
42✔
1424

1425
      tree_t d = search_type_decls(unit, ident_new(names[which]));
42✔
1426
      if (d == NULL)
42✔
1427
         fatal_trace("cannot find REFLECTION type %s", names[which]);
1428

1429
      // STD.STANDARD cannot depend on REFLECTION
1430
      assert(!opt_get_int(OPT_BOOTSTRAP));
42✔
1431

1432
      return (cache[which] = tree_type(d));
42✔
1433
   }
1434
   else
1435
      return cache[which];
1436
}
1437

1438
bool is_open_coded_builtin(subprogram_kind_t kind)
1,456,133✔
1439
{
1440
   switch (kind) {
1,456,133✔
1441
   case S_ADD:
1442
   case S_SUB:
1443
   case S_DIV:
1444
   case S_MUL:
1445
   case S_MUL_PR:
1446
   case S_MUL_RP:
1447
   case S_MUL_PI:
1448
   case S_MUL_IP:
1449
   case S_DIV_PR:
1450
   case S_DIV_PP:
1451
   case S_DIV_PI:
1452
   case S_IDENTITY:
1453
   case S_NEGATE:
1454
   case S_SCALAR_LT:
1455
   case S_SCALAR_LE:
1456
   case S_SCALAR_GT:
1457
   case S_SCALAR_GE:
1458
   case S_SCALAR_EQ:
1459
   case S_SCALAR_NEQ:
1460
   case S_ABS:
1461
   case S_MOD:
1462
   case S_REM:
1463
   case S_EXP:
1464
   case S_MUL_RI:
1465
   case S_MUL_IR:
1466
   case S_DIV_RI:
1467
   case S_CONCAT:
1468
   case S_SCALAR_AND:
1469
   case S_SCALAR_OR:
1470
   case S_SCALAR_NOT:
1471
   case S_SCALAR_NAND:
1472
   case S_SCALAR_NOR:
1473
   case S_SCALAR_XOR:
1474
   case S_SCALAR_XNOR:
1475
   case S_FILE_OPEN1:
1476
   case S_FILE_OPEN2:
1477
   case S_FILE_READ:
1478
   case S_FILE_WRITE:
1479
   case S_DEALLOCATE:
1480
      return true;
1481
   default:
543,971✔
1482
      return false;
543,971✔
1483
   }
1484
}
1485

UNCOV
1486
tree_t std_func(ident_t mangled)
×
1487
{
UNCOV
1488
   tree_t std = cached_std(NULL);
×
1489

UNCOV
1490
   const int ndecls = tree_decls(std);
×
UNCOV
1491
   for (int i = 0; i < ndecls; i++) {
×
UNCOV
1492
      tree_t d = tree_decl(std, i);
×
UNCOV
1493
      if (is_subprogram(d) && tree_has_ident2(d) && tree_ident2(d) == mangled)
×
1494
         return d;
×
1495
   }
1496

1497
   return NULL;
1498
}
1499

1500
tree_t verilog_func(ident_t mangled)
216✔
1501
{
1502
   tree_t pack = cached_verilog();
216✔
1503

1504
   const int ndecls = tree_decls(pack);
216✔
1505
   for (int i = 0; i < ndecls; i++) {
21,090✔
1506
      tree_t d = tree_decl(pack, i);
21,090✔
1507
      if (is_subprogram(d) && tree_ident2(d) == mangled)
21,090✔
1508
         return d;
216✔
1509
   }
1510

1511
   fatal_trace("missing Verilog helper function %s", istr(mangled));
1512
}
1513

1514
tree_t name_to_ref(tree_t name)
114,106✔
1515
{
1516
   tree_kind_t kind;
114,106✔
1517
   while ((kind = tree_kind(name)) != T_REF) {
131,470✔
1518
      switch (kind) {
19,582✔
1519
      case T_ARRAY_REF:
17,364✔
1520
      case T_ARRAY_SLICE:
1521
      case T_RECORD_REF:
1522
      case T_ALL:
1523
         name = tree_value(name);
17,364✔
1524
         break;
17,364✔
1525
      default:
1526
         return NULL;
1527
      }
1528
   }
1529

1530
   return name;
1531
}
1532

1533
const char *port_mode_str(port_mode_t mode)
44✔
1534
{
1535
   const char *mode_str[] = {
44✔
1536
      "INVALID", "IN", "OUT", "INOUT", "BUFFER", "LINKAGE", "VIEW", "VIEW"
1537
   };
1538
   assert(mode < ARRAY_LEN(mode_str));
44✔
1539
   return mode_str[mode];
44✔
1540
}
1541

1542
void mangle_one_type(text_buf_t *buf, type_t type)
203,588✔
1543
{
1544
   ident_t ident = type_ident(type);
203,588✔
1545

1546
   char code = 0;
203,588✔
1547
   switch (is_well_known(ident)) {
203,588✔
1548
   case W_STD_INTEGER:        code = 'I'; break;
1549
   case W_STD_STRING:         code = 'S'; break;
3,957✔
1550
   case W_STD_REAL:           code = 'R'; break;
4,000✔
1551
   case W_STD_BOOL:           code = 'B'; break;
27,747✔
1552
   case W_STD_CHAR:           code = 'C'; break;
677✔
1553
   case W_STD_TIME:           code = 'T'; break;
1,018✔
1554
   case W_STD_NATURAL:        code = 'N'; break;
4,739✔
1555
   case W_STD_POSITIVE:       code = 'P'; break;
463✔
1556
   case W_STD_BIT:            code = 'J'; break;
3,011✔
1557
   case W_STD_BIT_VECTOR:     code = 'Q'; break;
3,468✔
1558
   case W_IEEE_LOGIC:         code = 'L'; break;
330✔
1559
   case W_IEEE_ULOGIC:        code = 'U'; break;
4,858✔
1560
   case W_IEEE_LOGIC_VECTOR:  code = 'V'; break;
1,768✔
1561
   case W_IEEE_ULOGIC_VECTOR: code = 'Y'; break;
1,407✔
1562
   default: break;
1563
   }
1564

1565
   if (code)
57,443✔
1566
      tb_append(buf, code);
72,645✔
1567
   else {
1568
      tb_printf(buf, "%zu", ident_len(ident));
130,943✔
1569
      tb_istr(buf, ident);
130,943✔
1570
   }
1571
}
203,588✔
1572

1573
ident_t get_call_context(ident_t mangled)
30,207✔
1574
{
1575
   const char *str = istr(mangled), *p = str, *end = NULL;
30,207✔
1576
   for (; *p; p++) {
835,068✔
1577
      if (*p == '(') break;
797,973✔
1578
      if (*p == '.') end = p;
774,654✔
1579
   }
1580
   assert(end != NULL);
30,207✔
1581

1582
   return ident_new_n(str, end - str);
30,207✔
1583
}
1584

1585
tree_t primary_unit_of(tree_t unit)
20,855✔
1586
{
1587
   switch (tree_kind(unit)) {
20,855✔
1588
   case T_ENTITY:
1589
   case T_COMPONENT:
1590
   case T_PACKAGE:
1591
   case T_BLOCK:
1592
   case T_ELAB:
1593
   case T_PACK_INST:
1594
      return unit;
1595
   case T_ARCH:
10,423✔
1596
   case T_CONFIGURATION:
1597
   case T_PACK_BODY:
1598
      return tree_primary(unit);
10,423✔
1599
   default:
×
1600
      fatal_trace("invalid kind %s in primary_unit_of",
1601
                  tree_kind_str(tree_kind(unit)));
1602
   }
1603
}
1604

1605
unsigned get_case_choice_char(tree_t value, int depth)
12,569✔
1606
{
1607
   switch (tree_kind(value)) {
13,605✔
1608
   case T_STRING:
12,171✔
1609
      if (depth < tree_chars(value))
12,171✔
1610
         return assume_int(tree_char(value, depth));
12,170✔
1611
      else
1612
         return ~0;   // Out of bounds
1613

1614
   case T_AGGREGATE:
398✔
1615
      {
1616
         const int nassocs = tree_assocs(value);
398✔
1617
         type_t type = tree_type(value);
398✔
1618

1619
         for (int i = 0, pos = 0; i < nassocs; i++) {
600✔
1620
            tree_t a = tree_assoc(value, i);
599✔
1621
            switch (tree_subkind(a)) {
599✔
1622
            case A_NAMED:
×
1623
               if (rebase_index(type, 0, assume_int(tree_name(a))) == depth)
×
1624
                  return assume_int(tree_value(a));
×
1625
               break;
1626

1627
            case A_POS:
23✔
1628
               if (pos++ == (unsigned)depth)
23✔
1629
                  return assume_int(tree_value(a));
13✔
1630
               break;
1631

1632
            case A_CONCAT:
480✔
1633
               {
1634
                  tree_t left = tree_value(a);
480✔
1635

1636
                  type_t left_type = tree_type(left);
480✔
1637
                  if (type_is_unconstrained(left_type))
480✔
1638
                     fatal_at(tree_loc(left), "sorry, this expression is not "
×
1639
                              "currently supported in a case choice");
1640

1641
                  tree_t lr = range_of(tree_type(left), 0);
480✔
1642
                  int64_t left_len;
480✔
1643
                  if (!folded_length(lr, &left_len))
480✔
1644
                     fatal_at(tree_loc(left), "cannot determine length of "
×
1645
                              "aggregate element");
1646

1647
                  if (depth < pos + left_len)
480✔
1648
                     return get_case_choice_char(left, depth - pos);
320✔
1649

1650
                  pos += left_len;
160✔
1651
               }
1652
               break;
160✔
1653

1654
            case A_OTHERS:
×
1655
               return assume_int(tree_value(a));
×
1656

1657
            case A_SLICE:
96✔
1658
               {
1659
                  tree_t base = tree_value(a);
96✔
1660
                  tree_t r = tree_range(a, 0);
96✔
1661

1662
                  const int64_t rleft = assume_int(tree_left(r));
96✔
1663
                  const int64_t rright = assume_int(tree_right(r));
96✔
1664

1665
                  const int64_t loffset = rebase_index(type, 0, rleft);
96✔
1666
                  const int64_t roffset = rebase_index(type, 0, rright);
96✔
1667

1668
                  if (depth >= loffset && depth <= roffset)
96✔
1669
                     return get_case_choice_char(base, depth - loffset);
64✔
1670
               }
1671
            }
1672
         }
1673

1674
         // This will produce an error during bounds checking
1675
         return ~0;
1676
      }
1677

1678
   case T_REF:
716✔
1679
      {
1680
         tree_t decl = tree_ref(value);
716✔
1681
         assert(tree_kind(decl) == T_CONST_DECL || tree_kind(decl) == T_ALIAS);
716✔
1682
         assert(tree_has_value(decl));
716✔
1683
         return get_case_choice_char(tree_value(decl), depth);
716✔
1684
      }
1685

1686
   case T_ARRAY_SLICE:
320✔
1687
      {
1688
         tree_t base = tree_value(value);
320✔
1689
         tree_t r = tree_range(value, 0);
320✔
1690
         const int64_t rleft = assume_int(tree_left(r));
320✔
1691
         const int64_t offset = rebase_index(tree_type(base), 0, rleft);
320✔
1692
         return get_case_choice_char(base, depth + offset);
320✔
1693
      }
1694

1695
   default:
×
1696
      fatal_at(tree_loc(value), "unsupported tree type %s in case choice",
×
1697
               tree_kind_str(tree_kind(value)));
1698
   }
1699
}
1700

1701
int64_t encode_case_choice(tree_t value, int length, int bits)
1,800✔
1702
{
1703
   uint64_t enc = 0;
1,800✔
1704
   for (int i = 0; i < length; i++) {
13,963✔
1705
      if (bits > 0) {
12,163✔
1706
         enc <<= bits;
3,816✔
1707
         enc |= get_case_choice_char(value, i);
3,816✔
1708
      }
1709
      else {
1710
         enc *= 0x27d4eb2d;
8,347✔
1711
         enc += get_case_choice_char(value, i);
8,347✔
1712
      }
1713
   }
1714

1715
   return enc;
1,800✔
1716
}
1717

1718
void to_string(text_buf_t *tb, type_t type, int64_t value)
699✔
1719
{
1720
   if (type_is_integer(type))
699✔
1721
      tb_printf(tb, "%"PRIi64, value);
532✔
1722
   else if (type_is_enum(type)) {
167✔
1723
      type_t base = type_base_recur(type);
70✔
1724
      if (value < 0 || value >= type_enum_literals(base))
70✔
1725
         tb_printf(tb, "%"PRIi64, value);
4✔
1726
      else
1727
         tb_cat(tb, istr(tree_ident(type_enum_literal(base, value))));
66✔
1728
   }
1729
   else if (type_is_physical(type)) {
97✔
1730
      type_t base = type_base_recur(type);
27✔
1731
      const unsigned nunits = type_units(base);
27✔
1732
      tree_t max_unit = NULL;
27✔
1733
      int64_t max_unit_value = 0;
27✔
1734

1735
      // Find the largest unit that evenly divides the given value
1736
      for (unsigned u = 0; u < nunits; u++) {
243✔
1737
         tree_t unit = type_unit(base, u);
216✔
1738
         const int64_t unit_value = assume_int(tree_value(unit));
216✔
1739
         if ((unit_value > max_unit_value) && (value % unit_value == 0)) {
216✔
1740
            max_unit = unit;
100✔
1741
            max_unit_value = unit_value;
100✔
1742
         }
1743
      }
1744
      assert(max_unit);
27✔
1745

1746
      tb_printf(tb, "%"PRIi64" %s", value / max_unit_value,
27✔
1747
                istr(tree_ident(max_unit)));
1748
   }
1749
   else if (type_is_real(type)) {
70✔
1750
      union { int64_t i; double r; } u = { .i = value };
62✔
1751
      tb_printf(tb, "%.17g", u.r);
62✔
1752
   }
1753
   else if (type_is_access(type)) {
8✔
1754
      if (value == 0)
8✔
1755
         tb_cat(tb, "NULL");
4✔
1756
      else
1757
         tb_printf(tb, "%p", (void *)value);
4✔
1758
   }
1759
}
699✔
1760

1761
static bool is_static(tree_t expr)
8,079✔
1762
{
1763
   switch (tree_kind(expr)) {
8,192✔
1764
   case T_REF:
934✔
1765
      {
1766
         tree_t decl = tree_ref(expr);
934✔
1767
         switch (tree_kind(decl)) {
934✔
1768
         case T_CONST_DECL:
224✔
1769
            return !!(tree_flags(decl) & TREE_F_GLOBALLY_STATIC);
224✔
1770
         case T_UNIT_DECL:
1771
         case T_ENUM_LIT:
1772
         case T_GENERIC_DECL:
1773
            return true;
1774
         case T_ALIAS:
×
1775
            return is_static(tree_value(decl));
×
1776
         default:
258✔
1777
            return false;
258✔
1778
         }
1779
      }
1780

1781
   case T_LITERAL:
1782
   case T_STRING:
1783
      return true;
1784

1785
   case T_FCALL:
530✔
1786
      return !!(tree_flags(expr) & (TREE_F_LOCALLY_STATIC
530✔
1787
                                    | TREE_F_GLOBALLY_STATIC));
1788

1789
   case T_RECORD_REF:
109✔
1790
      return is_static(tree_value(expr));
109✔
1791

1792
   case T_ARRAY_REF:
80✔
1793
      {
1794
         if (!is_static(tree_value(expr)))
80✔
1795
            return false;
1796

1797
         const int nparams = tree_params(expr);
80✔
1798
         for (int i = 0; i < nparams; i++) {
160✔
1799
            if (!is_static(tree_value(tree_param(expr, i))))
80✔
1800
               return false;
1801
         }
1802

1803
         return true;
1804
      }
1805

1806
   case T_ARRAY_SLICE:
40✔
1807
      {
1808
         if (!is_static(tree_value(expr)))
40✔
1809
            return false;
1810

1811
         assert(tree_ranges(expr) == 1);
40✔
1812

1813
         tree_t r = tree_range(expr, 0);
40✔
1814
         if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
40✔
1815
            return false;
×
1816

1817
         return true;
1818
      }
1819

1820
   case T_ATTR_REF:
24✔
1821
      {
1822
         switch (tree_subkind(expr)) {
24✔
1823
         case ATTR_EVENT:
1824
         case ATTR_ACTIVE:
1825
         case ATTR_LAST_EVENT:
1826
         case ATTR_LAST_ACTIVE:
1827
         case ATTR_LAST_VALUE:
1828
         case ATTR_DRIVING:
1829
         case ATTR_DRIVING_VALUE:
1830
         case ATTR_STABLE:
1831
         case ATTR_QUIET:
1832
            return false;
1833
         case ATTR_POS:
4✔
1834
         case ATTR_VAL:
1835
         case ATTR_LEFTOF:
1836
         case ATTR_RIGHTOF:
1837
         case ATTR_SUCC:
1838
         case ATTR_PRED:
1839
         case ATTR_VALUE:
1840
         case ATTR_IMAGE:
1841
            assert(tree_params(expr) == 1);
4✔
1842
            return is_static(tree_value(tree_param(expr, 0)));
4✔
1843
         case ATTR_LENGTH:
20✔
1844
         case ATTR_LEFT:
1845
         case ATTR_RIGHT:
1846
         case ATTR_LOW:
1847
         case ATTR_HIGH:
1848
            {
1849
               tree_t ref = name_to_ref(tree_name(expr));
20✔
1850
               if (ref == NULL)
20✔
1851
                  return false;
1852

1853
               switch (tree_kind(tree_ref(ref))) {
20✔
1854
               case T_GENERIC_DECL:
1855
               case T_PORT_DECL:
1856
               case T_SIGNAL_DECL:
1857
                  return true;
1858
               default:
3✔
1859
                  return false;
3✔
1860
               }
1861
            }
1862
         default:
×
1863
            return true;
×
1864
         }
1865
      }
1866

1867
   default:
×
1868
      return false;
×
1869
   }
1870
}
1871

1872
tree_t longest_static_prefix(tree_t expr)
30,631✔
1873
{
1874
   switch (tree_kind(expr)) {
30,631✔
1875
   case T_ARRAY_REF:
5,595✔
1876
      {
1877
         tree_t value = tree_value(expr);
5,595✔
1878
         tree_t prefix = longest_static_prefix(value);
5,595✔
1879

1880
         if (prefix != value)
5,595✔
1881
            return prefix;
1882

1883
         const int nparams = tree_params(expr);
5,558✔
1884
         for (int i = 0; i < nparams; i++) {
11,358✔
1885
            if (!is_static(tree_value(tree_param(expr, i))))
6,126✔
1886
               return prefix;
1887
         }
1888

1889
         return expr;
1890
      }
1891

1892
   case T_ARRAY_SLICE:
861✔
1893
      {
1894
         tree_t value = tree_value(expr);
861✔
1895
         tree_t prefix = longest_static_prefix(value);
861✔
1896

1897
         if (prefix != value)
861✔
1898
            return prefix;
1899

1900
         assert(tree_ranges(expr) == 1);
852✔
1901

1902
         tree_t r = tree_range(expr, 0);
852✔
1903
         if (tree_subkind(r) == RANGE_EXPR)
852✔
1904
            return prefix;
1905
         else if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
845✔
1906
            return prefix;
20✔
1907

1908
         return expr;
1909
      }
1910

1911
   case T_RECORD_REF:
1,539✔
1912
      {
1913
         tree_t value = tree_value(expr);
1,539✔
1914
         tree_t prefix = longest_static_prefix(value);
1,539✔
1915

1916
         if (prefix != value)
1,539✔
1917
            return prefix;
28✔
1918

1919
         return expr;
1920
      }
1921

1922
   default:
1923
      return expr;
1924
   }
1925
}
1926

1927
tree_t body_of(tree_t pack)
14,241✔
1928
{
1929
   const tree_kind_t kind = tree_kind(pack);
14,241✔
1930
   if (kind == T_PACK_INST)
14,241✔
1931
      return NULL;
1932

1933
   assert(tree_kind(pack) == T_PACKAGE);
14,241✔
1934

1935
   ident_t body_i = well_known(W_BODY);
14,241✔
1936
   ident_t body_name = ident_prefix(tree_ident(pack), body_i, '-');
14,241✔
1937
   return lib_get_qualified(body_name);
14,241✔
1938
}
1939

1940
tree_t find_generic_map(tree_t unit, int pos, tree_t g)
758✔
1941
{
1942
   const int ngenmaps = tree_genmaps(unit);
758✔
1943

1944
   if (pos < ngenmaps) {
758✔
1945
      tree_t m = tree_genmap(unit, pos);
582✔
1946
      if (tree_subkind(m) == P_POS && tree_pos(m) == pos)
582✔
1947
         return tree_value(m);
395✔
1948
   }
1949

1950
   for (int j = 0; j < ngenmaps; j++) {
1,295✔
1951
      tree_t m = tree_genmap(unit, j);
1,119✔
1952
      switch (tree_subkind(m)) {
1,119✔
1953
      case P_NAMED:
569✔
1954
         {
1955
            tree_t name = tree_name(m);
569✔
1956
            assert(tree_kind(name) == T_REF);
569✔
1957

1958
            if (tree_has_ref(name) && tree_ref(name) == g)
569✔
1959
               return tree_value(m);
19✔
1960
         }
1961
         break;
1962

1963
      case P_POS:
550✔
1964
         if (tree_pos(m) == pos)
550✔
1965
            return tree_value(m);
168✔
1966
         break;
1967

1968
      default:
1969
         break;
1970
      }
1971
   }
1972

1973
   return NULL;
1974
}
1975

1976
bool relaxed_rules(void)
710,615✔
1977
{
1978
   return opt_get_int(OPT_RELAXED);
710,615✔
1979
}
1980

1981
bool is_type_attribute(attr_kind_t kind)
79,846✔
1982
{
1983
   switch (kind) {
79,846✔
1984
   case ATTR_SUBTYPE:
1985
   case ATTR_BASE:
1986
   case ATTR_ELEMENT:
1987
   case ATTR_DESIGNATED_SUBTYPE:
1988
   case ATTR_INDEX:
1989
      return true;
1990
   default:
79,028✔
1991
      return false;
79,028✔
1992
   }
1993
}
1994

1995
bool attribute_has_param(attr_kind_t attr)
26,566✔
1996
{
1997
   switch (attr) {
26,566✔
1998
   case ATTR_IMAGE:
1999
   case ATTR_SUCC:
2000
   case ATTR_PRED:
2001
   case ATTR_DELAYED:
2002
   case ATTR_LEFTOF:
2003
   case ATTR_RIGHTOF:
2004
   case ATTR_VALUE:
2005
   case ATTR_POS:
2006
   case ATTR_LOW:
2007
   case ATTR_HIGH:
2008
   case ATTR_LEFT:
2009
   case ATTR_RIGHT:
2010
   case ATTR_LENGTH:
2011
   case ATTR_RANGE:
2012
   case ATTR_REVERSE_RANGE:
2013
   case ATTR_VAL:
2014
   case ATTR_QUIET:
2015
   case ATTR_STABLE:
2016
   case ATTR_INDEX:
2017
   case ATTR_ASCENDING:
2018
      return true;
2019
   default:
2,709✔
2020
      return false;
2,709✔
2021
   }
2022
}
2023

2024
type_t get_type_or_null(tree_t t)
2,729,457✔
2025
{
2026
   switch (tree_kind(t)) {
2,729,457✔
2027
   case T_LIBRARY:
2028
   case T_ATTR_SPEC:
2029
   case T_PACKAGE:
2030
   case T_PACK_INST:
2031
   case T_PACK_BODY:
2032
   case T_ENTITY:
2033
   case T_ARCH:
2034
   case T_PROCESS:
2035
   case T_COMPONENT:
2036
   case T_INSTANCE:
2037
   case T_CONCURRENT:
2038
   case T_BLOCK:
2039
   case T_WHILE:
2040
   case T_FOR:
2041
   case T_LOOP:
2042
   case T_GROUP_TEMPLATE:
2043
   case T_CONFIGURATION:
2044
   case T_GROUP:
2045
   case T_FOR_GENERATE:
2046
   case T_IF_GENERATE:
2047
   case T_CASE_GENERATE:
2048
   case T_USE:
2049
   case T_CONTEXT:
2050
   case T_PSL_DECL:
2051
   case T_PSL_DIRECT:
2052
   case T_WAVEFORM:
2053
      return NULL;
2054
   default:
2,615,194✔
2055
      if (tree_has_type(t))
2,615,194✔
2056
         return tree_type(t);
2,613,458✔
2057
      else
2058
         return NULL;
2059
   }
2060
}
2061

2062
type_t subtype_for_string(tree_t str, type_t base)
31,427✔
2063
{
2064
   if (type_const_bounds(base))
31,427✔
2065
      return base;    // Can be checked statically
2066
   else if (!type_is_unconstrained(base))
27,460✔
2067
      base = type_base_recur(base);
188✔
2068

2069
   // Construct a new constrained array subtype: the direction and
2070
   // bounds are the same as those for a positional array aggregate
2071
   type_t sub = type_new(T_SUBTYPE);
27,460✔
2072
   type_set_base(sub, base);
27,460✔
2073

2074
   type_t index_type = index_type_of(base, 0);
27,460✔
2075
   const bool is_enum = type_is_enum(index_type);
27,460✔
2076

2077
   // The direction is determined by the index type
2078
   range_kind_t dir = direction_of(index_type, 0);
27,460✔
2079
   tree_t index_r = range_of(index_type, 0);
27,460✔
2080

2081
   // The left bound is the left of the index type and the right bound
2082
   // is determined by the number of elements
2083

2084
   tree_t left = NULL, right = NULL;
27,460✔
2085
   const int nchars = tree_chars(str);
27,460✔
2086

2087
   if (is_enum) {
27,460✔
2088
      const int nlits = type_enum_literals(type_base_recur(index_type));
14✔
2089
      int64_t index_left = assume_int(tree_left(index_r));
14✔
2090

2091
      int64_t iright, ileft;
14✔
2092
      if (nchars == 0) {
14✔
2093
         iright = index_left;
1✔
2094
         ileft = assume_int(tree_right(index_r));
1✔
2095
      }
2096
      else if (dir == RANGE_DOWNTO) {
13✔
2097
         ileft = index_left;
×
2098
         iright = MIN(nlits - 1, MAX(0, index_left - nchars + 1));
×
2099
      }
2100
      else {
2101
         ileft = index_left;
13✔
2102
         iright = MIN(nlits - 1, MAX(0, index_left + nchars - 1));
13✔
2103
      }
2104

2105
      left = get_enum_lit(str, index_type, ileft);
14✔
2106
      right = get_enum_lit(str, index_type, iright);
14✔
2107
   }
2108
   else {
2109
      left = tree_left(index_r);
27,446✔
2110

2111
      int64_t iright;
27,446✔
2112
      if (dir == RANGE_DOWNTO)
27,446✔
2113
         iright = assume_int(left) - nchars + 1;
×
2114
      else
2115
         iright = assume_int(left) + nchars - 1;
27,446✔
2116

2117
      right = get_int_lit(str, index_type, iright);
27,446✔
2118
   }
2119

2120
   tree_t r = tree_new(T_RANGE);
27,460✔
2121
   tree_set_subkind(r, dir);
27,460✔
2122
   tree_set_left(r, left);
27,460✔
2123
   tree_set_right(r, right);
27,460✔
2124
   tree_set_loc(r, tree_loc(str));
27,460✔
2125
   tree_set_type(r, index_type);
27,460✔
2126

2127
   tree_t c = tree_new(T_CONSTRAINT);
27,460✔
2128
   tree_set_subkind(c, C_INDEX);
27,460✔
2129
   tree_add_range(c, r);
27,460✔
2130
   tree_set_loc(c, tree_loc(str));
27,460✔
2131

2132
   type_set_constraint(sub, c);
27,460✔
2133

2134
   return sub;
27,460✔
2135
}
2136

2137
tree_t change_ref(tree_t name, tree_t new)
2,630✔
2138
{
2139
   switch (tree_kind(name)) {
2,630✔
2140
   case T_REF:
1,752✔
2141
      return make_ref(new);
1,752✔
2142

2143
   case T_ARRAY_REF:
130✔
2144
      {
2145
         tree_t value = change_ref(tree_value(name), new);
130✔
2146

2147
         tree_t t = tree_new(T_ARRAY_REF);
130✔
2148
         tree_set_loc(t, tree_loc(name));
130✔
2149
         tree_set_value(t, value);
130✔
2150
         tree_set_type(t, type_elem(tree_type(value)));
130✔
2151

2152
         const int nparams = tree_params(name);
130✔
2153
         for (int i = 0; i < nparams; i++)
260✔
2154
            tree_add_param(t, tree_param(name, i));
130✔
2155

2156
         return t;
2157
      }
2158

2159
   case T_ARRAY_SLICE:
61✔
2160
      {
2161
         tree_t value = change_ref(tree_value(name), new);
61✔
2162
         tree_t r = tree_range(name, 0);
61✔
2163

2164
         tree_t constraint = tree_new(T_CONSTRAINT);
61✔
2165
         tree_set_subkind(constraint, C_INDEX);
61✔
2166
         tree_add_range(constraint, r);
61✔
2167

2168
         type_t slice_type = type_new(T_SUBTYPE);
61✔
2169
         type_set_constraint(slice_type, constraint);
61✔
2170
         type_set_base(slice_type, tree_type(value));
61✔
2171

2172
         tree_t t = tree_new(T_ARRAY_SLICE);
61✔
2173
         tree_set_loc(t, tree_loc(name));
61✔
2174
         tree_set_value(t, value);
61✔
2175
         tree_set_type(t, slice_type);
61✔
2176
         tree_add_range(t, r);
61✔
2177

2178
         return t;
61✔
2179
      }
2180

2181
   case T_RECORD_REF:
518✔
2182
      {
2183
         tree_t t = tree_new(T_RECORD_REF);
518✔
2184
         tree_set_loc(t, tree_loc(name));
518✔
2185
         tree_set_value(t, change_ref(tree_value(name), new));
518✔
2186
         tree_set_type(t, tree_type(name));
518✔
2187
         tree_set_ident(t, tree_ident(name));
518✔
2188
         tree_set_ref(t, tree_ref(name));
518✔
2189

2190
         return t;
518✔
2191
      }
2192

2193
   case T_CONV_FUNC:
157✔
2194
      {
2195
         tree_t t = tree_new(T_CONV_FUNC);
157✔
2196
         tree_set_loc(t, tree_loc(name));
157✔
2197
         tree_set_value(t, change_ref(tree_value(name), new));
157✔
2198
         tree_set_ident(t, tree_ident(name));
157✔
2199
         tree_set_type(t, tree_type(name));
157✔
2200
         tree_set_ref(t, tree_ref(name));
157✔
2201

2202
         return t;
157✔
2203
      }
2204

2205
   case T_TYPE_CONV:
12✔
2206
      {
2207
         tree_t t = tree_new(T_TYPE_CONV);
12✔
2208
         tree_set_loc(t, tree_loc(name));
12✔
2209
         tree_set_type(t, tree_type(name));
12✔
2210
         tree_set_value(t, change_ref(tree_value(name), new));
12✔
2211

2212
         return t;
12✔
2213
      }
2214

2215
   default:
×
2216
      fatal_trace("cannot handle tree kind %s in elab_change_ref",
2217
                  tree_kind_str(tree_kind(name)));
2218
   }
2219
}
2220

2221
static void build_wait_for_target(tree_t expr, build_wait_fn_t fn, void *ctx)
3,873✔
2222
{
2223
   switch (tree_kind(expr)) {
3,873✔
2224
   case T_ARRAY_SLICE:
101✔
2225
      build_wait(tree_range(expr, 0), fn, ctx);
101✔
2226
      break;
101✔
2227

2228
   case T_ARRAY_REF:
751✔
2229
      {
2230
         const int nparams = tree_params(expr);
751✔
2231
         for (int i = 0; i < nparams; i++)
1,502✔
2232
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
751✔
2233
      }
2234
      break;
2235

2236
   default:
2237
      break;
2238
   }
2239
}
3,873✔
2240

2241
void build_wait(tree_t expr, build_wait_fn_t fn, void *ctx)
17,990✔
2242
{
2243
   // LRM 08 section 10.2 has rules for building a wait statement from a
2244
   // sensitivity list. LRM 08 section 11.3 extends these rules to
2245
   // all-sensitised processes.
2246

2247
   switch (tree_kind(expr)) {
22,377✔
2248
   case T_REF:
5,719✔
2249
      if (class_of(tree_ref(expr)) == C_SIGNAL)
5,719✔
2250
         (*fn)(expr, ctx);
3,290✔
2251
      break;
2252

2253
   case T_EXTERNAL_NAME:
9✔
2254
      if (tree_class(expr) == C_SIGNAL)
9✔
2255
         (*fn)(expr, ctx);
9✔
2256
      break;
2257

2258
   case T_WAVEFORM:
3,795✔
2259
   case T_QUALIFIED:
2260
   case T_TYPE_CONV:
2261
   case T_INERTIAL:
2262
      if (tree_has_value(expr))
3,795✔
2263
         build_wait(tree_value(expr), fn, ctx);
3,783✔
2264
      break;
2265

2266
   case T_ASSERT:
529✔
2267
      build_wait(tree_value(expr), fn, ctx);
529✔
2268
      // Fall-through
2269
   case T_REPORT:
534✔
2270
      if (tree_has_message(expr))
534✔
2271
         build_wait(tree_message(expr), fn, ctx);
371✔
2272
      break;
2273

2274
   case T_ARRAY_REF:
1,068✔
2275
   case T_ARRAY_SLICE:
2276
   case T_RECORD_REF:
2277
      {
2278
         tree_t ref = name_to_ref(expr);
1,068✔
2279
         if (ref != NULL && class_of(ref) == C_SIGNAL
1,068✔
2280
             && longest_static_prefix(expr) == expr)
680✔
2281
            (*fn)(expr, ctx);
581✔
2282
         else {
2283
            build_wait(tree_value(expr), fn, ctx);
487✔
2284
            build_wait_for_target(expr, fn, ctx);
487✔
2285
         }
2286
      }
2287
      break;
2288

2289
   case T_FCALL:
2,579✔
2290
   case T_PCALL:
2291
   case T_PROT_FCALL:
2292
   case T_PROT_PCALL:
2293
      {
2294
         tree_t decl = tree_ref(expr);
2,579✔
2295
         const int nparams = tree_params(expr);
2,579✔
2296
         for (int i = 0; i < nparams; i++) {
7,030✔
2297
            tree_t p = tree_param(expr, i), port;
4,451✔
2298
            switch (tree_subkind(p)) {
4,451✔
2299
            case P_POS:
4,451✔
2300
               port = tree_port(decl, tree_pos(p));
4,451✔
2301
               break;
4,451✔
2302
            case P_NAMED:
×
2303
               port = tree_ref(name_to_ref(tree_name(p)));
×
2304
               break;
×
2305
            default:
×
2306
               should_not_reach_here();
2307
            }
2308
            assert(tree_kind(port) == T_PARAM_DECL);
4,451✔
2309

2310
            switch (tree_subkind(port)) {
4,451✔
2311
            case PORT_IN:
4,442✔
2312
            case PORT_INOUT:
2313
            case PORT_ARRAY_VIEW:
2314
            case PORT_RECORD_VIEW:
2315
               build_wait(tree_value(p), fn, ctx);
4,442✔
2316
               break;
4,442✔
2317
            default:
2318
               break;
2319
            }
2320
         }
2321
      }
2322
      break;
2323

2324
   case T_AGGREGATE:
464✔
2325
      {
2326
         const int nassocs = tree_assocs(expr);
464✔
2327
         for (int i = 0; i < nassocs; i++) {
1,729✔
2328
            tree_t a = tree_assoc(expr, i);
1,265✔
2329
            build_wait(tree_value(a), fn, ctx);
1,265✔
2330

2331
            switch (tree_subkind(a)) {
1,265✔
2332
            case A_RANGE:
70✔
2333
            case A_SLICE:
2334
               build_wait(tree_range(a, 0), fn, ctx);
70✔
2335
               break;
70✔
2336
            case A_NAMED:
88✔
2337
               build_wait(tree_name(a), fn, ctx);
88✔
2338
               break;
88✔
2339
            }
2340
         }
2341
      }
2342
      break;
2343

2344
   case T_ATTR_REF:
453✔
2345
      {
2346
         const attr_kind_t predef = tree_subkind(expr);
453✔
2347
         if (predef == ATTR_EVENT || predef == ATTR_ACTIVE)
453✔
2348
            build_wait(tree_name(expr), fn, ctx);
198✔
2349

2350
         const int nparams = tree_params(expr);
453✔
2351
         for (int i = 0; i < nparams; i++)
475✔
2352
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
22✔
2353
      }
2354
      break;
2355

2356
   case T_LITERAL:
2357
   case T_STRING:
2358
   case T_DUMMY_DRIVER:
2359
      break;
2360

2361
   case T_IF:
298✔
2362
      {
2363
         const int nconds = tree_conds(expr);
298✔
2364
         for (int i = 0; i < nconds; i++)
822✔
2365
            build_wait(tree_cond(expr, i), fn, ctx);
524✔
2366
      }
2367
      break;
2368

2369
   case T_COND_STMT:
528✔
2370
      {
2371
         if (tree_has_value(expr))
528✔
2372
            build_wait(tree_value(expr), fn, ctx);
350✔
2373

2374
         const int nstmts = tree_stmts(expr);
528✔
2375
         for (int i = 0; i < nstmts; i++)
1,058✔
2376
            build_wait(tree_stmt(expr, i), fn, ctx);
530✔
2377
      }
2378
      break;
2379

2380
   case T_COND_VALUE:
4✔
2381
      {
2382
         const int nconds = tree_conds(expr);
4✔
2383
         for (int i = 0; i < nconds; i++)
16✔
2384
            build_wait(tree_cond(expr, i), fn, ctx);
12✔
2385
         break;
2386
      }
2387

2388
   case T_COND_EXPR:
12✔
2389
      {
2390
         if (tree_has_value(expr))
12✔
2391
            build_wait(tree_value(expr), fn, ctx);
8✔
2392

2393
         build_wait(tree_result(expr), fn, ctx);
12✔
2394
         break;
12✔
2395
      }
2396

2397
   case T_PROCESS:
64✔
2398
   case T_SEQUENCE:
2399
   case T_PROC_BODY:
2400
      {
2401
         const int ndecls = tree_decls(expr);
64✔
2402
         for (int i = 0; i < ndecls; i++) {
87✔
2403
            tree_t d = tree_decl(expr, i);
23✔
2404
            if (tree_kind(d) == T_PROC_BODY)
23✔
2405
               build_wait(d, fn, ctx);
2✔
2406
         }
2407

2408
         const int nstmts = tree_stmts(expr);
64✔
2409
         for (int i = 0; i < nstmts; i++)
147✔
2410
            build_wait(tree_stmt(expr, i), fn, ctx);
83✔
2411
      }
2412
      break;
2413

2414
   case T_SIGNAL_ASSIGN:
3,361✔
2415
      {
2416
         build_wait_for_target(tree_target(expr), fn, ctx);
3,361✔
2417

2418
         const int nwaves = tree_waveforms(expr);
3,361✔
2419
         for (int i = 0; i < nwaves; i++)
6,953✔
2420
            build_wait(tree_waveform(expr, i), fn, ctx);
3,592✔
2421
      }
2422
      break;
2423

2424
   case T_VAR_ASSIGN:
21✔
2425
   case T_FORCE:
2426
      build_wait_for_target(tree_target(expr), fn, ctx);
21✔
2427
      build_wait(tree_value(expr), fn, ctx);
21✔
2428
      break;
21✔
2429

2430
   case T_RELEASE:
4✔
2431
      build_wait_for_target(tree_target(expr), fn, ctx);
4✔
2432
      break;
4✔
2433

2434
   case T_CASE:
59✔
2435
   case T_MATCH_CASE:
2436
      {
2437
         build_wait(tree_value(expr), fn, ctx);
59✔
2438

2439
         const int nstmts = tree_stmts(expr);
59✔
2440
         for (int i = 0; i < nstmts; i++) {
365✔
2441
            tree_t alt = tree_stmt(expr, i);
306✔
2442

2443
            const int nstmts = tree_stmts(alt);
306✔
2444
            for (int j = 0; j < nstmts; j++)
612✔
2445
               build_wait(tree_stmt(alt, j), fn, ctx);
306✔
2446
         }
2447
      }
2448
      break;
2449

2450
   case T_FOR:
21✔
2451
      {
2452
         build_wait(tree_range(expr, 0), fn, ctx);
21✔
2453

2454
         const int nstmts = tree_stmts(expr);
21✔
2455
         for (int i = 0; i < nstmts; i++)
46✔
2456
            build_wait(tree_stmt(expr, i), fn, ctx);
25✔
2457
      }
2458
      break;
2459

2460
   case T_WHILE:
1✔
2461
      build_wait(tree_value(expr), fn, ctx);
1✔
2462
      // Fall-through
2463
   case T_LOOP:
5✔
2464
      {
2465
         const int nstmts = tree_stmts(expr);
5✔
2466
         for (int i = 0; i < nstmts; i++)
26✔
2467
            build_wait(tree_stmt(expr, i), fn, ctx);
21✔
2468
      }
2469
      break;
2470

2471
   case T_NEXT:
12✔
2472
   case T_EXIT:
2473
      if (tree_has_value(expr))
12✔
2474
         build_wait(tree_value(expr), fn, ctx);
8✔
2475
      break;
2476

2477
   case T_RANGE:
192✔
2478
      if (tree_subkind(expr) == RANGE_EXPR)
192✔
2479
         build_wait(tree_value(expr), fn, ctx);
14✔
2480
      else {
2481
         build_wait(tree_left(expr), fn, ctx);
178✔
2482
         build_wait(tree_right(expr), fn, ctx);
178✔
2483
      }
2484
      break;
2485

2486
   case T_OPEN:
2487
      break;
2488

2489
   default:
×
2490
      fatal_trace("Cannot handle tree kind %s in wait expression",
2491
                  tree_kind_str(tree_kind(expr)));
2492
   }
2493
}
17,990✔
2494

2495
void print_syntax(const char *fmt, ...)
2,035✔
2496
{
2497
   LOCAL_TEXT_BUF tb = tb_new();
2,035✔
2498
   bool highlighting = false;
2,035✔
2499
   static bool comment = false, last_was_newline = false;
2,035✔
2500
   for (const char *p = fmt; *p != '\0'; p++) {
10,698✔
2501
      if (comment) {
8,663✔
2502
         if (*p == '\n' || *p == '\r') {
3,166✔
2503
            comment = false;
94✔
2504
            last_was_newline = true;
94✔
2505
            tb_printf(tb, "$$\n");
94✔
2506
         }
2507
         else if (*p != '~' && *p != '#') {
3,072✔
2508
            tb_append(tb, *p);
2,912✔
2509
            last_was_newline = false;
2,912✔
2510
         }
2511
         if (p > fmt && *p == '/' && *(p - 1) == '*') {
3,166✔
2512
            tb_printf(tb, "$$");
10✔
2513
            comment = false;
10✔
2514
            last_was_newline = false;
10✔
2515
         }
2516
      }
2517
      else if (*p == '\r') {
5,497✔
2518
         if (!last_was_newline) {
21✔
2519
            tb_append(tb, '\n');
×
2520
            last_was_newline = true;
×
2521
         }
2522
      }
2523
      else if (*p == '#' && *(p + 1) != '#') {
5,476✔
2524
         tb_printf(tb, "$bold$$cyan$");
367✔
2525
         last_was_newline = false;
367✔
2526
         highlighting = true;
367✔
2527
      }
2528
      else if (*p == '~' && *(p + 1) != '~') {
5,109✔
2529
         tb_printf(tb, "$yellow$");
1✔
2530
         last_was_newline = false;
1✔
2531
         highlighting = true;
1✔
2532
      }
2533
      else if ((*p == '-' && *(p + 1) == '-')
5,108✔
2534
               || (*p == '/' && *(p + 1) == '/')
5,018✔
2535
               || (*p == '/' && *(p + 1) == '*')) {
5,014✔
2536
         tb_printf(tb, "$red$%c", *p);
104✔
2537
         last_was_newline = false;
104✔
2538
         comment = true;
104✔
2539
      }
2540
      else if (!isalnum_iso88591(*p) && *p != '_'
5,004✔
2541
               && *p != '%' && highlighting) {
2,551✔
2542
         tb_printf(tb, "$$%c", *p);
314✔
2543
         last_was_newline = false;
314✔
2544
         highlighting = false;
314✔
2545
      }
2546
      else {
2547
         tb_append(tb, *p);
4,690✔
2548
         last_was_newline = (*p == '\n');
4,690✔
2549
      }
2550
   }
2551

2552
   if (highlighting)
2,035✔
2553
      tb_cat(tb, "$$");
54✔
2554

2555
   va_list ap;
2,035✔
2556
   va_start(ap, fmt);
2,035✔
2557

2558
   if (syntax_buf != NULL) {
2,035✔
2559
      char *stripped LOCAL = strip_color(tb_get(tb), ap);
4,070✔
2560
      tb_cat(syntax_buf, stripped);
2,035✔
2561
   }
2562
   else
2563
      color_vprintf(tb_get(tb), ap);
×
2564

2565
   va_end(ap);
2,035✔
2566
}
2,035✔
2567

2568
void capture_syntax(text_buf_t *tb)
9✔
2569
{
2570
   assert(tb == NULL || syntax_buf == NULL);
9✔
2571
   syntax_buf = tb;
9✔
2572
}
9✔
2573

2574
void analyse_file(const char *file, jit_t *jit, unit_registry_t *ur,
4,931✔
2575
                  mir_context_t *mc)
2576
{
2577
   input_from_file(file);
4,931✔
2578

2579
   switch (source_kind()) {
4,931✔
2580
   case SOURCE_VHDL:
4,733✔
2581
      {
2582
         lib_t work = lib_work();
4,733✔
2583
         int base_errors = 0;
4,733✔
2584
         tree_t unit;
4,733✔
2585
         while (base_errors = error_count(), (unit = parse())) {
18,350✔
2586
            if (error_count() == base_errors) {
13,617✔
2587
               lib_put(work, unit);
13,617✔
2588
               unit_registry_purge(ur, tree_ident(unit));
13,617✔
2589

2590
               simplify_local(unit, jit, ur, mc);
13,617✔
2591
               bounds_check(unit);
13,617✔
2592
            }
2593
            else
2594
               lib_put_error(work, unit);
×
2595
         }
2596
      }
2597
      break;
2598

2599
   case SOURCE_VERILOG:
198✔
2600
      {
2601
         LOCAL_TEXT_BUF tb = tb_new();
396✔
2602
         vlog_preprocess(tb, true);
198✔
2603

2604
         input_from_buffer(tb_get(tb), tb_len(tb), SOURCE_VERILOG);
198✔
2605

2606
         lib_t work = lib_work();
198✔
2607
         vlog_node_t module;
198✔
2608
         while ((module = vlog_parse())) {
631✔
2609
            if (error_count() == 0) {
235✔
2610
               vlog_check(module);
235✔
2611

2612
               if (error_count() == 0) {
235✔
2613
                  vlog_simp(module);
235✔
2614
                  lib_put_vlog(work, module);
235✔
2615
               }
2616
            }
2617
         }
2618
      }
2619
      break;
198✔
2620

2621
   case SOURCE_SDF:
×
2622
      {
2623
         sdf_file_t *sdf_file = sdf_parse(file, 0);
×
2624
         progress("analysed SDF file: %s", file);
×
2625

2626
         if (sdf_file != NULL) {
×
2627
            warnf("SDF is not yet supported");
×
2628
            sdf_file_free(sdf_file);
×
2629
         }
2630
      }
2631
      break;
2632
   }
2633
}
4,927✔
2634

2635
bool all_character_literals(type_t type)
18,865✔
2636
{
2637
   assert(type_is_enum(type));
18,865✔
2638

2639
   type_t base = type_base_recur(type);
18,865✔
2640
   const int nlits = type_enum_literals(base);
18,865✔
2641
   for (int i = 0; i < nlits; i++) {
90,847✔
2642
      if (ident_char(tree_ident(type_enum_literal(base, i)), 0) != '\'')
79,351✔
2643
         return false;
2644
   }
2645

2646
   return true;
2647
}
2648

2649
bool is_operator_symbol(ident_t ident)
30,167✔
2650
{
2651
   const int len = ident_len(ident);
30,167✔
2652
   if (len < 3)
30,167✔
2653
      return false;
2654
   else if (ident_char(ident, 0) != '"')
29,850✔
2655
      return false;
2656
   else if (ident_char(ident, len - 1) != '"')
16,390✔
2657
      return false;
2658

2659
   const well_known_t wk = is_well_known(ident);
16,390✔
2660

2661
   if (standard() < STD_08)
16,390✔
2662
      return wk >= W_OP_AND && wk <= W_OP_NOT;
3,304✔
2663
   else
2664
      return wk >= W_OP_AND && wk <= W_OP_MATCH_GREATER_EQUAL;
13,086✔
2665
}
2666

2667
bool same_tree(tree_t a, tree_t b)
9,925✔
2668
{
2669
   const tree_kind_t akind = tree_kind(a);
9,925✔
2670
   if (akind != tree_kind(b))
9,925✔
2671
      return false;
2672

2673
   switch (akind) {
9,769✔
2674
   case T_REF:
4,682✔
2675
      return tree_ref(a) == tree_ref(b);
4,682✔
2676
   case T_ARRAY_REF:
1,529✔
2677
      {
2678
         if (!same_tree(tree_value(a), tree_value(b)))
1,529✔
2679
            return false;
2680

2681
         const int nparams = tree_params(a);
1,500✔
2682
         assert(nparams == tree_params(b));
1,500✔
2683

2684
         for (int i = 0; i < nparams; i++) {
2,785✔
2685
            tree_t pa = tree_value(tree_param(a, i));
2,400✔
2686
            tree_t pb = tree_value(tree_param(b, i));
2,400✔
2687
            if (!same_tree(pa, pb))
2,400✔
2688
               return false;
2689
         }
2690

2691
         return true;
2692
      }
2693
   case T_ARRAY_SLICE:
51✔
2694
      {
2695
         if (!same_tree(tree_value(a), tree_value(b)))
51✔
2696
            return false;
2697

2698
         tree_t ra = tree_range(a, 0);
51✔
2699
         tree_t rb = tree_range(b, 0);
51✔
2700

2701
         const range_kind_t rakind = tree_subkind(ra);
51✔
2702
         if (rakind != tree_subkind(rb) || rakind == RANGE_EXPR)
51✔
2703
            return false;
2704

2705
         return same_tree(tree_left(ra), tree_left(rb))
51✔
2706
            && same_tree(tree_right(ra), tree_right(rb));
55✔
2707
      }
2708

2709
   case T_RECORD_REF:
1,007✔
2710
      return ident_casecmp(tree_ident(a), tree_ident(b))
1,007✔
2711
         && same_tree(tree_value(a), tree_value(b));
1,011✔
2712

2713
   case T_LITERAL:
2,496✔
2714
      {
2715
         const literal_kind_t alkind = tree_subkind(a);
2,496✔
2716
         if (alkind != tree_subkind(b) || alkind != L_INT)
2,496✔
2717
            return false;
2718
         else
2719
            return tree_ival(a) == tree_ival(b);
2,440✔
2720
      }
2721
   default:
2722
      return false;
2723
   }
2724
}
2725

2726
bool calculate_aggregate_bounds(tree_t expr, range_kind_t *kind,
8,505✔
2727
                                int64_t *left, int64_t *right)
2728
{
2729
   // Calculate the direction and bounds of an array aggregate using the
2730
   // rules in LRM 93 7.3.2.2
2731

2732
   type_t type = tree_type(expr);
8,505✔
2733
   type_t index_type = index_type_of(type, 0);
8,505✔
2734
   if (index_type == NULL || type_is_none(index_type))
8,505✔
2735
      return false;
1✔
2736

2737
   tree_t index_r = range_of(index_type, 0), base_r = index_r;
8,504✔
2738

2739
   int64_t low, high;
8,504✔
2740
   if (!folded_bounds(index_r, &low, &high))
8,504✔
2741
      return false;
2742

2743
   int64_t clow = INT64_MAX, chigh = INT64_MIN;  // Actual bounds computed below
8,484✔
2744

2745
   range_kind_t dir;
8,484✔
2746
   if (type_is_unconstrained(type))
8,484✔
2747
      dir = tree_subkind(index_r);
8,171✔
2748
   else {
2749
      base_r = range_of(type, 0);
313✔
2750
      dir = tree_subkind(base_r);
313✔
2751
   }
2752

2753
   const int nassocs = tree_assocs(expr);
8,484✔
2754

2755
   if (standard() >= STD_08) {
8,484✔
2756
      // VHDL-2008 range association determines index direction for
2757
      // unconstrained aggregate when the expression type matches the
2758
      // array type
2759
      for (int i = 0; i < nassocs; i++) {
16,810✔
2760
         tree_t a = tree_assoc(expr, i);
12,078✔
2761
         if (tree_subkind(a) == A_SLICE)
12,078✔
2762
            dir = tree_subkind(tree_range(a, 0));
71✔
2763
      }
2764
   }
2765

2766
   if (dir != RANGE_TO && dir != RANGE_DOWNTO)
8,484✔
2767
      return false;
2768

2769
   int64_t pos = 0;
2770
   for (int i = 0; i < nassocs; i++) {
24,189✔
2771
      tree_t a = tree_assoc(expr, i);
21,379✔
2772
      int64_t ilow = 0, ihigh = 0;
21,379✔
2773
      const assoc_kind_t akind = tree_subkind(a);
21,379✔
2774

2775
      switch (akind) {
21,379✔
2776
      case A_NAMED:
712✔
2777
         {
2778
            tree_t name = tree_name(a);
712✔
2779
            if (folded_int(name, &ilow))
712✔
2780
               ihigh = ilow;
699✔
2781
            else
2782
               return false;
5,630✔
2783
         }
2784
         break;
699✔
2785

2786
      case A_RANGE:
1,404✔
2787
      case A_SLICE:
2788
         {
2789
            tree_t r = tree_range(a, 0);
1,404✔
2790
            const range_kind_t rkind = tree_subkind(r);
1,404✔
2791
            if (rkind == RANGE_TO || rkind == RANGE_DOWNTO) {
1,404✔
2792
               tree_t left = tree_left(r), right = tree_right(r);
1,060✔
2793

2794
               int64_t ileft, iright;
1,060✔
2795
               if (folded_int(left, &ileft) && folded_int(right, &iright)) {
1,060✔
2796
                  ilow = (rkind == RANGE_TO ? ileft : iright);
544✔
2797
                  ihigh = (rkind == RANGE_TO ? iright : ileft);
544✔
2798
               }
2799
               else
2800
                  return false;
516✔
2801
            }
2802
            else
2803
               return false;
2804
         }
2805
         break;
2806

2807
      case A_OTHERS:
2808
         return false;
2809

2810
      case A_POS:
12,312✔
2811
         if (i == 0) {
12,312✔
2812
            int64_t ileft;
1,924✔
2813
            if (folded_int(tree_left(base_r), &ileft))
1,924✔
2814
               ilow = ihigh = ileft;
1,924✔
2815
            else
2816
               return false;
×
2817
         }
2818
         else if (dir == RANGE_TO)
10,388✔
2819
            ilow = ihigh = clow + pos;
10,386✔
2820
         else
2821
            ilow = ihigh = chigh - pos;
2✔
2822
         pos++;
12,312✔
2823
         break;
12,312✔
2824

2825
      case A_CONCAT:
6,937✔
2826
         {
2827
            type_t value_type = tree_type(tree_value(a));
6,937✔
2828

2829
            int64_t length;
6,937✔
2830
            if (type_is_unconstrained(value_type))
6,937✔
2831
               return false;
4,743✔
2832
            else if (folded_length(range_of(value_type, 0), &length)) {
2,577✔
2833
               if (i == 0) {
2,194✔
2834
                  int64_t ileft;
1,927✔
2835
                  if (folded_int(tree_left(base_r), &ileft))
1,927✔
2836
                     ilow = ihigh = ileft;
1,927✔
2837
                  else
2838
                     return false;
×
2839
               }
2840
               else if (dir == RANGE_TO) {
267✔
2841
                  ilow = clow + pos;
243✔
2842
                  ihigh = ilow + length - 1;
243✔
2843
               }
2844
               else {
2845
                  ihigh = chigh - pos;
24✔
2846
                  ilow = ihigh - length + 1;
24✔
2847
               }
2848
               pos += length;
2,194✔
2849
            }
2850
            else
2851
               return false;
2852
         }
2853
         break;
2854
      }
2855

2856
      clow = MIN(clow, ilow);
15,749✔
2857
      chigh = MAX(chigh, ihigh);
15,749✔
2858
   }
2859

2860
   if (clow < low || chigh > high)
2,810✔
2861
      return false;   // Will raise a bounds check error later
2862

2863
   *kind = dir;
2,805✔
2864
   *left = dir == RANGE_TO ? clow : chigh;
2,805✔
2865
   *right = dir == RANGE_TO ? chigh : clow;
2,805✔
2866

2867
   return true;
2,805✔
2868
}
2869

2870
type_t calculate_aggregate_subtype(tree_t expr)
7,010✔
2871
{
2872
   range_kind_t dir;
7,010✔
2873
   int64_t ileft, iright;
7,010✔
2874
   if (!calculate_aggregate_bounds(expr, &dir, &ileft, &iright))
7,010✔
2875
      return NULL;
2876

2877
   type_t type = tree_type(expr);
2,782✔
2878

2879
   const int ndims = dimension_of(type);
2,782✔
2880
   type_t a0_type = NULL;
2,782✔
2881
   if (ndims > 1) {
2,782✔
2882
      a0_type = tree_type(tree_value(tree_assoc(expr, 0)));
81✔
2883
      if (type_is_unconstrained(a0_type))
81✔
2884
         return NULL;
2885

2886
      assert(dimension_of(a0_type) == ndims - 1);
81✔
2887
   }
2888

2889
   type_t index_type = index_type_of(type, 0);
2,782✔
2890

2891
   tree_t left = get_discrete_lit(expr, index_type, ileft);
2,782✔
2892
   tree_t right = get_discrete_lit(expr, index_type, iright);
2,782✔
2893
   assert(left != NULL && right != NULL);
2,782✔
2894

2895
   type_t sub = type_new(T_SUBTYPE);
2,782✔
2896
   type_set_base(sub, type_base_recur(type));
2,782✔
2897

2898
   type_t elem = type_elem(type);
2,782✔
2899
   if (type_is_unconstrained(elem)) {
2,782✔
2900
      tree_t a0 = tree_assoc(expr, 0);
124✔
2901
      switch (tree_subkind(a0)) {
124✔
2902
      case A_CONCAT:
7✔
2903
      case A_SLICE:
2904
         a0_type = type_elem(tree_type(tree_value(a0)));
7✔
2905
         break;
7✔
2906
      default:
117✔
2907
         a0_type = tree_type(tree_value(a0));
117✔
2908
         break;
117✔
2909
      }
2910

2911
      if (!type_is_unconstrained(a0_type))
124✔
2912
         elem = a0_type;
68✔
2913
   }
2914

2915
   type_set_elem(sub, elem);
2,782✔
2916

2917
   tree_t cons = tree_new(T_CONSTRAINT);
2,782✔
2918
   tree_set_subkind(cons, C_INDEX);
2,782✔
2919

2920
   tree_t r = tree_new(T_RANGE);
2,782✔
2921
   tree_set_subkind(r, dir);
2,782✔
2922
   tree_set_type(r, index_type);
2,782✔
2923
   tree_set_left(r, left);
2,782✔
2924
   tree_set_right(r, right);
2,782✔
2925

2926
   tree_add_range(cons, r);
2,782✔
2927

2928
   for (int i = 1; i < ndims; i++)
2,863✔
2929
      tree_add_range(cons, range_of(a0_type, i - 1));
81✔
2930

2931
   type_set_constraint(sub, cons);
2,782✔
2932

2933
   return sub;
2,782✔
2934
}
2935

2936
bool can_be_signal(type_t type)
20,579✔
2937
{
2938
   switch (type_kind(type)) {
36,387✔
2939
   case T_RECORD:
4,206✔
2940
      {
2941
         const int nfields = type_fields(type);
4,206✔
2942
         for (int i = 0; i < nfields; i++) {
16,777✔
2943
            if (!can_be_signal(tree_type(type_field(type, i))))
13,609✔
2944
               return false;
2945
         }
2946

2947
         return true;
2948
      }
2949
   case T_ARRAY:
6,072✔
2950
      return can_be_signal(type_elem(type));
6,072✔
2951
   case T_SUBTYPE:
9,736✔
2952
      return can_be_signal(type_base(type));
9,736✔
2953
   case T_ACCESS:
2954
   case T_FILE:
2955
   case T_PROTECTED:
2956
   case T_INCOMPLETE:
2957
      return false;
2958
   default:
11,895✔
2959
      return true;
11,895✔
2960
   }
2961
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc