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

nickg / nvc / 19509869737

19 Nov 2025 05:08PM UTC coverage: 92.56% (-0.01%) from 92.57%
19509869737

push

github

web-flow
Allow constant record elements in case choice (#1349)

Fixes #1347

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

9 existing lines in 1 file now uncovered.

74846 of 80862 relevant lines covered (92.56%)

452572.98 hits per line

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

94.39
/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)
585,180✔
46
{
47
   int64_t value;
585,180✔
48
   if (folded_int(t, &value))
585,180✔
49
      return value;
585,180✔
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)
94,718✔
56
{
57
   assert(tree_kind(r) == T_RANGE);
94,718✔
58

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

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

66
bool folded_int(tree_t t, int64_t *l)
4,805,730✔
67
{
68
   switch (tree_kind(t)) {
4,848,427✔
69
   case T_LITERAL:
3,060,212✔
70
      switch (tree_subkind(t)) {
3,060,212✔
71
      case L_PHYSICAL:
17,578✔
72
         if (tree_has_ref(t))
17,578✔
73
            return false;
74
         // Fall-through
75
      case L_INT:
76
         *l = tree_ival(t);
2,986,712✔
77
         return true;
2,986,712✔
78
      default:
79
         return false;
80
      }
81
   case T_QUALIFIED:
342✔
82
      return folded_int(tree_value(t), l);
342✔
83
   case T_REF:
1,557,413✔
84
      if (tree_has_ref(t)) {
1,557,413✔
85
         tree_t decl = tree_ref(t);
1,557,412✔
86
         switch (tree_kind(decl)) {
1,557,412✔
87
         case T_CONST_DECL:
50,161✔
88
            if (tree_has_value(decl))
50,161✔
89
               return folded_int(tree_value(decl), l);
42,010✔
90
            else
91
               return false;
92
         case T_ENUM_LIT:
1,435,050✔
93
            *l = tree_pos(decl);
1,435,050✔
94
            return true;
1,435,050✔
95
         case T_ALIAS:
345✔
96
            return folded_int(tree_value(decl), l);
345✔
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)
256,617✔
108
{
109
   switch (tree_kind(t)) {
256,626✔
110
   case T_LITERAL:
247,699✔
111
      if (tree_subkind(t) == L_REAL) {
247,699✔
112
         *l = tree_dval(t);
247,622✔
113
         return true;
247,622✔
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)
66,117✔
125
{
126
   int64_t low, high;
66,117✔
127
   if (folded_bounds(r, &low, &high)) {
66,117✔
128
      *l = MAX(high - low + 1, 0);
62,328✔
129
      return true;
62,328✔
130
   }
131
   else
132
      return false;
133
}
134

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

139
   const range_kind_t rkind = tree_subkind(r);
1,956,987✔
140

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

144
   int64_t left, right;
1,949,514✔
145
   if (!folded_int(tree_left(r), &left))
1,949,514✔
146
      return false;
147
   else if (!folded_int(tree_right(r), &right))
1,825,851✔
148
      return false;
149

150
   switch (rkind) {
1,780,382✔
151
   case RANGE_TO:
1,646,283✔
152
      *low  = left;
1,646,283✔
153
      *high = right;
1,646,283✔
154
      return true;
1,646,283✔
155
   case RANGE_DOWNTO:
134,099✔
156
      *low  = right;
134,099✔
157
      *high = left;
134,099✔
158
      return true;
134,099✔
159
   default:
160
      return false;
161
   }
162
}
163

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

168
   const range_kind_t rkind = tree_subkind(r);
95,137✔
169

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

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

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

203
   return false;
204
}
205

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

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

217
   return b;
8,424✔
218
}
219

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

228
   return f;
43,108✔
229
}
230

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

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

264
      int map[256];
21✔
265
      for (int i = 0; i < ARRAY_LEN(map); i++)
5,397✔
266
         map[i] = INT_MAX;
5,376✔
267

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

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

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

280
      int base = 0, dbits = 1;
21✔
281
      bool quoted = false;
21✔
282
      if (map['\"'] == INT_MAX) {
21✔
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;
21✔
296
      enum_array_t *array = xmalloc_flex(sizeof(enum_array_t), max, 1);
21✔
297

298
      int n = 0, m;
21✔
299
      for (; *str != '\0'; str++, n += dbits) {
116✔
300
         if (base > 0) {
82✔
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)
70✔
323
            break;
324
         else
325
            array->values[n] = m;
65✔
326
      }
327

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

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

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

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

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

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

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

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

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

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

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

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

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

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

398
         if (value->integer == -1)
14✔
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++) {
90✔
450
      if (!isspace_iso88591(*str))
11✔
451
         return false;
452
   }
453

454
   return true;
455
}
456

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

467
vhdl_standard_t standard(void)
2,839,905✔
468
{
469
   return current_std;
2,839,905✔
470
}
471

472
void set_standard(vhdl_standard_t s)
5,464✔
473
{
474
   current_std = s;
5,464✔
475
   have_set_std = true;
5,464✔
476
}
5,464✔
477

478
void set_default_standard(vhdl_standard_t s)
475✔
479
{
480
   if (!have_set_std)
475✔
481
      set_standard(s);
96✔
482
}
475✔
483

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

490
   if ((unsigned)s < ARRAY_LEN(text))
4,963✔
491
      return text[s];
4,963✔
492
   else
493
      return "????";
494
}
495

496
tree_t find_element_mode_indication(tree_t view, tree_t field, bool *converse)
503✔
497
{
498
   switch (tree_kind(view)) {
1,578✔
499
   case T_REF:
682✔
500
      return find_element_mode_indication(tree_ref(view), field, converse);
682✔
501

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

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

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

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

522
         return NULL;
523
      }
524

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

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

541
class_t class_of(tree_t t)
1,004,691✔
542
{
543
   switch (tree_kind(t)) {
1,056,887✔
544
   case T_VAR_DECL:
545
      return C_VARIABLE;
546
   case T_SIGNAL_DECL:
47,888✔
547
   case T_IMPLICIT_SIGNAL:
548
      return C_SIGNAL;
47,888✔
549
   case T_CONST_DECL:
36,391✔
550
      return C_CONSTANT;
36,391✔
551
   case T_PORT_DECL:
151,658✔
552
   case T_GENERIC_DECL:
553
   case T_PARAM_DECL:
554
   case T_EXTERNAL_NAME:
555
      return tree_class(t);
151,658✔
556
   case T_ENUM_LIT:
576,875✔
557
   case T_LITERAL:
558
   case T_STRING:
559
      return C_LITERAL;
576,875✔
560
   case T_FIELD_DECL:
1,097✔
561
   case T_ATTR_DECL:
562
      return C_DEFAULT;
1,097✔
563
   case T_VIEW_DECL:
163✔
564
      return C_VIEW;
163✔
565
   case T_UNIT_DECL:
7,948✔
566
      return C_UNITS;
7,948✔
567
   case T_ARCH:
47✔
568
      return C_ARCHITECTURE;
47✔
569
   case T_FUNC_DECL:
2,462✔
570
   case T_FUNC_BODY:
571
   case T_FUNC_INST:
572
   case T_FCALL:
573
   case T_PROT_FCALL:
574
      return C_FUNCTION;
2,462✔
575
   case T_PROC_DECL:
8,489✔
576
   case T_PROC_BODY:
577
   case T_PROC_INST:
578
   case T_PCALL:
579
   case T_PROT_PCALL:
580
      return C_PROCEDURE;
8,489✔
581
   case T_ENTITY:
135✔
582
      return C_ENTITY;
135✔
583
   case T_SUBTYPE_DECL:
19,094✔
584
      return C_SUBTYPE;
19,094✔
585
   case T_TYPE_DECL:
73,196✔
586
   case T_PROT_DECL:
587
   case T_PROT_BODY:
588
      return C_TYPE;
73,196✔
589
   case T_FILE_DECL:
1,124✔
590
      return C_FILE;
1,124✔
591
   case T_PROCESS:
138✔
592
   case T_BLOCK:
593
   case T_FOR:
594
   case T_INSTANCE:
595
   case T_CONCURRENT:
596
   case T_ELAB:
597
   case T_PSL_DECL:
598
   case T_PSL_DIRECT:
599
   case T_FOR_GENERATE:
600
   case T_IF_GENERATE:
601
   case T_CASE_GENERATE:
602
      return C_LABEL;
138✔
603
   case T_COMPONENT:
1✔
604
      return C_COMPONENT;
1✔
605
   case T_REF:
41,735✔
606
   case T_PROT_REF:
607
      return tree_has_ref(t) ? class_of(tree_ref(t)) : C_DEFAULT;
41,735✔
608
   case T_ARRAY_REF:
10,465✔
609
   case T_ARRAY_SLICE:
610
   case T_RECORD_REF:
611
   case T_ALL:
612
   case T_ALIAS:
613
   case T_QUALIFIED:
614
      return class_of(tree_value(t));
10,465✔
615
   case T_PACKAGE:
1,227✔
616
   case T_PACK_BODY:
617
   case T_PACK_INST:
618
      return C_PACKAGE;
1,227✔
619
   case T_CONFIGURATION:
1✔
620
      return C_CONFIGURATION;
1✔
621
   case T_LIBRARY:
1✔
622
      return C_LIBRARY;
1✔
623
   case T_ATTR_REF:
70✔
624
      switch (tree_subkind(t)) {
70✔
625
      case ATTR_DELAYED:
626
      case ATTR_STABLE:
627
      case ATTR_QUIET:
628
      case ATTR_TRANSACTION:
629
         return C_SIGNAL;
630
      default:
64✔
631
         return C_DEFAULT;
64✔
632
      }
633
   case T_CONTEXT:
×
634
      return C_CONTEXT;
×
635
   default:
×
636
      fatal_trace("missing class_of for %s", tree_kind_str(tree_kind(t)));
637
   }
638
}
639

640
bool class_has_type(class_t c)
853,785✔
641
{
642
   switch (c) {
853,785✔
643
   case C_LABEL:
644
   case C_ENTITY:
645
   case C_ARCHITECTURE:
646
   case C_COMPONENT:
647
   case C_CONFIGURATION:
648
   case C_PACKAGE:
649
   case C_LIBRARY:
650
      return false;
651
   default:
852,507✔
652
      return true;
852,507✔
653
   }
654
}
655

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

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

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

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

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

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

744
bool is_package(tree_t t)
39,612✔
745
{
746
   switch (tree_kind(t)) {
39,612✔
747
   case T_PACKAGE:
748
   case T_PACK_BODY:
749
   case T_PACK_INST:
750
      return true;
751
   default:
1,019✔
752
      return false;
1,019✔
753
   }
754
}
755

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

772
bool is_literal(tree_t t)
60,893✔
773
{
774
   switch (tree_kind(t)) {
60,893✔
775
   case T_REF:
20,848✔
776
      return tree_has_ref(t) && tree_kind(tree_ref(t)) == T_ENUM_LIT;
22,914✔
777
   case T_LITERAL:
778
      return true;
779
   case T_STRING:
22,366✔
780
   default:
781
      return false;
22,366✔
782
   }
783
}
784

785
bool is_body(tree_t t)
10,450✔
786
{
787
   switch (tree_kind(t)) {
10,450✔
788
   case T_FUNC_BODY:
789
   case T_PROC_BODY:
790
   case T_PACK_BODY:
791
   case T_PROT_BODY:
792
      return true;
793
   default:
3,117✔
794
      return false;
3,117✔
795
   }
796
}
797

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

809
bool is_type_decl(tree_t t)
1,092,869✔
810
{
811
   switch (tree_kind(t)) {
1,092,869✔
812
   case T_TYPE_DECL:
813
   case T_SUBTYPE_DECL:
814
   case T_PROT_DECL:
815
   case T_PROT_BODY:
816
      return true;
817
   default:
901,855✔
818
      return false;
901,855✔
819
   }
820
}
821

822
tree_t aliased_type_decl(tree_t decl)
126,306✔
823
{
824
   switch (tree_kind(decl)) {
126,570✔
825
   case T_ALIAS:
266✔
826
      {
827
         tree_t value = tree_value(decl);
266✔
828
         const tree_kind_t kind = tree_kind(value);
266✔
829
         if (kind == T_REF && tree_has_ref(value))
266✔
830
            return aliased_type_decl(tree_ref(value));
264✔
831
         else if (kind == T_ATTR_REF && is_type_attribute(tree_subkind(value)))
2✔
832
             return value;
833
         else
834
            return NULL;
×
835
      }
836
   case T_TYPE_DECL:
837
   case T_SUBTYPE_DECL:
838
   case T_PROT_DECL:
839
   case T_PROT_BODY:
840
      return decl;
841
   case T_GENERIC_DECL:
1,551✔
842
      if (tree_class(decl) == C_TYPE)
1,551✔
843
         return decl;
844
      else
845
         return NULL;
749✔
846
   default:
30,265✔
847
      return NULL;
30,265✔
848
   }
849
}
850

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

858
   switch (kind) {
158,951✔
859
   case P_NAMED:
134✔
860
      assert(name != NULL);
134✔
861
      tree_set_name(p, name);
134✔
862
      break;
134✔
863
   case P_POS:
158,817✔
864
      tree_set_pos(p, tree_params(call));
158,817✔
865
      break;
158,817✔
866
   }
867

868
   tree_add_param(call, p);
158,951✔
869
   return p;
158,951✔
870
}
871

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

877
   if (type_is_unconstrained(array)) {
292✔
878
      const int nindex = type_indexes(array);
45✔
879
      assert(from_dim < nindex);
45✔
880

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

885
      for (int i = from_dim; i < nindex; i++)
90✔
886
         type_add_index(type, type_index(array, i));
45✔
887

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

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

898
      tree_t constraint = tree_new(T_CONSTRAINT);
247✔
899
      tree_set_subkind(constraint, C_INDEX);
247✔
900

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

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

914
         type_add_index(base, tree_type(r));
269✔
915
         tree_add_range(constraint, r);
269✔
916
      }
917

918
      return sub;
919
   }
920
}
921

922
unsigned bits_for_range(int64_t low, int64_t high)
2,449,162✔
923
{
924
   if (low > high)
2,449,162✔
925
      return 0;   // Null range
926
   else if (low < 0) {
2,449,161✔
927
      // Signed integers
928
      if (low >= INT8_MIN && high <= INT8_MAX)
593,380✔
929
         return 8;
930
      else if (low >= INT16_MIN && high <= INT16_MAX)
587,558✔
931
         return 16;
932
      else if (low >= INT32_MIN && high <= INT32_MAX)
587,262✔
933
         return 32;
934
      else
935
         return 64;
94,501✔
936
   }
937
   else {
938
      // Unsigned integers
939
      if (high <= 1)
1,855,781✔
940
         return 1;
941
      else if (high <= UINT8_MAX)
1,158,789✔
942
         return 8;
943
      else if (high <= UINT16_MAX)
226,620✔
944
         return 16;
945
      else if (high <= UINT32_MAX)
222,414✔
946
         return 32;
947
      else
948
         return 64;
44,939✔
949
   }
950
}
951

952
unsigned dimension_of(type_t type)
1,444,175✔
953
{
954
   switch (type_kind(type)) {
2,718,068✔
955
   case T_SUBTYPE:
1,273,891✔
956
      return dimension_of(type_base(type));
1,273,891✔
957
   case T_GENERIC:
145✔
958
      switch (type_subkind(type)) {
145✔
959
      case GTYPE_ARRAY:
133✔
960
         return type_indexes(type);
133✔
961
      case GTYPE_ACCESS:
×
962
         return dimension_of(type_designated(type));
×
963
      case GTYPE_FILE:
964
      case GTYPE_PRIVATE:
965
         return 0;
966
      default:
12✔
967
         return 1;
12✔
968
      }
969
   case T_ARRAY:
1,436,907✔
970
      return type_indexes(type);
1,436,907✔
971
   case T_NONE:
972
   case T_RECORD:
973
   case T_INCOMPLETE:
974
   case T_FILE:
975
   case T_SIGNATURE:
976
      return 0;
977
   case T_INTEGER:
7,052✔
978
   case T_REAL:
979
   case T_PHYSICAL:
980
   case T_ENUM:
981
      return type_dims(type);
7,052✔
982
   case T_ACCESS:
2✔
983
      return dimension_of(type_designated(type));
2✔
984
   default:
×
985
      fatal_trace("invalid type kind %s in dimension_of",
986
                  type_kind_str(type_kind(type)));
987
   }
988
}
989

990
tree_t range_of(type_t type, unsigned dim)
2,131,079✔
991
{
992
   switch (type_kind(type)) {
2,165,700✔
993
   case T_SUBTYPE:
1,678,025✔
994
      if (type_has_constraint(type)) {
1,678,025✔
995
         tree_t c = type_constraint(type);
1,643,404✔
996
         switch (tree_subkind(c)) {
1,643,404✔
997
         case C_INDEX:
1,643,404✔
998
         case C_RANGE:
999
            if (dim < tree_ranges(c))
1,643,404✔
1000
               return tree_range(c, dim);
1,643,403✔
1001
            else
1002
               return NULL;   // Must be an error
1003
         default:
×
1004
            should_not_reach_here();
1005
         }
1006
      }
1007
      else
1008
         return range_of(type_base(type), dim);
34,621✔
1009
   case T_INTEGER:
487,675✔
1010
   case T_REAL:
1011
   case T_PHYSICAL:
1012
   case T_ENUM:
1013
      return type_dim(type, dim);
487,675✔
1014
   default:
×
1015
      fatal_trace("invalid type kind %s for %s in range_of",
1016
                  type_kind_str(type_kind(type)), type_pp(type));
1017
   }
1018
}
1019

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

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

1044
            tree_t name = tree_name(value);
152✔
1045
            if (tree_kind(name) == T_REF && tree_has_ref(name)) {
152✔
1046
               tree_t decl = tree_ref(name);
151✔
1047
               if (is_type_decl(decl))
151✔
1048
                  return direction_of(tree_type(decl), 0);
80✔
1049
            }
1050
         }
1051

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

1060
type_t index_type_of(type_t type, unsigned dim)
231,143✔
1061
{
1062
   if (dim >= dimension_of(type))
231,145✔
1063
      return NULL;
1064

1065
   type_t base = type_base_recur(type);
231,105✔
1066
   type_kind_t base_kind = type_kind(base);
231,105✔
1067
   if (base_kind == T_ARRAY)
231,105✔
1068
      return type_index(base, dim);
227,796✔
1069
   else if (base_kind == T_ENUM || base_kind == T_NONE)
3,309✔
1070
      return type;
1071
   else if (base_kind == T_GENERIC && type_subkind(base) == GTYPE_ARRAY)
3,155✔
1072
      return type_index(base, dim);
82✔
1073
   else if (base_kind == T_RECORD || base_kind == T_GENERIC)
3,073✔
1074
      return NULL;
1075
   else if (base_kind == T_ACCESS)
3,067✔
1076
      return index_type_of(type_designated(type), dim);
2✔
1077
   else
1078
      return tree_type(range_of(base, dim));
3,065✔
1079
}
1080

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

1089
ident_t well_known(well_known_t id)
491,200✔
1090
{
1091
   assert(id < NUM_WELL_KNOWN);
491,200✔
1092
   return id_cache[id];
491,200✔
1093
}
1094

1095
well_known_t is_well_known(ident_t ident)
275,336✔
1096
{
1097
   well_known_t pos = 0;
275,336✔
1098
   for (; pos < NUM_WELL_KNOWN; pos++) {
15,450,644✔
1099
      if (id_cache[pos] == ident)
15,309,344✔
1100
         break;
1101
   }
1102

1103
   return pos;
275,336✔
1104
}
1105

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

1157
   id_cache[W_IEEE_LOGIC_VECTOR] =
11,238✔
1158
      ident_new("IEEE.STD_LOGIC_1164.STD_LOGIC_VECTOR");
5,619✔
1159
   id_cache[W_IEEE_ULOGIC_VECTOR] =
11,238✔
1160
      ident_new("IEEE.STD_LOGIC_1164.STD_ULOGIC_VECTOR");
5,619✔
1161
   id_cache[W_IEEE_1164_RISING_EDGE] =
11,238✔
1162
      ident_new("IEEE.STD_LOGIC_1164.RISING_EDGE(sU)B");
5,619✔
1163
   id_cache[W_IEEE_1164_FALLING_EDGE] =
11,238✔
1164
      ident_new("IEEE.STD_LOGIC_1164.FALLING_EDGE(sU)B");
5,619✔
1165

1166
   id_cache[W_NUMERIC_STD_UNSIGNED] = ident_new("IEEE.NUMERIC_STD_UNSIGNED");
5,619✔
1167
   id_cache[W_NUMERIC_BIT_UNSIGNED] = ident_new("IEEE.NUMERIC_BIT_UNSIGNED");
5,619✔
1168
   id_cache[W_VERILOG_NET_VALUE]    = ident_new("NVC.VERILOG.T_NET_VALUE");
5,619✔
1169
   id_cache[W_VERILOG_WIRE_ARRAY]   = ident_new("NVC.VERILOG.T_WIRE_ARRAY");
5,619✔
1170

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

1208
bool is_uninstantiated_package(tree_t pack)
36,090✔
1209
{
1210
   return tree_kind(pack) == T_PACKAGE
36,090✔
1211
      && tree_generics(pack) > 0
34,662✔
1212
      && tree_genmaps(pack) == 0;
38,036✔
1213
}
1214

1215
bool is_uninstantiated_subprogram(tree_t decl)
100,112✔
1216
{
1217
   switch (tree_kind(decl)) {
100,112✔
1218
   case T_FUNC_DECL:
99,577✔
1219
   case T_FUNC_BODY:
1220
   case T_PROC_DECL:
1221
   case T_PROC_BODY:
1222
      return tree_generics(decl) > 0;
99,577✔
1223
   default:
1224
      return false;
1225
   }
1226
}
1227

1228
bool is_anonymous_subtype(type_t type)
203,837✔
1229
{
1230
   return type_kind(type) == T_SUBTYPE && !type_has_ident(type);
203,837✔
1231
}
1232

1233
bool unit_needs_cgen(tree_t unit)
202✔
1234
{
1235
   switch (tree_kind(unit)) {
202✔
1236
   case T_PACK_INST:
1237
      return true;
1238
   case T_PACK_BODY:
×
1239
      {
1240
         tree_t pack = tree_primary(unit);
×
1241
         return package_needs_body(pack) && !is_uninstantiated_package(pack);
×
1242
      }
1243
   case T_PACKAGE:
12✔
1244
      return !package_needs_body(unit) && !is_uninstantiated_package(unit);
24✔
1245
   default:
×
1246
      return false;
×
1247
   }
1248
}
1249

1250
bool package_needs_body(tree_t pack)
12,000✔
1251
{
1252
   assert(tree_kind(pack) == T_PACKAGE);
12,000✔
1253

1254
   const int ndecls = tree_decls(pack);
12,000✔
1255
   for (int i = 0; i < ndecls; i++) {
1,094,011✔
1256
      tree_t d = tree_decl(pack, i);
1,092,937✔
1257
      const tree_kind_t dkind = tree_kind(d);
1,092,937✔
1258
      if ((dkind == T_FUNC_DECL || dkind == T_PROC_DECL)
1,092,937✔
1259
          && !(tree_flags(d) & TREE_F_PREDEFINED))
1,000,516✔
1260
         return true;
1261
      else if (dkind == T_CONST_DECL && !tree_has_value(d))
1,082,482✔
1262
         return true;
1263
      else if (dkind == T_PROT_DECL)
1,082,117✔
1264
         return true;
1265
   }
1266

1267
   return false;
1268
}
1269

1270
static tree_t cached_unit(tree_t hint, tree_t *cache, well_known_t lib_name,
15,566✔
1271
                          well_known_t unit_name)
1272
{
1273
   const vhdl_standard_t curr = standard();
15,566✔
1274

1275
   if (cache[curr] == NULL) {
15,566✔
1276
      if (hint != NULL)
4,944✔
1277
         cache[curr] = hint;
1,461✔
1278
      else {
1279
         lib_t std = lib_require(well_known(lib_name));
3,483✔
1280
         cache[curr] = lib_get(std, well_known(unit_name));
3,483✔
1281
         assert(cache[curr] != NULL);
3,483✔
1282
      }
1283
   }
1284

1285
   assert(hint == NULL || hint == cache[curr]);
15,566✔
1286
   return cache[curr];
15,566✔
1287
}
1288

1289
static tree_t cached_std(tree_t hint)
14,348✔
1290
{
1291
   static tree_t standard_cache[STD_19 + 1] = {};
14,348✔
1292
   return cached_unit(hint, standard_cache, W_STD, W_STD_STANDARD);
14,348✔
1293
}
1294

1295
static tree_t search_type_decls(tree_t container, ident_t name)
15,216✔
1296
{
1297
   const int ndecls = tree_decls(container);
15,216✔
1298

1299
   for (int i = 0; i < ndecls; i++) {
971,513✔
1300
      tree_t d = tree_decl(container, i);
971,513✔
1301
      if (is_type_decl(d) && tree_ident(d) == name)
971,513✔
1302
         return d;
15,216✔
1303
   }
1304

1305
   return NULL;
1306
}
1307

1308
type_t std_type(tree_t std, std_type_t which)
944,577✔
1309
{
1310
   static type_t cache[STD_FILE_OPEN_STATE + 1] = {};
944,577✔
1311
   assert(which < ARRAY_LEN(cache));
944,577✔
1312

1313
   if (cache[which] == NULL) {
944,577✔
1314
      const char *names[] = {
14,348✔
1315
         "universal_integer",
1316
         "universal_real",
1317
         "INTEGER",
1318
         "REAL",
1319
         "BOOLEAN",
1320
         "STRING",
1321
         "TIME",
1322
         "BIT",
1323
         "FILE_OPEN_KIND",
1324
         "FILE_OPEN_STATUS",
1325
         "NATURAL",
1326
         "BIT_VECTOR",
1327
         "SEVERITY_LEVEL",
1328
         "FILE_ORIGIN_KIND",
1329
         "FILE_OPEN_STATE",
1330
      };
1331

1332
      tree_t d = search_type_decls(cached_std(std), ident_new(names[which]));
14,348✔
1333
      if (d == NULL)
14,348✔
1334
         fatal_trace("cannot find standard type %s", names[which]);
1335

1336
      // Do not cache standard types while bootstrapping as the GC will
1337
      // move the objects after parsing
1338
      static int can_cache = -1;
14,348✔
1339
      if (can_cache == -1) can_cache = !opt_get_int(OPT_BOOTSTRAP);
14,348✔
1340

1341
      if (can_cache)
14,348✔
1342
         return (cache[which] = tree_type(d));
14,158✔
1343
      else
1344
         return tree_type(d);
190✔
1345
   }
1346
   else
1347
      return cache[which];
1348
}
1349

1350
type_t ieee_type(ieee_type_t which)
1,874✔
1351
{
1352
   static type_t cache[IEEE_STD_LOGIC_VECTOR + 1] = {};
1,874✔
1353
   assert(which < ARRAY_LEN(cache));
1,874✔
1354

1355
   if (cache[which] == NULL) {
1,874✔
1356
      static const char *const names[] = {
242✔
1357
         [IEEE_STD_ULOGIC] = "STD_ULOGIC",
1358
         [IEEE_STD_LOGIC] = "STD_LOGIC",
1359
         [IEEE_STD_ULOGIC_VECTOR] = "STD_ULOGIC_VECTOR",
1360
         [IEEE_STD_LOGIC_VECTOR] = "STD_LOGIC_VECTOR",
1361
      };
1362

1363
      static tree_t ieee_cache[STD_19 + 1] = {};
242✔
1364
      tree_t unit = cached_unit(NULL, ieee_cache, W_IEEE, W_IEEE_1164);
242✔
1365

1366
      tree_t d = search_type_decls(unit, ident_new(names[which]));
242✔
1367
      if (d == NULL)
242✔
1368
         fatal_trace("cannot find IEEE type %s", names[which]);
1369

1370
      // STD.STANDARD cannot depend on IEEE
1371
      assert(!opt_get_int(OPT_BOOTSTRAP));
242✔
1372

1373
      return (cache[which] = tree_type(d));
242✔
1374
   }
1375
   else
1376
      return cache[which];
1377
}
1378

1379
static tree_t cached_verilog(void)
944✔
1380
{
1381
   static tree_t verilog_cache[STD_19 + 1] = {};
944✔
1382
   return cached_unit(NULL, verilog_cache, W_NVC, W_NVC_VERILOG);
944✔
1383
}
1384

1385
type_t verilog_type(verilog_type_t which)
1,965✔
1386
{
1387
   static type_t cache[VERILOG_WIRE_ARRAY + 1] = {};
1,965✔
1388
   assert(which < ARRAY_LEN(cache));
1,965✔
1389

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

1401
      tree_t d = search_type_decls(cached_verilog(), ident_new(names[which]));
594✔
1402
      if (d == NULL)
594✔
1403
         fatal_trace("cannot find NVC.VERILOG type %s", names[which]);
1404

1405
      // STD.STANDARD cannot depend on NVC.VERILOG
1406
      assert(!opt_get_int(OPT_BOOTSTRAP));
594✔
1407

1408
      return (cache[which] = tree_type(d));
594✔
1409
   }
1410
   else
1411
      return cache[which];
1412
}
1413

1414
type_t reflection_type(reflect_type_t which)
189✔
1415
{
1416
   static type_t cache[REFLECT_SUBTYPE_MIRROR + 1] = {};
189✔
1417
   assert(which < ARRAY_LEN(cache));
189✔
1418

1419
   if (cache[which] == NULL) {
189✔
1420
      static const char *const names[] = {
32✔
1421
         [REFLECT_VALUE_MIRROR] = "VALUE_MIRROR",
1422
         [REFLECT_SUBTYPE_MIRROR] = "SUBTYPE_MIRROR",
1423
      };
1424

1425
      static tree_t reflect_cache[STD_19 + 1] = {};
32✔
1426
      tree_t unit = cached_unit(NULL, reflect_cache, W_STD, W_STD_REFLECTION);
32✔
1427

1428
      tree_t d = search_type_decls(unit, ident_new(names[which]));
32✔
1429
      if (d == NULL)
32✔
1430
         fatal_trace("cannot find REFLECTION type %s", names[which]);
1431

1432
      // STD.STANDARD cannot depend on REFLECTION
1433
      assert(!opt_get_int(OPT_BOOTSTRAP));
32✔
1434

1435
      return (cache[which] = tree_type(d));
32✔
1436
   }
1437
   else
1438
      return cache[which];
1439
}
1440

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

1489
tree_t std_func(ident_t mangled)
×
1490
{
1491
   tree_t std = cached_std(NULL);
×
1492

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

1500
   return NULL;
1501
}
1502

1503
tree_t verilog_func(ident_t mangled)
350✔
1504
{
1505
   tree_t pack = cached_verilog();
350✔
1506

1507
   const int ndecls = tree_decls(pack);
350✔
1508
   for (int i = 0; i < ndecls; i++) {
36,949✔
1509
      tree_t d = tree_decl(pack, i);
36,949✔
1510
      if (is_subprogram(d) && tree_ident2(d) == mangled)
36,949✔
1511
         return d;
350✔
1512
   }
1513

1514
   fatal_trace("missing Verilog helper function %s", istr(mangled));
1515
}
1516

1517
tree_t name_to_ref(tree_t name)
97,326✔
1518
{
1519
   tree_kind_t kind;
97,326✔
1520
   while ((kind = tree_kind(name)) != T_REF) {
110,727✔
1521
      switch (kind) {
15,154✔
1522
      case T_ARRAY_REF:
13,401✔
1523
      case T_ARRAY_SLICE:
1524
      case T_RECORD_REF:
1525
      case T_ALL:
1526
         name = tree_value(name);
13,401✔
1527
         break;
13,401✔
1528
      default:
1529
         return NULL;
1530
      }
1531
   }
1532

1533
   return name;
1534
}
1535

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

1545
void mangle_one_type(text_buf_t *buf, type_t type)
174,112✔
1546
{
1547
   ident_t ident = type_ident(type);
174,112✔
1548

1549
   char code = 0;
174,112✔
1550
   switch (is_well_known(ident)) {
174,112✔
1551
   case W_STD_INTEGER:        code = 'I'; break;
1552
   case W_STD_STRING:         code = 'S'; break;
3,436✔
1553
   case W_STD_REAL:           code = 'R'; break;
3,555✔
1554
   case W_STD_BOOL:           code = 'B'; break;
23,577✔
1555
   case W_STD_CHAR:           code = 'C'; break;
625✔
1556
   case W_STD_TIME:           code = 'T'; break;
918✔
1557
   case W_STD_NATURAL:        code = 'N'; break;
4,275✔
1558
   case W_STD_POSITIVE:       code = 'P'; break;
365✔
1559
   case W_STD_BIT:            code = 'J'; break;
2,674✔
1560
   case W_STD_BIT_VECTOR:     code = 'Q'; break;
2,982✔
1561
   case W_IEEE_LOGIC:         code = 'L'; break;
298✔
1562
   case W_IEEE_ULOGIC:        code = 'U'; break;
4,629✔
1563
   case W_IEEE_LOGIC_VECTOR:  code = 'V'; break;
1,623✔
1564
   case W_IEEE_ULOGIC_VECTOR: code = 'Y'; break;
1,436✔
1565
   default: break;
1566
   }
1567

1568
   if (code)
50,393✔
1569
      tb_append(buf, code);
63,171✔
1570
   else {
1571
      tb_printf(buf, "%zu", ident_len(ident));
110,941✔
1572
      tb_istr(buf, ident);
110,941✔
1573
   }
1574
}
174,112✔
1575

1576
ident_t get_call_context(ident_t mangled)
2,615✔
1577
{
1578
   const char *str = istr(mangled), *p = str, *end = NULL;
2,615✔
1579
   for (; *p; p++) {
94,641✔
1580
      if (*p == '(') break;
90,245✔
1581
      if (*p == '.') end = p;
89,411✔
1582
   }
1583
   assert(end != NULL);
2,615✔
1584

1585
   return ident_new_n(str, end - str);
2,615✔
1586
}
1587

1588
tree_t primary_unit_of(tree_t unit)
16,419✔
1589
{
1590
   switch (tree_kind(unit)) {
16,419✔
1591
   case T_ENTITY:
1592
   case T_COMPONENT:
1593
   case T_PACKAGE:
1594
   case T_BLOCK:
1595
   case T_ELAB:
1596
   case T_PACK_INST:
1597
      return unit;
1598
   case T_ARCH:
8,122✔
1599
   case T_CONFIGURATION:
1600
   case T_PACK_BODY:
1601
      return tree_primary(unit);
8,122✔
1602
   default:
×
1603
      fatal_trace("invalid kind %s in primary_unit_of",
1604
                  tree_kind_str(tree_kind(unit)));
1605
   }
1606
}
1607

1608
unsigned get_case_choice_char(tree_t value, int depth)
11,838✔
1609
{
1610
   switch (tree_kind(value)) {
12,457✔
1611
   case T_STRING:
11,816✔
1612
      if (depth < tree_chars(value))
11,816✔
1613
         return assume_int(tree_char(value, depth));
11,395✔
1614
      else
1615
         return ~0;   // Out of bounds
1616

1617
   case T_AGGREGATE:
22✔
1618
      {
1619
         const int nassocs = tree_assocs(value);
22✔
1620
         type_t type = tree_type(value);
22✔
1621

1622
         for (int i = 0, pos = 0; i < nassocs; i++) {
36✔
1623
            tree_t a = tree_assoc(value, i);
35✔
1624
            switch (tree_subkind(a)) {
35✔
1625
            case A_NAMED:
×
1626
               if (rebase_index(type, 0, assume_int(tree_name(a))) == depth)
×
1627
                  return assume_int(tree_value(a));
×
1628
               break;
1629

1630
            case A_POS:
11✔
1631
               if (pos++ == (unsigned)depth)
11✔
1632
                  return assume_int(tree_value(a));
5✔
1633
               break;
1634

1635
            case A_CONCAT:
24✔
1636
               {
1637
                  tree_t left = tree_value(a);
24✔
1638

1639
                  type_t left_type = tree_type(left);
24✔
1640
                  if (type_is_unconstrained(left_type))
24✔
1641
                     fatal_at(tree_loc(left), "sorry, this expression is not "
×
1642
                              "currently supported in a case choice");
1643

1644
                  tree_t lr = range_of(tree_type(left), 0);
24✔
1645
                  int64_t left_len;
24✔
1646
                  if (!folded_length(lr, &left_len))
24✔
1647
                     fatal_at(tree_loc(left), "cannot determine length of "
×
1648
                              "aggregate element");
1649

1650
                  if (depth < pos + left_len)
24✔
1651
                     return get_case_choice_char(left, depth - pos);
16✔
1652

1653
                  pos += left_len;
8✔
1654
               }
1655
               break;
8✔
1656

1657
            case A_OTHERS:
×
1658
               return assume_int(tree_value(a));
×
1659

UNCOV
1660
            case A_SLICE:
×
1661
               {
UNCOV
1662
                  tree_t base = tree_value(a);
×
UNCOV
1663
                  tree_t r = tree_range(a, 0);
×
1664

UNCOV
1665
                  const int64_t rleft = assume_int(tree_left(r));
×
UNCOV
1666
                  const int64_t rright = assume_int(tree_right(r));
×
1667

UNCOV
1668
                  const int64_t loffset = rebase_index(type, 0, rleft);
×
UNCOV
1669
                  const int64_t roffset = rebase_index(type, 0, rright);
×
1670

UNCOV
1671
                  if (depth >= loffset && depth <= roffset)
×
UNCOV
1672
                     return get_case_choice_char(base, depth - loffset);
×
1673
               }
1674
            }
1675
         }
1676

1677
         // This will produce an error during bounds checking
1678
         return ~0;
1679
      }
1680

1681
   case T_REF:
379✔
1682
      {
1683
         tree_t decl = tree_ref(value);
379✔
1684
         assert(tree_kind(decl) == T_CONST_DECL || tree_kind(decl) == T_ALIAS);
379✔
1685
         assert(tree_has_value(decl));
379✔
1686
         return get_case_choice_char(tree_value(decl), depth);
379✔
1687
      }
1688

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

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

1704
int64_t encode_case_choice(tree_t value, int length, int bits)
1,592✔
1705
{
1706
   uint64_t enc = 0;
1,592✔
1707
   for (int i = 0; i < length; i++) {
13,392✔
1708
      if (bits > 0) {
11,800✔
1709
         enc <<= bits;
4,343✔
1710
         enc |= get_case_choice_char(value, i);
4,343✔
1711
      }
1712
      else {
1713
         enc *= 0x27d4eb2d;
7,457✔
1714
         enc += get_case_choice_char(value, i);
7,457✔
1715
      }
1716
   }
1717

1718
   return enc;
1,592✔
1719
}
1720

1721
void to_string(text_buf_t *tb, type_t type, int64_t value)
587✔
1722
{
1723
   if (type_is_integer(type))
587✔
1724
      tb_printf(tb, "%"PRIi64, value);
444✔
1725
   else if (type_is_enum(type)) {
143✔
1726
      type_t base = type_base_recur(type);
62✔
1727
      if (value < 0 || value >= type_enum_literals(base))
62✔
1728
         tb_printf(tb, "%"PRIi64, value);
3✔
1729
      else
1730
         tb_cat(tb, istr(tree_ident(type_enum_literal(base, value))));
59✔
1731
   }
1732
   else if (type_is_physical(type)) {
81✔
1733
      type_t base = type_base_recur(type);
24✔
1734
      const unsigned nunits = type_units(base);
24✔
1735
      tree_t max_unit = NULL;
24✔
1736
      int64_t max_unit_value = 0;
24✔
1737

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

1749
      tb_printf(tb, "%"PRIi64" %s", value / max_unit_value,
24✔
1750
                istr(tree_ident(max_unit)));
1751
   }
1752
   else if (type_is_real(type)) {
57✔
1753
      union { int64_t i; double r; } u = { .i = value };
51✔
1754
      tb_printf(tb, "%.17g", u.r);
51✔
1755
   }
1756
   else if (type_is_access(type)) {
6✔
1757
      if (value == 0)
6✔
1758
         tb_cat(tb, "NULL");
3✔
1759
      else
1760
         tb_printf(tb, "%p", (void *)value);
3✔
1761
   }
1762
}
587✔
1763

1764
static bool is_static(tree_t expr)
6,156✔
1765
{
1766
   switch (tree_kind(expr)) {
6,260✔
1767
   case T_REF:
721✔
1768
      {
1769
         tree_t decl = tree_ref(expr);
721✔
1770
         switch (tree_kind(decl)) {
721✔
1771
         case T_CONST_DECL:
179✔
1772
            return !!(tree_flags(decl) & TREE_F_GLOBALLY_STATIC);
179✔
1773
         case T_UNIT_DECL:
1774
         case T_ENUM_LIT:
1775
         case T_GENERIC_DECL:
1776
            return true;
1777
         case T_ALIAS:
×
1778
            return is_static(tree_value(decl));
×
1779
         default:
197✔
1780
            return false;
197✔
1781
         }
1782
      }
1783

1784
   case T_LITERAL:
1785
   case T_STRING:
1786
      return true;
1787

1788
   case T_FCALL:
399✔
1789
      return !!(tree_flags(expr) & (TREE_F_LOCALLY_STATIC
399✔
1790
                                    | TREE_F_GLOBALLY_STATIC));
1791

1792
   case T_RECORD_REF:
101✔
1793
      return is_static(tree_value(expr));
101✔
1794

1795
   case T_ARRAY_REF:
60✔
1796
      {
1797
         if (!is_static(tree_value(expr)))
60✔
1798
            return false;
1799

1800
         const int nparams = tree_params(expr);
60✔
1801
         for (int i = 0; i < nparams; i++) {
120✔
1802
            if (!is_static(tree_value(tree_param(expr, i))))
60✔
1803
               return false;
1804
         }
1805

1806
         return true;
1807
      }
1808

1809
   case T_ARRAY_SLICE:
30✔
1810
      {
1811
         if (!is_static(tree_value(expr)))
30✔
1812
            return false;
1813

1814
         assert(tree_ranges(expr) == 1);
30✔
1815

1816
         tree_t r = tree_range(expr, 0);
30✔
1817
         if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
30✔
1818
            return false;
×
1819

1820
         return true;
1821
      }
1822

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

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

1870
   default:
×
1871
      return false;
×
1872
   }
1873
}
1874

1875
tree_t longest_static_prefix(tree_t expr)
23,467✔
1876
{
1877
   switch (tree_kind(expr)) {
23,467✔
1878
   case T_ARRAY_REF:
4,265✔
1879
      {
1880
         tree_t value = tree_value(expr);
4,265✔
1881
         tree_t prefix = longest_static_prefix(value);
4,265✔
1882

1883
         if (prefix != value)
4,265✔
1884
            return prefix;
1885

1886
         const int nparams = tree_params(expr);
4,237✔
1887
         for (int i = 0; i < nparams; i++) {
8,652✔
1888
            if (!is_static(tree_value(tree_param(expr, i))))
4,663✔
1889
               return prefix;
1890
         }
1891

1892
         return expr;
1893
      }
1894

1895
   case T_ARRAY_SLICE:
661✔
1896
      {
1897
         tree_t value = tree_value(expr);
661✔
1898
         tree_t prefix = longest_static_prefix(value);
661✔
1899

1900
         if (prefix != value)
661✔
1901
            return prefix;
1902

1903
         assert(tree_ranges(expr) == 1);
654✔
1904

1905
         tree_t r = tree_range(expr, 0);
654✔
1906
         if (tree_subkind(r) == RANGE_EXPR)
654✔
1907
            return prefix;
1908
         else if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
648✔
1909
            return prefix;
16✔
1910

1911
         return expr;
1912
      }
1913

1914
   case T_RECORD_REF:
1,185✔
1915
      {
1916
         tree_t value = tree_value(expr);
1,185✔
1917
         tree_t prefix = longest_static_prefix(value);
1,185✔
1918

1919
         if (prefix != value)
1,185✔
1920
            return prefix;
21✔
1921

1922
         return expr;
1923
      }
1924

1925
   default:
1926
      return expr;
1927
   }
1928
}
1929

1930
tree_t body_of(tree_t pack)
11,151✔
1931
{
1932
   const tree_kind_t kind = tree_kind(pack);
11,151✔
1933
   if (kind == T_PACK_INST)
11,151✔
1934
      return NULL;
1935

1936
   assert(tree_kind(pack) == T_PACKAGE);
11,151✔
1937

1938
   ident_t body_i = well_known(W_BODY);
11,151✔
1939
   ident_t body_name = ident_prefix(tree_ident(pack), body_i, '-');
11,151✔
1940
   return lib_get_qualified(body_name);
11,151✔
1941
}
1942

1943
tree_t find_generic_map(tree_t unit, int pos, tree_t g)
596✔
1944
{
1945
   const int ngenmaps = tree_genmaps(unit);
596✔
1946

1947
   if (pos < ngenmaps) {
596✔
1948
      tree_t m = tree_genmap(unit, pos);
458✔
1949
      if (tree_subkind(m) == P_POS && tree_pos(m) == pos)
458✔
1950
         return tree_value(m);
312✔
1951
   }
1952

1953
   for (int j = 0; j < ngenmaps; j++) {
998✔
1954
      tree_t m = tree_genmap(unit, j);
860✔
1955
      switch (tree_subkind(m)) {
860✔
1956
      case P_NAMED:
440✔
1957
         {
1958
            tree_t name = tree_name(m);
440✔
1959
            assert(tree_kind(name) == T_REF);
440✔
1960

1961
            if (tree_has_ref(name) && tree_ref(name) == g)
440✔
1962
               return tree_value(m);
15✔
1963
         }
1964
         break;
1965

1966
      case P_POS:
420✔
1967
         if (tree_pos(m) == pos)
420✔
1968
            return tree_value(m);
131✔
1969
         break;
1970

1971
      default:
1972
         break;
1973
      }
1974
   }
1975

1976
   return NULL;
1977
}
1978

1979
bool relaxed_rules(void)
543,456✔
1980
{
1981
   return opt_get_int(OPT_RELAXED);
543,456✔
1982
}
1983

1984
bool is_type_attribute(attr_kind_t kind)
69,632✔
1985
{
1986
   switch (kind) {
69,632✔
1987
   case ATTR_SUBTYPE:
1988
   case ATTR_BASE:
1989
   case ATTR_ELEMENT:
1990
   case ATTR_DESIGNATED_SUBTYPE:
1991
   case ATTR_INDEX:
1992
      return true;
1993
   default:
68,876✔
1994
      return false;
68,876✔
1995
   }
1996
}
1997

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

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

2065
type_t subtype_for_string(tree_t str, type_t base)
25,455✔
2066
{
2067
   if (type_const_bounds(base))
25,455✔
2068
      return base;    // Can be checked statically
2069
   else if (!type_is_unconstrained(base))
22,274✔
2070
      base = type_base_recur(base);
263✔
2071

2072
   // Construct a new constrained array subtype: the direction and
2073
   // bounds are the same as those for a positional array aggregate
2074
   type_t sub = type_new(T_SUBTYPE);
22,274✔
2075
   type_set_base(sub, base);
22,274✔
2076

2077
   type_t index_type = index_type_of(base, 0);
22,274✔
2078
   const bool is_enum = type_is_enum(index_type);
22,274✔
2079

2080
   // The direction is determined by the index type
2081
   range_kind_t dir = direction_of(index_type, 0);
22,274✔
2082
   tree_t index_r = range_of(index_type, 0);
22,274✔
2083

2084
   // The left bound is the left of the index type and the right bound
2085
   // is determined by the number of elements
2086

2087
   tree_t left = NULL, right = NULL;
22,274✔
2088
   const int nchars = tree_chars(str);
22,274✔
2089

2090
   if (is_enum) {
22,274✔
2091
      const int nlits = type_enum_literals(type_base_recur(index_type));
14✔
2092
      int64_t index_left = assume_int(tree_left(index_r));
14✔
2093

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

2108
      left = get_enum_lit(str, index_type, ileft);
14✔
2109
      right = get_enum_lit(str, index_type, iright);
14✔
2110
   }
2111
   else {
2112
      left = tree_left(index_r);
22,260✔
2113

2114
      int64_t iright;
22,260✔
2115
      if (dir == RANGE_DOWNTO)
22,260✔
2116
         iright = assume_int(left) - nchars + 1;
×
2117
      else
2118
         iright = assume_int(left) + nchars - 1;
22,260✔
2119

2120
      right = get_int_lit(str, index_type, iright);
22,260✔
2121
   }
2122

2123
   tree_t r = tree_new(T_RANGE);
22,274✔
2124
   tree_set_subkind(r, dir);
22,274✔
2125
   tree_set_left(r, left);
22,274✔
2126
   tree_set_right(r, right);
22,274✔
2127
   tree_set_loc(r, tree_loc(str));
22,274✔
2128
   tree_set_type(r, index_type);
22,274✔
2129

2130
   tree_t c = tree_new(T_CONSTRAINT);
22,274✔
2131
   tree_set_subkind(c, C_INDEX);
22,274✔
2132
   tree_add_range(c, r);
22,274✔
2133
   tree_set_loc(c, tree_loc(str));
22,274✔
2134

2135
   type_set_constraint(sub, c);
22,274✔
2136

2137
   return sub;
22,274✔
2138
}
2139

2140
tree_t change_ref(tree_t name, tree_t new)
2,305✔
2141
{
2142
   switch (tree_kind(name)) {
2,305✔
2143
   case T_REF:
1,592✔
2144
      return make_ref(new);
1,592✔
2145

2146
   case T_ARRAY_REF:
106✔
2147
      {
2148
         tree_t value = change_ref(tree_value(name), new);
106✔
2149

2150
         tree_t t = tree_new(T_ARRAY_REF);
106✔
2151
         tree_set_loc(t, tree_loc(name));
106✔
2152
         tree_set_value(t, value);
106✔
2153
         tree_set_type(t, type_elem(tree_type(value)));
106✔
2154

2155
         const int nparams = tree_params(name);
106✔
2156
         for (int i = 0; i < nparams; i++)
212✔
2157
            tree_add_param(t, tree_param(name, i));
106✔
2158

2159
         return t;
2160
      }
2161

2162
   case T_ARRAY_SLICE:
47✔
2163
      {
2164
         tree_t value = change_ref(tree_value(name), new);
47✔
2165
         tree_t r = tree_range(name, 0);
47✔
2166

2167
         tree_t constraint = tree_new(T_CONSTRAINT);
47✔
2168
         tree_set_subkind(constraint, C_INDEX);
47✔
2169
         tree_add_range(constraint, r);
47✔
2170

2171
         type_t slice_type = type_new(T_SUBTYPE);
47✔
2172
         type_set_constraint(slice_type, constraint);
47✔
2173
         type_set_base(slice_type, tree_type(value));
47✔
2174

2175
         tree_t t = tree_new(T_ARRAY_SLICE);
47✔
2176
         tree_set_loc(t, tree_loc(name));
47✔
2177
         tree_set_value(t, value);
47✔
2178
         tree_set_type(t, slice_type);
47✔
2179
         tree_add_range(t, r);
47✔
2180

2181
         return t;
47✔
2182
      }
2183

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

2193
         return t;
404✔
2194
      }
2195

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

2205
         return t;
147✔
2206
      }
2207

2208
   case T_TYPE_CONV:
9✔
2209
      {
2210
         tree_t t = tree_new(T_TYPE_CONV);
9✔
2211
         tree_set_loc(t, tree_loc(name));
9✔
2212
         tree_set_type(t, tree_type(name));
9✔
2213
         tree_set_value(t, change_ref(tree_value(name), new));
9✔
2214

2215
         return t;
9✔
2216
      }
2217

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

2224
static void build_wait_for_target(tree_t expr, build_wait_fn_t fn, void *ctx)
3,000✔
2225
{
2226
   switch (tree_kind(expr)) {
3,000✔
2227
   case T_ARRAY_SLICE:
81✔
2228
      build_wait(tree_range(expr, 0), fn, ctx);
81✔
2229
      break;
81✔
2230

2231
   case T_ARRAY_REF:
572✔
2232
      {
2233
         const int nparams = tree_params(expr);
572✔
2234
         for (int i = 0; i < nparams; i++)
1,144✔
2235
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
572✔
2236
      }
2237
      break;
2238

2239
   default:
2240
      break;
2241
   }
2242
}
3,000✔
2243

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

2250
   switch (tree_kind(expr)) {
17,430✔
2251
   case T_REF:
4,449✔
2252
      if (class_of(tree_ref(expr)) == C_SIGNAL)
4,449✔
2253
         (*fn)(expr, ctx);
2,596✔
2254
      break;
2255

2256
   case T_EXTERNAL_NAME:
7✔
2257
      if (tree_class(expr) == C_SIGNAL)
7✔
2258
         (*fn)(expr, ctx);
7✔
2259
      break;
2260

2261
   case T_WAVEFORM:
2,936✔
2262
   case T_QUALIFIED:
2263
   case T_TYPE_CONV:
2264
   case T_INERTIAL:
2265
      if (tree_has_value(expr))
2,936✔
2266
         build_wait(tree_value(expr), fn, ctx);
2,927✔
2267
      break;
2268

2269
   case T_ASSERT:
405✔
2270
      build_wait(tree_value(expr), fn, ctx);
405✔
2271
      // Fall-through
2272
   case T_REPORT:
409✔
2273
      if (tree_has_message(expr))
409✔
2274
         build_wait(tree_message(expr), fn, ctx);
280✔
2275
      break;
2276

2277
   case T_ARRAY_REF:
824✔
2278
   case T_ARRAY_SLICE:
2279
   case T_RECORD_REF:
2280
      {
2281
         tree_t ref = name_to_ref(expr);
824✔
2282
         if (ref != NULL && class_of(ref) == C_SIGNAL
824✔
2283
             && longest_static_prefix(expr) == expr)
528✔
2284
            (*fn)(expr, ctx);
451✔
2285
         else {
2286
            build_wait(tree_value(expr), fn, ctx);
373✔
2287
            build_wait_for_target(expr, fn, ctx);
373✔
2288
         }
2289
      }
2290
      break;
2291

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

2313
            switch (tree_subkind(port)) {
3,477✔
2314
            case PORT_IN:
3,470✔
2315
            case PORT_INOUT:
2316
            case PORT_ARRAY_VIEW:
2317
            case PORT_RECORD_VIEW:
2318
               build_wait(tree_value(p), fn, ctx);
3,470✔
2319
               break;
3,470✔
2320
            default:
2321
               break;
2322
            }
2323
         }
2324
      }
2325
      break;
2326

2327
   case T_AGGREGATE:
376✔
2328
      {
2329
         const int nassocs = tree_assocs(expr);
376✔
2330
         for (int i = 0; i < nassocs; i++) {
1,373✔
2331
            tree_t a = tree_assoc(expr, i);
997✔
2332
            build_wait(tree_value(a), fn, ctx);
997✔
2333

2334
            switch (tree_subkind(a)) {
997✔
2335
            case A_RANGE:
53✔
2336
            case A_SLICE:
2337
               build_wait(tree_range(a, 0), fn, ctx);
53✔
2338
               break;
53✔
2339
            case A_NAMED:
93✔
2340
               build_wait(tree_name(a), fn, ctx);
93✔
2341
               break;
93✔
2342
            }
2343
         }
2344
      }
2345
      break;
2346

2347
   case T_ATTR_REF:
362✔
2348
      {
2349
         const attr_kind_t predef = tree_subkind(expr);
362✔
2350
         if (predef == ATTR_EVENT || predef == ATTR_ACTIVE)
362✔
2351
            build_wait(tree_name(expr), fn, ctx);
169✔
2352

2353
         const int nparams = tree_params(expr);
362✔
2354
         for (int i = 0; i < nparams; i++)
379✔
2355
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
17✔
2356
      }
2357
      break;
2358

2359
   case T_LITERAL:
2360
   case T_STRING:
2361
   case T_DUMMY_DRIVER:
2362
      break;
2363

2364
   case T_IF:
235✔
2365
      {
2366
         const int nconds = tree_conds(expr);
235✔
2367
         for (int i = 0; i < nconds; i++)
641✔
2368
            build_wait(tree_cond(expr, i), fn, ctx);
406✔
2369
      }
2370
      break;
2371

2372
   case T_COND_STMT:
410✔
2373
      {
2374
         if (tree_has_value(expr))
410✔
2375
            build_wait(tree_value(expr), fn, ctx);
275✔
2376

2377
         const int nstmts = tree_stmts(expr);
410✔
2378
         for (int i = 0; i < nstmts; i++)
822✔
2379
            build_wait(tree_stmt(expr, i), fn, ctx);
412✔
2380
      }
2381
      break;
2382

2383
   case T_COND_VALUE:
3✔
2384
      {
2385
         const int nconds = tree_conds(expr);
3✔
2386
         for (int i = 0; i < nconds; i++)
12✔
2387
            build_wait(tree_cond(expr, i), fn, ctx);
9✔
2388
         break;
2389
      }
2390

2391
   case T_COND_EXPR:
9✔
2392
      {
2393
         if (tree_has_value(expr))
9✔
2394
            build_wait(tree_value(expr), fn, ctx);
6✔
2395

2396
         build_wait(tree_result(expr), fn, ctx);
9✔
2397
         break;
9✔
2398
      }
2399

2400
   case T_PROCESS:
52✔
2401
   case T_SEQUENCE:
2402
   case T_PROC_BODY:
2403
      {
2404
         const int ndecls = tree_decls(expr);
52✔
2405
         for (int i = 0; i < ndecls; i++) {
70✔
2406
            tree_t d = tree_decl(expr, i);
18✔
2407
            if (tree_kind(d) == T_PROC_BODY)
18✔
2408
               build_wait(d, fn, ctx);
2✔
2409
         }
2410

2411
         const int nstmts = tree_stmts(expr);
52✔
2412
         for (int i = 0; i < nstmts; i++)
119✔
2413
            build_wait(tree_stmt(expr, i), fn, ctx);
67✔
2414
      }
2415
      break;
2416

2417
   case T_SIGNAL_ASSIGN:
2,608✔
2418
      {
2419
         build_wait_for_target(tree_target(expr), fn, ctx);
2,608✔
2420

2421
         const int nwaves = tree_waveforms(expr);
2,608✔
2422
         for (int i = 0; i < nwaves; i++)
5,390✔
2423
            build_wait(tree_waveform(expr, i), fn, ctx);
2,782✔
2424
      }
2425
      break;
2426

2427
   case T_VAR_ASSIGN:
16✔
2428
   case T_FORCE:
2429
      build_wait_for_target(tree_target(expr), fn, ctx);
16✔
2430
      build_wait(tree_value(expr), fn, ctx);
16✔
2431
      break;
16✔
2432

2433
   case T_RELEASE:
3✔
2434
      build_wait_for_target(tree_target(expr), fn, ctx);
3✔
2435
      break;
3✔
2436

2437
   case T_CASE:
46✔
2438
   case T_MATCH_CASE:
2439
      {
2440
         build_wait(tree_value(expr), fn, ctx);
46✔
2441

2442
         const int nstmts = tree_stmts(expr);
46✔
2443
         for (int i = 0; i < nstmts; i++) {
281✔
2444
            tree_t alt = tree_stmt(expr, i);
235✔
2445

2446
            const int nstmts = tree_stmts(alt);
235✔
2447
            for (int j = 0; j < nstmts; j++)
470✔
2448
               build_wait(tree_stmt(alt, j), fn, ctx);
235✔
2449
         }
2450
      }
2451
      break;
2452

2453
   case T_FOR:
16✔
2454
      {
2455
         build_wait(tree_range(expr, 0), fn, ctx);
16✔
2456

2457
         const int nstmts = tree_stmts(expr);
16✔
2458
         for (int i = 0; i < nstmts; i++)
35✔
2459
            build_wait(tree_stmt(expr, i), fn, ctx);
19✔
2460
      }
2461
      break;
2462

2463
   case T_WHILE:
1✔
2464
      build_wait(tree_value(expr), fn, ctx);
1✔
2465
      // Fall-through
2466
   case T_LOOP:
4✔
2467
      {
2468
         const int nstmts = tree_stmts(expr);
4✔
2469
         for (int i = 0; i < nstmts; i++)
20✔
2470
            build_wait(tree_stmt(expr, i), fn, ctx);
16✔
2471
      }
2472
      break;
2473

2474
   case T_NEXT:
9✔
2475
   case T_EXIT:
2476
      if (tree_has_value(expr))
9✔
2477
         build_wait(tree_value(expr), fn, ctx);
6✔
2478
      break;
2479

2480
   case T_RANGE:
150✔
2481
      if (tree_subkind(expr) == RANGE_EXPR)
150✔
2482
         build_wait(tree_value(expr), fn, ctx);
11✔
2483
      else {
2484
         build_wait(tree_left(expr), fn, ctx);
139✔
2485
         build_wait(tree_right(expr), fn, ctx);
139✔
2486
      }
2487
      break;
2488

2489
   case T_OPEN:
2490
      break;
2491

2492
   default:
×
2493
      fatal_trace("Cannot handle tree kind %s in wait expression",
2494
                  tree_kind_str(tree_kind(expr)));
2495
   }
2496
}
14,042✔
2497

2498
void print_syntax(const char *fmt, ...)
2,091✔
2499
{
2500
   LOCAL_TEXT_BUF tb = tb_new();
2,091✔
2501
   bool highlighting = false;
2,091✔
2502
   static bool comment = false, last_was_newline = false;
2,091✔
2503
   for (const char *p = fmt; *p != '\0'; p++) {
10,929✔
2504
      if (comment) {
8,838✔
2505
         if (*p == '\n' || *p == '\r') {
3,244✔
2506
            comment = false;
94✔
2507
            last_was_newline = true;
94✔
2508
            tb_printf(tb, "$$\n");
94✔
2509
         }
2510
         else if (*p != '~' && *p != '#') {
3,150✔
2511
            tb_append(tb, *p);
2,990✔
2512
            last_was_newline = false;
2,990✔
2513
         }
2514
         if (p > fmt && *p == '/' && *(p - 1) == '*') {
3,244✔
2515
            tb_printf(tb, "$$");
16✔
2516
            comment = false;
16✔
2517
            last_was_newline = false;
16✔
2518
         }
2519
      }
2520
      else if (*p == '\r') {
5,594✔
2521
         if (!last_was_newline) {
21✔
2522
            tb_append(tb, '\n');
×
2523
            last_was_newline = true;
×
2524
         }
2525
      }
2526
      else if (*p == '#' && *(p + 1) != '#') {
5,573✔
2527
         tb_printf(tb, "$bold$$cyan$");
365✔
2528
         last_was_newline = false;
365✔
2529
         highlighting = true;
365✔
2530
      }
2531
      else if (*p == '~' && *(p + 1) != '~') {
5,208✔
2532
         tb_printf(tb, "$yellow$");
1✔
2533
         last_was_newline = false;
1✔
2534
         highlighting = true;
1✔
2535
      }
2536
      else if ((*p == '-' && *(p + 1) == '-')
5,207✔
2537
               || (*p == '/' && *(p + 1) == '/')
5,117✔
2538
               || (*p == '/' && *(p + 1) == '*')) {
5,113✔
2539
         tb_printf(tb, "$red$%c", *p);
110✔
2540
         last_was_newline = false;
110✔
2541
         comment = true;
110✔
2542
      }
2543
      else if (!isalnum_iso88591(*p) && *p != '_'
5,097✔
2544
               && *p != '%' && highlighting) {
2,636✔
2545
         tb_printf(tb, "$$%c", *p);
314✔
2546
         last_was_newline = false;
314✔
2547
         highlighting = false;
314✔
2548
      }
2549
      else {
2550
         tb_append(tb, *p);
4,783✔
2551
         last_was_newline = (*p == '\n');
4,783✔
2552
      }
2553
   }
2554

2555
   if (highlighting)
2,091✔
2556
      tb_cat(tb, "$$");
52✔
2557

2558
   va_list ap;
2,091✔
2559
   va_start(ap, fmt);
2,091✔
2560

2561
   if (syntax_buf != NULL) {
2,091✔
2562
      char *stripped LOCAL = strip_color(tb_get(tb), ap);
4,182✔
2563
      tb_cat(syntax_buf, stripped);
2,091✔
2564
   }
2565
   else
2566
      color_vprintf(tb_get(tb), ap);
×
2567

2568
   va_end(ap);
2,091✔
2569
}
2,091✔
2570

2571
void capture_syntax(text_buf_t *tb)
9✔
2572
{
2573
   assert(tb == NULL || syntax_buf == NULL);
9✔
2574
   syntax_buf = tb;
9✔
2575
}
9✔
2576

2577
void analyse_file(const char *file, jit_t *jit, unit_registry_t *ur,
3,962✔
2578
                  mir_context_t *mc)
2579
{
2580
   input_from_file(file);
3,962✔
2581

2582
   switch (source_kind()) {
3,962✔
2583
   case SOURCE_VHDL:
3,673✔
2584
      {
2585
         lib_t work = lib_work();
3,673✔
2586
         int base_errors = 0;
3,673✔
2587
         tree_t unit;
3,673✔
2588
         while (base_errors = error_count(), (unit = parse())) {
14,147✔
2589
            if (error_count() == base_errors) {
10,474✔
2590
               lib_put(work, unit);
10,474✔
2591
               unit_registry_purge(ur, tree_ident(unit));
10,474✔
2592

2593
               simplify_local(unit, jit, ur, mc);
10,474✔
2594
               bounds_check(unit);
10,474✔
2595
            }
2596
            else
2597
               lib_put_error(work, unit);
×
2598
         }
2599
      }
2600
      break;
2601

2602
   case SOURCE_VERILOG:
289✔
2603
      {
2604
         LOCAL_TEXT_BUF tb = tb_new();
578✔
2605
         vlog_preprocess(tb, true);
289✔
2606

2607
         file_ref_t file_ref = loc_file_ref(file, NULL);
289✔
2608
         input_from_buffer(tb_get(tb), tb_len(tb), file_ref, SOURCE_VERILOG);
289✔
2609

2610
         lib_t work = lib_work();
289✔
2611
         vlog_node_t module;
289✔
2612
         while ((module = vlog_parse())) {
916✔
2613
            if (error_count() == 0) {
338✔
2614
               vlog_check(module);
338✔
2615

2616
               if (error_count() == 0) {
338✔
2617
                  vlog_simp(module);
338✔
2618
                  lib_put_vlog(work, module);
338✔
2619
               }
2620
            }
2621
         }
2622
      }
2623
      break;
289✔
2624

2625
   case SOURCE_SDF:
×
2626
      {
2627
         sdf_file_t *sdf_file = sdf_parse(file, 0);
×
2628
         progress("analysed SDF file: %s", file);
×
2629

2630
         if (sdf_file != NULL) {
×
2631
            warnf("SDF is not yet supported");
×
2632
            sdf_file_free(sdf_file);
×
2633
         }
2634
      }
2635
      break;
2636
   }
2637
}
3,959✔
2638

2639
bool all_character_literals(type_t type)
15,179✔
2640
{
2641
   assert(type_is_enum(type));
15,179✔
2642

2643
   type_t base = type_base_recur(type);
15,179✔
2644
   const int nlits = type_enum_literals(base);
15,179✔
2645
   for (int i = 0; i < nlits; i++) {
74,169✔
2646
      if (ident_char(tree_ident(type_enum_literal(base, i)), 0) != '\'')
64,828✔
2647
         return false;
2648
   }
2649

2650
   return true;
2651
}
2652

2653
bool is_operator_symbol(ident_t ident)
27,555✔
2654
{
2655
   const int len = ident_len(ident);
27,555✔
2656
   if (len < 3)
27,555✔
2657
      return false;
2658
   else if (ident_char(ident, 0) != '"')
27,293✔
2659
      return false;
2660
   else if (ident_char(ident, len - 1) != '"')
15,723✔
2661
      return false;
2662

2663
   const well_known_t wk = is_well_known(ident);
15,723✔
2664

2665
   if (standard() < STD_08)
15,723✔
2666
      return wk >= W_OP_AND && wk <= W_OP_NOT;
3,267✔
2667
   else
2668
      return wk >= W_OP_AND && wk <= W_OP_MATCH_GREATER_EQUAL;
12,456✔
2669
}
2670

2671
bool same_tree(tree_t a, tree_t b)
7,942✔
2672
{
2673
   const tree_kind_t akind = tree_kind(a);
7,942✔
2674
   if (akind != tree_kind(b))
7,942✔
2675
      return false;
2676

2677
   switch (akind) {
7,820✔
2678
   case T_REF:
3,614✔
2679
      return tree_ref(a) == tree_ref(b);
3,614✔
2680
   case T_ARRAY_REF:
1,159✔
2681
      {
2682
         if (!same_tree(tree_value(a), tree_value(b)))
1,159✔
2683
            return false;
2684

2685
         const int nparams = tree_params(a);
1,137✔
2686
         assert(nparams == tree_params(b));
1,137✔
2687

2688
         for (int i = 0; i < nparams; i++) {
2,112✔
2689
            tree_t pa = tree_value(tree_param(a, i));
1,812✔
2690
            tree_t pb = tree_value(tree_param(b, i));
1,812✔
2691
            if (!same_tree(pa, pb))
1,812✔
2692
               return false;
2693
         }
2694

2695
         return true;
2696
      }
2697
   case T_ARRAY_SLICE:
41✔
2698
      {
2699
         if (!same_tree(tree_value(a), tree_value(b)))
41✔
2700
            return false;
2701

2702
         tree_t ra = tree_range(a, 0);
41✔
2703
         tree_t rb = tree_range(b, 0);
41✔
2704

2705
         const range_kind_t rakind = tree_subkind(ra);
41✔
2706
         if (rakind != tree_subkind(rb) || rakind == RANGE_EXPR)
41✔
2707
            return false;
2708

2709
         return same_tree(tree_left(ra), tree_left(rb))
41✔
2710
            && same_tree(tree_right(ra), tree_right(rb));
44✔
2711
      }
2712
   case T_RECORD_REF:
768✔
2713
      return ident_casecmp(tree_ident(a), tree_ident(b))
768✔
2714
         && same_tree(tree_value(a), tree_value(b));
771✔
2715
   case T_LITERAL:
2,064✔
2716
      {
2717
         const literal_kind_t lkind = tree_subkind(a);
2,064✔
2718
         if (lkind != tree_subkind(b))
2,064✔
2719
            return false;
2720

2721
         switch (lkind) {
2,064✔
2722
         case L_PHYSICAL:
24✔
2723
            {
2724
               ident_t aid = tree_has_ident(a) ? tree_ident(a) : NULL;
24✔
2725
               ident_t bid = tree_has_ident(b) ? tree_ident(b) : NULL;
24✔
2726
               if (aid == bid)
24✔
2727
                  return tree_ival(a) == tree_ival(b);
24✔
2728
               else
2729
                  return false;
2730
            }
2731
         case L_INT:
2,017✔
2732
            return tree_ival(a) == tree_ival(b);
2,017✔
2733
         case L_REAL:
23✔
2734
            return tree_dval(a) == tree_dval(b);
23✔
2735
         case L_NULL:
2736
            return true;
2737
         default:
×
2738
            return false;
×
2739
         }
2740
      }
2741
   case T_STRING:
171✔
2742
      {
2743
         const int nchars = tree_chars(a);
171✔
2744
         if (tree_chars(b) != nchars)
171✔
2745
            return false;
2746

2747
         for (int i = 0; i < nchars; i++) {
213✔
2748
            if (!same_tree(tree_char(a, i), tree_char(b, i)))
43✔
2749
               return false;
2750
         }
2751

2752
         return true;
2753
      }
2754
   case T_OPEN:
2755
      return true;
2756
   default:
3✔
2757
      return false;
3✔
2758
   }
2759
}
2760

2761
static range_kind_t get_range_direction(tree_t r)
305✔
2762
{
2763
   assert(tree_kind(r) == T_RANGE);
305✔
2764

2765
   const range_kind_t dir = tree_subkind(r);
305✔
2766
   if (dir != RANGE_EXPR)
305✔
2767
      return dir;
2768

2769
   // Handle ranges like X'RANGE where X has known direction
2770

2771
   tree_t aref = tree_value(r);
43✔
2772
   assert(tree_kind(aref) == T_ATTR_REF);
43✔
2773

2774
   const attr_kind_t kind = tree_subkind(aref);
43✔
2775
   assert(kind == ATTR_RANGE || kind == ATTR_REVERSE_RANGE);
43✔
2776

2777
   type_t prefix_type = tree_type(tree_name(aref));
43✔
2778
   if (type_is_unconstrained(prefix_type))
43✔
2779
      return RANGE_EXPR;
2780

2781
   tree_t prefix_r = range_of(prefix_type, 0);
40✔
2782

2783
   const range_kind_t prefix_dir = get_range_direction(prefix_r);
40✔
2784
   if (prefix_dir != RANGE_TO && prefix_dir != RANGE_DOWNTO)
40✔
2785
      return prefix_dir;
2786
   else if (kind == ATTR_REVERSE_RANGE)
40✔
2787
      return prefix_dir == RANGE_TO ? RANGE_DOWNTO : RANGE_TO;
3✔
2788
   else
2789
      return prefix_dir;
2790
}
2791

2792
bool calculate_aggregate_bounds(tree_t expr, range_kind_t *kind,
6,968✔
2793
                                int64_t *left, int64_t *right)
2794
{
2795
   // Calculate the direction and bounds of an array aggregate using the
2796
   // rules in LRM 93 7.3.2.2
2797

2798
   type_t type = tree_type(expr);
6,968✔
2799
   type_t index_type = index_type_of(type, 0);
6,968✔
2800
   if (index_type == NULL || type_is_none(index_type))
6,968✔
2801
      return false;
1✔
2802

2803
   tree_t index_r = range_of(index_type, 0), base_r = index_r;
6,967✔
2804

2805
   int64_t low, high;
6,967✔
2806
   if (!folded_bounds(index_r, &low, &high))
6,967✔
2807
      return false;
2808

2809
   int64_t clow = INT64_MAX, chigh = INT64_MIN;  // Actual bounds computed below
6,952✔
2810

2811
   range_kind_t dir;
6,952✔
2812
   if (type_is_unconstrained(type))
6,952✔
2813
      dir = tree_subkind(index_r);
6,687✔
2814
   else {
2815
      base_r = range_of(type, 0);
265✔
2816
      dir = get_range_direction(base_r);
265✔
2817
   }
2818

2819
   const int nassocs = tree_assocs(expr);
6,952✔
2820

2821
   if (standard() >= STD_08) {
6,952✔
2822
      // VHDL-2008 range association determines index direction for
2823
      // unconstrained aggregate when the expression type matches the
2824
      // array type
2825
      for (int i = 0; i < nassocs; i++) {
14,326✔
2826
         tree_t a = tree_assoc(expr, i);
10,303✔
2827
         if (tree_subkind(a) == A_SLICE)
10,303✔
2828
            dir = tree_subkind(tree_range(a, 0));
56✔
2829
      }
2830
   }
2831

2832
   if (dir != RANGE_TO && dir != RANGE_DOWNTO)
6,952✔
2833
      return false;
2834

2835
   int64_t pos = 0;
2836
   for (int i = 0; i < nassocs; i++) {
19,532✔
2837
      tree_t a = tree_assoc(expr, i);
17,281✔
2838
      int64_t ilow = 0, ihigh = 0;
17,281✔
2839
      const assoc_kind_t akind = tree_subkind(a);
17,281✔
2840

2841
      switch (akind) {
17,281✔
2842
      case A_NAMED:
592✔
2843
         {
2844
            tree_t name = tree_name(a);
592✔
2845
            if (folded_int(name, &ilow))
592✔
2846
               ihigh = ilow;
582✔
2847
            else
2848
               return false;
4,689✔
2849
         }
2850
         break;
582✔
2851

2852
      case A_RANGE:
1,167✔
2853
      case A_SLICE:
2854
         {
2855
            tree_t r = tree_range(a, 0);
1,167✔
2856
            const range_kind_t rkind = tree_subkind(r);
1,167✔
2857
            if (rkind == RANGE_TO || rkind == RANGE_DOWNTO) {
1,167✔
2858
               tree_t left = tree_left(r), right = tree_right(r);
858✔
2859

2860
               int64_t ileft, iright;
858✔
2861
               if (folded_int(left, &ileft) && folded_int(right, &iright)) {
858✔
2862
                  ilow = (rkind == RANGE_TO ? ileft : iright);
437✔
2863
                  ihigh = (rkind == RANGE_TO ? iright : ileft);
437✔
2864
               }
2865
               else
2866
                  return false;
421✔
2867
            }
2868
            else
2869
               return false;
2870
         }
2871
         break;
2872

2873
      case A_OTHERS:
2874
         return false;
2875

2876
      case A_POS:
9,808✔
2877
         if (i == 0) {
9,808✔
2878
            int64_t ileft;
1,561✔
2879
            if (folded_int(tree_left(base_r), &ileft))
1,561✔
2880
               ilow = ihigh = ileft;
1,561✔
2881
            else
2882
               return false;
×
2883
         }
2884
         else if (dir == RANGE_TO)
8,247✔
2885
            ilow = ihigh = clow + pos;
8,245✔
2886
         else
2887
            ilow = ihigh = chigh - pos;
2✔
2888
         pos++;
9,808✔
2889
         break;
9,808✔
2890

2891
      case A_CONCAT:
5,703✔
2892
         {
2893
            type_t value_type = tree_type(tree_value(a));
5,703✔
2894

2895
            int64_t length;
5,703✔
2896
            if (type_is_unconstrained(value_type))
5,703✔
2897
               return false;
3,938✔
2898
            else if (folded_length(range_of(value_type, 0), &length)) {
2,087✔
2899
               if (i == 0) {
1,765✔
2900
                  int64_t ileft;
1,471✔
2901
                  if (folded_int(tree_left(base_r), &ileft))
1,471✔
2902
                     ilow = ihigh = ileft;
1,471✔
2903
                  else
2904
                     return false;
×
2905
               }
2906
               else if (dir == RANGE_TO) {
294✔
2907
                  ilow = clow + pos;
276✔
2908
                  ihigh = ilow + length - 1;
276✔
2909
               }
2910
               else {
2911
                  ihigh = chigh - pos;
18✔
2912
                  ilow = ihigh - length + 1;
18✔
2913
               }
2914
               pos += length;
1,765✔
2915
            }
2916
            else
2917
               return false;
2918
         }
2919
         break;
2920
      }
2921

2922
      clow = MIN(clow, ilow);
12,592✔
2923
      chigh = MAX(chigh, ihigh);
12,592✔
2924
   }
2925

2926
   if (clow < low || chigh > high)
2,251✔
2927
      return false;   // Will raise a bounds check error later
2928

2929
   *kind = dir;
2,246✔
2930
   *left = dir == RANGE_TO ? clow : chigh;
2,246✔
2931
   *right = dir == RANGE_TO ? chigh : clow;
2,246✔
2932

2933
   return true;
2,246✔
2934
}
2935

2936
type_t calculate_aggregate_subtype(tree_t expr)
5,841✔
2937
{
2938
   range_kind_t dir;
5,841✔
2939
   int64_t ileft, iright;
5,841✔
2940
   if (!calculate_aggregate_bounds(expr, &dir, &ileft, &iright))
5,841✔
2941
      return NULL;
2942

2943
   type_t type = tree_type(expr);
2,228✔
2944

2945
   const int ndims = dimension_of(type);
2,228✔
2946
   type_t a0_type = NULL;
2,228✔
2947
   if (ndims > 1) {
2,228✔
2948
      a0_type = tree_type(tree_value(tree_assoc(expr, 0)));
66✔
2949
      if (type_is_unconstrained(a0_type))
66✔
2950
         return NULL;
2951

2952
      assert(dimension_of(a0_type) == ndims - 1);
66✔
2953
   }
2954

2955
   type_t index_type = index_type_of(type, 0);
2,228✔
2956

2957
   tree_t left = get_discrete_lit(expr, index_type, ileft);
2,228✔
2958
   tree_t right = get_discrete_lit(expr, index_type, iright);
2,228✔
2959
   assert(left != NULL && right != NULL);
2,228✔
2960

2961
   type_t sub = type_new(T_SUBTYPE);
2,228✔
2962
   type_set_base(sub, type_base_recur(type));
2,228✔
2963

2964
   type_t elem = type_elem(type);
2,228✔
2965
   if (type_is_unconstrained(elem)) {
2,228✔
2966
      tree_t a0 = tree_assoc(expr, 0);
106✔
2967
      switch (tree_subkind(a0)) {
106✔
2968
      case A_CONCAT:
6✔
2969
      case A_SLICE:
2970
         a0_type = type_elem(tree_type(tree_value(a0)));
6✔
2971
         break;
6✔
2972
      default:
100✔
2973
         a0_type = tree_type(tree_value(a0));
100✔
2974
         break;
100✔
2975
      }
2976

2977
      if (!type_is_unconstrained(a0_type))
106✔
2978
         elem = a0_type;
62✔
2979
   }
2980

2981
   type_set_elem(sub, elem);
2,228✔
2982

2983
   tree_t cons = tree_new(T_CONSTRAINT);
2,228✔
2984
   tree_set_subkind(cons, C_INDEX);
2,228✔
2985

2986
   tree_t r = tree_new(T_RANGE);
2,228✔
2987
   tree_set_subkind(r, dir);
2,228✔
2988
   tree_set_type(r, index_type);
2,228✔
2989
   tree_set_left(r, left);
2,228✔
2990
   tree_set_right(r, right);
2,228✔
2991

2992
   tree_add_range(cons, r);
2,228✔
2993

2994
   for (int i = 1; i < ndims; i++)
2,294✔
2995
      tree_add_range(cons, range_of(a0_type, i - 1));
66✔
2996

2997
   type_set_constraint(sub, cons);
2,228✔
2998

2999
   return sub;
2,228✔
3000
}
3001

3002
bool can_be_signal(type_t type)
15,919✔
3003
{
3004
   switch (type_kind(type)) {
27,948✔
3005
   case T_RECORD:
3,288✔
3006
      {
3007
         const int nfields = type_fields(type);
3,288✔
3008
         for (int i = 0; i < nfields; i++) {
12,994✔
3009
            if (!can_be_signal(tree_type(type_field(type, i))))
10,498✔
3010
               return false;
3011
         }
3012

3013
         return true;
3014
      }
3015
   case T_ARRAY:
4,648✔
3016
      return can_be_signal(type_elem(type));
4,648✔
3017
   case T_SUBTYPE:
7,381✔
3018
      return can_be_signal(type_base(type));
7,381✔
3019
   case T_ACCESS:
3020
   case T_FILE:
3021
   case T_PROTECTED:
3022
   case T_INCOMPLETE:
3023
      return false;
3024
   default:
9,178✔
3025
      return true;
9,178✔
3026
   }
3027
}
3028

3029
type_t merge_constraints(type_t to, type_t from)
971✔
3030
{
3031
   assert(type_is_unconstrained(to));
971✔
3032
   assert(type_eq(to, from));
971✔
3033

3034
   tree_t cto = NULL;
971✔
3035
   if (type_kind(to) == T_SUBTYPE && type_has_constraint(to))
971✔
3036
      cto = type_constraint(to);
23✔
3037

3038
   tree_t cfrom = NULL;
971✔
3039
   if (type_kind(from) == T_SUBTYPE && type_has_constraint(from))
971✔
3040
      cfrom = type_constraint(from);
758✔
3041

3042
   if (cfrom == NULL)
758✔
3043
      return to;
213✔
3044

3045
   type_t sub = type_new(T_SUBTYPE);
758✔
3046
   type_set_base(sub, type_base_recur(to));
758✔
3047

3048
   if (type_is_array(to)) {
758✔
3049
      type_set_constraint(sub, cto ?: cfrom);
1,496✔
3050

3051
      type_t elem = type_elem(to);
753✔
3052
      if (type_is_unconstrained(elem))
753✔
3053
         type_set_elem(sub, merge_constraints(elem, type_elem(from)));
14✔
3054
      else
3055
         type_set_elem(sub, elem);
739✔
3056
   }
3057
   else {
3058
      tree_t cnew = tree_new(T_CONSTRAINT);
5✔
3059
      tree_set_subkind(cnew, C_RECORD);
5✔
3060
      tree_set_loc(cnew, tree_loc(cto ?: cfrom));
6✔
3061

3062
      type_set_constraint(sub, cnew);
5✔
3063

3064
      if (cto != NULL) {
5✔
3065
         const int nto = tree_ranges(cto);
4✔
3066
         for (int i = 0; i < nto; i++)
8✔
3067
            tree_add_range(cnew, tree_range(cto, i));
4✔
3068
      }
3069

3070
      const int nfrom = tree_ranges(cfrom), base = tree_ranges(cnew);
5✔
3071
      for (int i = 0; i < nfrom; i++) {
13✔
3072
         tree_t ec = tree_range(cfrom, i);
8✔
3073
         assert(tree_kind(ec) == T_ELEM_CONSTRAINT);
8✔
3074

3075
         ident_t id = tree_ident(ec);
8✔
3076
         bool found = false;
8✔
3077
         for (int j = 0; j < base && !found; j++)
15✔
3078
            found |= tree_ident(tree_range(cnew, j)) == id;
7✔
3079

3080
         if (!found)
8✔
3081
            tree_add_range(cnew, ec);
4✔
3082
      }
3083
   }
3084

3085
   return sub;
3086
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc