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

nickg / nvc / 21458432965

28 Jan 2026 10:49PM UTC coverage: 92.632% (+0.02%) from 92.616%
21458432965

Pull #1384

github

web-flow
Merge a7f274965 into 71ebda0ca
Pull Request #1384: Random signal initialization plugin.

17 of 34 new or added lines in 1 file covered. (50.0%)

1096 existing lines in 29 files now uncovered.

76515 of 82601 relevant lines covered (92.63%)

444886.01 hits per line

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

94.12
/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 "printf.h"
28
#include "scan.h"
29
#include "thread.h"
30
#include "type.h"
31
#include "vlog/vlog-phase.h"
32
#include "sdf/sdf-phase.h"
33
#include "sdf/sdf-util.h"
34

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

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

46
int64_t assume_int(tree_t t)
605,792✔
47
{
48
   int64_t value;
605,792✔
49
   if (folded_int(t, &value))
605,792✔
50
      return value;
605,792✔
51

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

56
void range_bounds(tree_t r, int64_t *low, int64_t *high)
96,668✔
57
{
58
   assert(tree_kind(r) == T_RANGE);
96,668✔
59

60
   const int64_t left = assume_int(tree_left(r));
96,668✔
61
   const int64_t right = assume_int(tree_right(r));
96,668✔
62

63
   *low  = tree_subkind(r) == RANGE_TO ? left : right;
96,668✔
64
   *high = tree_subkind(r) == RANGE_TO ? right : left;
96,668✔
65
}
96,668✔
66

67
bool folded_int(tree_t t, int64_t *l)
4,692,547✔
68
{
69
   switch (tree_kind(t)) {
4,736,745✔
70
   case T_LITERAL:
2,907,072✔
71
      switch (tree_subkind(t)) {
2,907,072✔
72
      case L_PHYSICAL:
18,236✔
73
         if (tree_has_ref(t))
18,236✔
74
            return false;
75
         // Fall-through
76
      case L_INT:
77
         *l = tree_ival(t);
2,833,395✔
78
         return true;
2,833,395✔
79
      default:
80
         return false;
81
      }
82
   case T_QUALIFIED:
352✔
83
      return folded_int(tree_value(t), l);
352✔
84
   case T_REF:
1,592,123✔
85
      if (tree_has_ref(t)) {
1,592,123✔
86
         tree_t decl = tree_ref(t);
1,592,122✔
87
         switch (tree_kind(decl)) {
1,592,122✔
88
         case T_CONST_DECL:
51,520✔
89
            if (tree_has_value(decl))
51,520✔
90
               return folded_int(tree_value(decl), l);
43,369✔
91
            else
92
               return false;
93
         case T_ENUM_LIT:
1,461,470✔
94
            *l = tree_pos(decl);
1,461,470✔
95
            return true;
1,461,470✔
96
         case T_ALIAS:
477✔
97
            return folded_int(tree_value(decl), l);
477✔
98
         default:
99
            return false;
100
         }
101
      }
102
      // Fall-through
103
   default:
104
      return false;
105
   }
106
}
107

108
bool folded_real(tree_t t, double *l)
245,009✔
109
{
110
   switch (tree_kind(t)) {
245,018✔
111
   case T_LITERAL:
236,058✔
112
      if (tree_subkind(t) == L_REAL) {
236,058✔
113
         *l = tree_dval(t);
235,864✔
114
         return true;
235,864✔
115
      }
116
      else
117
         return false;
118
   case T_QUALIFIED:
9✔
119
      return folded_real(tree_value(t), l);
9✔
120
   default:
121
      return false;
122
   }
123
}
124

125
bool folded_length(tree_t r, int64_t *l)
69,474✔
126
{
127
   int64_t low, high;
69,474✔
128
   if (folded_bounds(r, &low, &high)) {
69,474✔
129
      *l = MAX(high - low + 1, 0);
65,507✔
130
      return true;
65,507✔
131
   }
132
   else
133
      return false;
134
}
135

136
bool folded_bounds(tree_t r, int64_t *low, int64_t *high)
1,889,565✔
137
{
138
   assert(tree_kind(r) == T_RANGE);
1,889,565✔
139

140
   const range_kind_t rkind = tree_subkind(r);
1,889,565✔
141

142
   if (rkind != RANGE_TO && rkind != RANGE_DOWNTO)
1,889,565✔
143
      return false;
144

145
   int64_t left, right;
1,881,717✔
146
   if (!folded_int(tree_left(r), &left))
1,881,717✔
147
      return false;
148
   else if (!folded_int(tree_right(r), &right))
1,754,564✔
149
      return false;
150

151
   switch (rkind) {
1,711,107✔
152
   case RANGE_TO:
1,582,709✔
153
      *low  = left;
1,582,709✔
154
      *high = right;
1,582,709✔
155
      return true;
1,582,709✔
156
   case RANGE_DOWNTO:
128,398✔
157
      *low  = right;
128,398✔
158
      *high = left;
128,398✔
159
      return true;
128,398✔
160
   default:
161
      return false;
162
   }
163
}
164

165
bool folded_bounds_real(tree_t r, double *low, double *high)
89,207✔
166
{
167
   assert(tree_kind(r) == T_RANGE);
89,207✔
168

169
   const range_kind_t rkind = tree_subkind(r);
89,207✔
170

171
   if (rkind != RANGE_TO && rkind != RANGE_DOWNTO)
89,207✔
172
      return false;
173

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

193
bool folded_bool(tree_t t, bool *b)
39,495✔
194
{
195
   if (tree_kind(t) == T_REF) {
39,495✔
196
      tree_t decl = tree_ref(t);
9,345✔
197
      if (tree_kind(decl) == T_ENUM_LIT
9,345✔
198
          && type_ident(tree_type(decl)) == well_known(W_STD_BOOL)) {
6,803✔
199
         *b = (tree_pos(decl) == 1);
6,803✔
200
         return true;
6,803✔
201
      }
202
   }
203

204
   return false;
205
}
206

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

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

218
   return b;
7,179✔
219
}
220

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

229
   return f;
39,419✔
230
}
231

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

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

254
   return f;
×
255
}
256

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

348
   while (isspace_iso88591(*str))
94✔
349
      ++str;
10✔
350

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

357
         if (is_negative) ++str;
59✔
358

359
         int64_t sum = 0;
360
         for (; isdigit_iso88591(*str) || (*str == '_'); str++) {
162✔
361
            if (*str != '_') {
103✔
362
               sum *= 10;
101✔
363
               sum += (*str - '0');
101✔
364
               num_digits++;
101✔
365
            }
366
         }
367

368
         value->integer = is_negative ? -sum : sum;
59✔
369

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

446
   default:
447
      return false;
448
   }
449

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

455
   return true;
456
}
457

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

468
vhdl_standard_t standard(void)
2,721,578✔
469
{
470
   return current_std;
2,721,578✔
471
}
472

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

479
void set_default_standard(vhdl_standard_t s)
481✔
480
{
481
   if (!have_set_std)
481✔
482
      set_standard(s);
99✔
483
}
481✔
484

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

491
   if ((unsigned)s < ARRAY_LEN(text))
5,074✔
492
      return text[s];
5,074✔
493
   else
494
      return "????";
495
}
496

497
tree_t find_element_mode_indication(tree_t view, tree_t field, bool *converse)
518✔
498
{
499
   switch (tree_kind(view)) {
1,608✔
500
   case T_REF:
697✔
501
      return find_element_mode_indication(tree_ref(view), field, converse);
697✔
502

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

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

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

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

523
         return NULL;
524
      }
525

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

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

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

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

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

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

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

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

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

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

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

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

773
bool is_literal(tree_t t)
53,524✔
774
{
775
   switch (tree_kind(t)) {
53,524✔
776
   case T_REF:
16,040✔
777
      return tree_has_ref(t) && tree_kind(tree_ref(t)) == T_ENUM_LIT;
17,916✔
778
   case T_LITERAL:
779
      return true;
780
   case T_STRING:
23,377✔
781
   default:
782
      return false;
23,377✔
783
   }
784
}
785

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

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

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

823
tree_t aliased_type_decl(tree_t decl)
135,757✔
824
{
825
   switch (tree_kind(decl)) {
136,027✔
826
   case T_ALIAS:
272✔
827
      {
828
         tree_t value = tree_value(decl);
272✔
829
         const tree_kind_t kind = tree_kind(value);
272✔
830
         if (kind == T_REF && tree_has_ref(value))
272✔
831
            return aliased_type_decl(tree_ref(value));
270✔
832
         else if (kind == T_ATTR_REF && is_type_attribute(tree_subkind(value)))
2✔
833
             return value;
834
         else
835
            return NULL;
×
836
      }
837
   case T_TYPE_DECL:
838
   case T_SUBTYPE_DECL:
839
   case T_PROT_DECL:
840
   case T_PROT_BODY:
841
      return decl;
842
   case T_GENERIC_DECL:
1,566✔
843
      if (tree_class(decl) == C_TYPE)
1,566✔
844
         return decl;
845
      else
846
         return NULL;
752✔
847
   default:
33,014✔
848
      return NULL;
33,014✔
849
   }
850
}
851

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

859
   switch (kind) {
167,059✔
860
   case P_NAMED:
140✔
861
      assert(name != NULL);
140✔
862
      tree_set_name(p, name);
140✔
863
      break;
140✔
864
   case P_POS:
166,919✔
865
      tree_set_pos(p, tree_params(call));
166,919✔
866
      break;
166,919✔
867
   }
868

869
   tree_add_param(call, p);
167,059✔
870
   return p;
167,059✔
871
}
872

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

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

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

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

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

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

899
      tree_t constraint = tree_new(T_CONSTRAINT);
306✔
900
      tree_set_subkind(constraint, C_INDEX);
306✔
901

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

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

915
         type_add_index(base, tree_type(r));
336✔
916
         tree_add_range(constraint, r);
336✔
917
      }
918

919
      return sub;
920
   }
921
}
922

923
unsigned bits_for_range(int64_t low, int64_t high)
1,531,724✔
924
{
925
   if (low > high)
1,531,724✔
926
      return 0;   // Null range
927
   else if (low < 0) {
1,531,724✔
928
      // Signed integers
929
      if (low >= INT8_MIN && high <= INT8_MAX)
461,017✔
930
         return 8;
931
      else if (low >= INT16_MIN && high <= INT16_MAX)
461,002✔
932
         return 16;
933
      else if (low >= INT32_MIN && high <= INT32_MAX)
460,984✔
934
         return 32;
935
      else
936
         return 64;
68,338✔
937
   }
938
   else {
939
      // Unsigned integers
940
      if (high <= 1)
1,070,707✔
941
         return 1;
942
      else if (high <= UINT8_MAX)
594,177✔
943
         return 8;
944
      else if (high <= UINT16_MAX)
3,419✔
945
         return 16;
946
      else if (high <= UINT32_MAX)
3,272✔
947
         return 32;
948
      else
949
         return 64;
54✔
950
   }
951
}
952

953
unsigned dimension_of(type_t type)
1,461,903✔
954
{
955
   switch (type_kind(type)) {
2,753,166✔
956
   case T_SUBTYPE:
1,291,261✔
957
      return dimension_of(type_base(type));
1,291,261✔
958
   case T_GENERIC:
235✔
959
      switch (type_subkind(type)) {
235✔
960
      case GTYPE_ARRAY:
199✔
961
         return type_indexes(type);
199✔
962
      case GTYPE_ACCESS:
×
963
         return dimension_of(type_designated(type));
×
964
      case GTYPE_FILE:
965
      case GTYPE_PRIVATE:
966
         return 0;
967
      default:
36✔
968
         return 1;
36✔
969
      }
970
   case T_ARRAY:
1,454,336✔
971
      return type_indexes(type);
1,454,336✔
972
   case T_NONE:
973
   case T_RECORD:
974
   case T_INCOMPLETE:
975
   case T_FILE:
976
   case T_SIGNATURE:
977
      return 0;
978
   case T_INTEGER:
7,260✔
979
   case T_REAL:
980
   case T_PHYSICAL:
981
   case T_ENUM:
982
      return type_dims(type);
7,260✔
983
   case T_ACCESS:
2✔
984
      return dimension_of(type_designated(type));
2✔
985
   default:
×
986
      fatal_trace("invalid type kind %s in dimension_of",
987
                  type_kind_str(type_kind(type)));
988
   }
989
}
990

991
tree_t range_of(type_t type, unsigned dim)
2,137,996✔
992
{
993
   switch (type_kind(type)) {
2,167,034✔
994
   case T_SUBTYPE:
1,669,941✔
995
      if (type_has_constraint(type)) {
1,669,941✔
996
         tree_t c = type_constraint(type);
1,640,903✔
997
         switch (tree_subkind(c)) {
1,640,903✔
998
         case C_INDEX:
1,640,903✔
999
         case C_RANGE:
1000
            if (dim < tree_ranges(c))
1,640,903✔
1001
               return tree_range(c, dim);
1,640,902✔
1002
            else
1003
               return NULL;   // Must be an error
1004
         default:
×
1005
            should_not_reach_here();
1006
         }
1007
      }
1008
      else
1009
         return range_of(type_base(type), dim);
29,038✔
1010
   case T_INTEGER:
497,093✔
1011
   case T_REAL:
1012
   case T_PHYSICAL:
1013
   case T_ENUM:
1014
      return type_dim(type, dim);
497,093✔
1015
   default:
×
1016
      fatal_trace("invalid type kind %s for %s in range_of",
1017
                  type_kind_str(type_kind(type)), type_pp(type));
1018
   }
1019
}
1020

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

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

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

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

1061
type_t index_type_of(type_t type, unsigned dim)
240,767✔
1062
{
1063
   if (dim >= dimension_of(type))
240,769✔
1064
      return NULL;
1065

1066
   type_t base = type_base_recur(type);
240,729✔
1067
   type_kind_t base_kind = type_kind(base);
240,729✔
1068
   if (base_kind == T_ARRAY)
240,729✔
1069
      return type_index(base, dim);
237,115✔
1070
   else if (base_kind == T_ENUM || base_kind == T_NONE)
3,614✔
1071
      return type;
1072
   else if (base_kind == T_GENERIC && type_subkind(base) == GTYPE_ARRAY)
3,456✔
1073
      return type_index(base, dim);
127✔
1074
   else if (base_kind == T_RECORD || base_kind == T_GENERIC)
3,329✔
1075
      return NULL;
1076
   else if (base_kind == T_ACCESS)
3,311✔
1077
      return index_type_of(type_designated(type), dim);
2✔
1078
   else
1079
      return tree_type(range_of(base, dim));
3,309✔
1080
}
1081

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

1090
ident_t well_known(well_known_t id)
382,536✔
1091
{
1092
   assert(id < NUM_WELL_KNOWN);
382,536✔
1093
   return id_cache[id];
382,536✔
1094
}
1095

1096
well_known_t is_well_known(ident_t ident)
264,671✔
1097
{
1098
   return ident_key(ident);
264,671✔
1099
}
1100

1101
void intern_strings(void)
5,746✔
1102
{
1103
   static const char *tab[] = {
5,746✔
1104
      [W_STD_STANDARD]   = "STD.STANDARD",
1105
      [W_ALL]            = "all",
1106
      [W_STD_BIT]        = "STD.STANDARD.BIT",
1107
      [W_STD_BOOL]       = "STD.STANDARD.BOOLEAN",
1108
      [W_STD_CHAR]       = "STD.STANDARD.CHARACTER",
1109
      [W_STD_NATURAL]    = "STD.STANDARD.NATURAL",
1110
      [W_STD_POSITIVE]   = "STD.STANDARD.POSITIVE",
1111
      [W_STD_INTEGER]    = "STD.STANDARD.INTEGER",
1112
      [W_STD_STRING]     = "STD.STANDARD.STRING",
1113
      [W_STD_REAL]       = "STD.STANDARD.REAL",
1114
      [W_STD_TIME]       = "STD.STANDARD.TIME",
1115
      [W_STD_BIT_VECTOR] = "STD.STANDARD.BIT_VECTOR",
1116

1117
      [W_IEEE_SIGNED]   = "IEEE.NUMERIC_STD.SIGNED",
1118
      [W_IEEE_UNSIGNED] = "IEEE.NUMERIC_STD.UNSIGNED",
1119
      [W_IEEE_LOGIC]    = "IEEE.STD_LOGIC_1164.STD_LOGIC",
1120
      [W_IEEE_ULOGIC]   = "IEEE.STD_LOGIC_1164.STD_ULOGIC",
1121

1122
      [W_IEEE_1164_AND]  = "IEEE.STD_LOGIC_1164.\"and\"",
1123
      [W_IEEE_1164_NAND] = "IEEE.STD_LOGIC_1164.\"nand\"",
1124
      [W_IEEE_1164_OR]   = "IEEE.STD_LOGIC_1164.\"or\"",
1125
      [W_IEEE_1164_NOR]  = "IEEE.STD_LOGIC_1164.\"nor\"",
1126
      [W_IEEE_1164_XOR]  = "IEEE.STD_LOGIC_1164.\"xor\"",
1127
      [W_IEEE_1164_XNOR] = "IEEE.STD_LOGIC_1164.\"xnor\"",
1128

1129
      [W_FOREIGN]         = "FOREIGN",
1130
      [W_WORK]            = "WORK",
1131
      [W_STD]             = "STD",
1132
      [W_THUNK]           = "thunk",
1133
      [W_BODY]            = "body",
1134
      [W_CARET]           = "^",
1135
      [W_IEEE]            = "IEEE",
1136
      [W_IEEE_1164]       = "IEEE.STD_LOGIC_1164",
1137
      [W_ERROR]           = "$error",
1138
      [W_ELAB]            = "elab",
1139
      [W_NUMERIC_STD]     = "IEEE.NUMERIC_STD",
1140
      [W_NUMERIC_BIT]     = "IEEE.NUMERIC_BIT",
1141
      [W_NVC]             = "NVC",
1142
      [W_DEFAULT_CLOCK]   = "default clock",
1143
      [W_STD_REFLECTION]  = "STD.REFLECTION",
1144
      [W_NEVER_WAITS]     = "NEVER_WAITS",
1145
      [W_NVC_VERILOG]     = "NVC.VERILOG",
1146
      [W_NVC_PSL_SUPPORT] = "NVC.PSL_SUPPORT",
1147
      [W_INSTANCE_NAME]   = "instance_name",
1148
      [W_PATH_NAME]       = "path_name",
1149
      [W_VITAL]           = "VITAL",
1150
      [W_RESOLUTION]      = "resolution",
1151
      [W_TEXT_UTIL]       = "NVC.TEXT_UTIL",
1152
      [W_VERILOG_LOGIC]   = "NVC.VERILOG.T_LOGIC",
1153
      [W_DLR_SIGNED]      = "$signed",
1154
      [W_DLR_CLOG2]       = "$clog2",
1155
      [W_COUNTERS]        = "#counters",
1156

1157
      [W_IEEE_LOGIC_VECTOR]      = "IEEE.STD_LOGIC_1164.STD_LOGIC_VECTOR",
1158
      [W_IEEE_ULOGIC_VECTOR]     = "IEEE.STD_LOGIC_1164.STD_ULOGIC_VECTOR",
1159
      [W_IEEE_1164_RISING_EDGE]  = "IEEE.STD_LOGIC_1164.RISING_EDGE(sU)B",
1160
      [W_IEEE_1164_FALLING_EDGE] = "IEEE.STD_LOGIC_1164.FALLING_EDGE(sU)B",
1161

1162
      [W_NUMERIC_STD_UNSIGNED] = "IEEE.NUMERIC_STD_UNSIGNED",
1163
      [W_NUMERIC_BIT_UNSIGNED] = "IEEE.NUMERIC_BIT_UNSIGNED",
1164
      [W_VERILOG_NET_VALUE]    = "NVC.VERILOG.T_NET_VALUE",
1165
      [W_VERILOG_WIRE_ARRAY]   = "NVC.VERILOG.T_WIRE_ARRAY",
1166

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

1204
   for (int i = 0; i < ARRAY_LEN(tab); i++)
534,378✔
1205
      id_cache[i] = ident_intern(i, tab[i]);
528,632✔
1206
}
5,746✔
1207

1208
bool is_uninstantiated_package(tree_t pack)
34,058✔
1209
{
1210
   return tree_kind(pack) == T_PACKAGE
34,058✔
1211
      && tree_generics(pack) > 0
32,625✔
1212
      && tree_genmaps(pack) == 0;
35,824✔
1213
}
1214

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

1228
bool is_anonymous_subtype(type_t type)
216,280✔
1229
{
1230
   return type_kind(type) == T_SUBTYPE && !type_has_ident(type);
216,280✔
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;
UNCOV
1238
   case T_PACK_BODY:
×
1239
      {
1240
         tree_t pack = tree_primary(unit);
×
UNCOV
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:
×
UNCOV
1246
      return false;
×
1247
   }
1248
}
1249

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

1254
   const int ndecls = tree_decls(pack);
9,929✔
1255
   for (int i = 0; i < ndecls; i++) {
684,417✔
1256
      tree_t d = tree_decl(pack, i);
683,333✔
1257
      const tree_kind_t dkind = tree_kind(d);
683,333✔
1258
      if ((dkind == T_FUNC_DECL || dkind == T_PROC_DECL)
683,333✔
1259
          && !(tree_flags(d) & TREE_F_PREDEFINED))
612,227✔
1260
         return true;
1261
      else if (dkind == T_CONST_DECL && !tree_has_value(d))
674,957✔
1262
         return true;
1263
      else if (dkind == T_PROT_DECL)
674,594✔
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,341✔
1271
                          well_known_t unit_name)
1272
{
1273
   const vhdl_standard_t curr = standard();
15,341✔
1274

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

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

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

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

1299
   for (int i = 0; i < ndecls; i++) {
775,879✔
1300
      tree_t d = tree_decl(container, i);
775,879✔
1301
      if (is_type_decl(d) && tree_ident(d) == name)
775,879✔
1302
         return d;
14,931✔
1303
   }
1304

1305
   return NULL;
1306
}
1307

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

1313
   if (cache[which] == NULL) {
959,312✔
1314
      const char *names[] = {
14,357✔
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,357✔
1333
      if (d == NULL)
14,357✔
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,357✔
1339
      if (can_cache == -1) can_cache = !opt_get_int(OPT_BOOTSTRAP);
14,357✔
1340

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

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

1355
   if (cache[which] == NULL) {
1,961✔
1356
      static const char *const names[] = {
266✔
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] = {};
266✔
1364
      tree_t unit = cached_unit(NULL, ieee_cache, W_IEEE, W_IEEE_1164);
266✔
1365

1366
      tree_t d = search_type_decls(unit, ident_new(names[which]));
266✔
1367
      if (d == NULL)
266✔
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));
266✔
1372

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

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

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

1390
   if (cache[which] == NULL) {
924✔
1391
      static const char *const names[] = {
276✔
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]));
276✔
1402
      if (d == NULL)
276✔
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));
276✔
1407

1408
      return (cache[which] = tree_type(d));
276✔
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,242,812✔
1442
{
1443
   switch (kind) {
1,242,812✔
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
   case S_IEEE_AND:
1484
   case S_IEEE_OR:
1485
   case S_IEEE_XOR:
1486
   case S_IEEE_NAND:
1487
   case S_IEEE_NOR:
1488
   case S_IEEE_XNOR:
1489
   case S_IEEE_NOT:
1490
      return true;
1491
   default:
504,227✔
1492
      return false;
504,227✔
1493
   }
1494
}
1495

UNCOV
1496
tree_t std_func(ident_t mangled)
×
1497
{
UNCOV
1498
   tree_t std = cached_std(NULL);
×
1499

1500
   const int ndecls = tree_decls(std);
×
1501
   for (int i = 0; i < ndecls; i++) {
×
1502
      tree_t d = tree_decl(std, i);
×
1503
      if (is_subprogram(d) && tree_has_ident2(d) && tree_ident2(d) == mangled)
×
UNCOV
1504
         return d;
×
1505
   }
1506

1507
   return NULL;
1508
}
1509

1510
tree_t verilog_func(ident_t mangled)
410✔
1511
{
1512
   tree_t pack = cached_verilog();
410✔
1513

1514
   const int ndecls = tree_decls(pack);
410✔
1515
   for (int i = 0; i < ndecls; i++) {
43,585✔
1516
      tree_t d = tree_decl(pack, i);
43,585✔
1517
      if (is_subprogram(d) && tree_ident2(d) == mangled)
43,585✔
1518
         return d;
410✔
1519
   }
1520

1521
   fatal_trace("missing Verilog helper function %s", istr(mangled));
1522
}
1523

1524
tree_t name_to_ref(tree_t name)
87,933✔
1525
{
1526
   tree_kind_t kind;
87,933✔
1527
   while ((kind = tree_kind(name)) != T_REF) {
97,503✔
1528
      switch (kind) {
10,848✔
1529
      case T_ARRAY_REF:
9,570✔
1530
      case T_ARRAY_SLICE:
1531
      case T_RECORD_REF:
1532
      case T_ALL:
1533
         name = tree_value(name);
9,570✔
1534
         break;
9,570✔
1535
      default:
1536
         return NULL;
1537
      }
1538
   }
1539

1540
   return name;
1541
}
1542

1543
const char *port_mode_str(port_mode_t mode)
47✔
1544
{
1545
   const char *mode_str[] = {
47✔
1546
      "INVALID", "IN", "OUT", "INOUT", "BUFFER", "LINKAGE", "VIEW", "VIEW"
1547
   };
1548
   assert(mode < ARRAY_LEN(mode_str));
47✔
1549
   return mode_str[mode];
47✔
1550
}
1551

1552
void mangle_one_type(text_buf_t *buf, type_t type)
182,371✔
1553
{
1554
   ident_t ident = type_ident(type);
182,371✔
1555

1556
   char code = 0;
182,371✔
1557
   switch (is_well_known(ident)) {
182,371✔
1558
   case W_STD_INTEGER:        code = 'I'; break;
1559
   case W_STD_STRING:         code = 'S'; break;
3,824✔
1560
   case W_STD_REAL:           code = 'R'; break;
3,555✔
1561
   case W_STD_BOOL:           code = 'B'; break;
24,822✔
1562
   case W_STD_CHAR:           code = 'C'; break;
678✔
1563
   case W_STD_TIME:           code = 'T'; break;
1,116✔
1564
   case W_STD_NATURAL:        code = 'N'; break;
4,294✔
1565
   case W_STD_POSITIVE:       code = 'P'; break;
375✔
1566
   case W_STD_BIT:            code = 'J'; break;
2,698✔
1567
   case W_STD_BIT_VECTOR:     code = 'Q'; break;
3,000✔
1568
   case W_IEEE_LOGIC:         code = 'L'; break;
381✔
1569
   case W_IEEE_ULOGIC:        code = 'U'; break;
5,289✔
1570
   case W_IEEE_LOGIC_VECTOR:  code = 'V'; break;
2,209✔
1571
   case W_IEEE_ULOGIC_VECTOR: code = 'Y'; break;
1,437✔
1572
   default: break;
1573
   }
1574

1575
   if (code)
53,678✔
1576
      tb_append(buf, code);
66,707✔
1577
   else {
1578
      tb_printf(buf, "%zu", ident_len(ident));
115,664✔
1579
      tb_istr(buf, ident);
115,664✔
1580
   }
1581
}
182,371✔
1582

1583
ident_t get_call_context(ident_t mangled)
2,642✔
1584
{
1585
   const char *str = istr(mangled), *p = str, *end = NULL;
2,642✔
1586
   for (; *p; p++) {
95,733✔
1587
      if (*p == '(') break;
91,286✔
1588
      if (*p == '.') end = p;
90,449✔
1589
   }
1590
   assert(end != NULL);
2,642✔
1591

1592
   return ident_new_n(str, end - str);
2,642✔
1593
}
1594

1595
tree_t primary_unit_of(tree_t unit)
27,207✔
1596
{
1597
   switch (tree_kind(unit)) {
27,207✔
1598
   case T_ENTITY:
1599
   case T_COMPONENT:
1600
   case T_PACKAGE:
1601
   case T_BLOCK:
1602
   case T_ELAB:
1603
   case T_PACK_INST:
1604
      return unit;
1605
   case T_ARCH:
17,560✔
1606
   case T_CONFIGURATION:
1607
   case T_PACK_BODY:
1608
      return tree_primary(unit);
17,560✔
UNCOV
1609
   default:
×
1610
      fatal_trace("invalid kind %s in primary_unit_of",
1611
                  tree_kind_str(tree_kind(unit)));
1612
   }
1613
}
1614

1615
unsigned get_case_choice_char(tree_t value, int depth)
11,914✔
1616
{
1617
   switch (tree_kind(value)) {
12,533✔
1618
   case T_STRING:
11,892✔
1619
      if (depth < tree_chars(value))
11,892✔
1620
         return assume_int(tree_char(value, depth));
11,471✔
1621
      else
1622
         return ~0;   // Out of bounds
1623

1624
   case T_AGGREGATE:
22✔
1625
      {
1626
         const int nassocs = tree_assocs(value);
22✔
1627
         type_t type = tree_type(value);
22✔
1628

1629
         for (int i = 0, pos = 0; i < nassocs; i++) {
36✔
1630
            tree_t a = tree_assoc(value, i);
35✔
1631
            switch (tree_subkind(a)) {
35✔
1632
            case A_NAMED:
×
1633
               if (rebase_index(type, 0, assume_int(tree_name(a))) == depth)
×
UNCOV
1634
                  return assume_int(tree_value(a));
×
1635
               break;
1636

1637
            case A_POS:
11✔
1638
               if (pos++ == (unsigned)depth)
11✔
1639
                  return assume_int(tree_value(a));
5✔
1640
               break;
1641

1642
            case A_CONCAT:
24✔
1643
               {
1644
                  tree_t left = tree_value(a);
24✔
1645

1646
                  type_t left_type = tree_type(left);
24✔
1647
                  if (type_is_unconstrained(left_type))
24✔
UNCOV
1648
                     fatal_at(tree_loc(left), "sorry, this expression is not "
×
1649
                              "currently supported in a case choice");
1650

1651
                  tree_t lr = range_of(tree_type(left), 0);
24✔
1652
                  int64_t left_len;
24✔
1653
                  if (!folded_length(lr, &left_len))
24✔
UNCOV
1654
                     fatal_at(tree_loc(left), "cannot determine length of "
×
1655
                              "aggregate element");
1656

1657
                  if (depth < pos + left_len)
24✔
1658
                     return get_case_choice_char(left, depth - pos);
16✔
1659

1660
                  pos += left_len;
8✔
1661
               }
1662
               break;
8✔
1663

1664
            case A_OTHERS:
×
UNCOV
1665
               return assume_int(tree_value(a));
×
1666

UNCOV
1667
            case A_SLICE:
×
1668
               {
1669
                  tree_t base = tree_value(a);
×
UNCOV
1670
                  tree_t r = tree_range(a, 0);
×
1671

1672
                  const int64_t rleft = assume_int(tree_left(r));
×
UNCOV
1673
                  const int64_t rright = assume_int(tree_right(r));
×
1674

1675
                  const int64_t loffset = rebase_index(type, 0, rleft);
×
UNCOV
1676
                  const int64_t roffset = rebase_index(type, 0, rright);
×
1677

1678
                  if (depth >= loffset && depth <= roffset)
×
UNCOV
1679
                     return get_case_choice_char(base, depth - loffset);
×
1680
               }
1681
            }
1682
         }
1683

1684
         // This will produce an error during bounds checking
1685
         return ~0;
1686
      }
1687

1688
   case T_REF:
379✔
1689
      {
1690
         tree_t decl = tree_ref(value);
379✔
1691
         assert(tree_kind(decl) == T_CONST_DECL || tree_kind(decl) == T_ALIAS);
379✔
1692
         assert(tree_has_value(decl));
379✔
1693
         return get_case_choice_char(tree_value(decl), depth);
379✔
1694
      }
1695

1696
   case T_ARRAY_SLICE:
240✔
1697
      {
1698
         tree_t base = tree_value(value);
240✔
1699
         tree_t r = tree_range(value, 0);
240✔
1700
         const int64_t rleft = assume_int(tree_left(r));
240✔
1701
         const int64_t offset = rebase_index(tree_type(base), 0, rleft);
240✔
1702
         return get_case_choice_char(base, depth + offset);
240✔
1703
      }
1704

1705
   default:
×
UNCOV
1706
      fatal_at(tree_loc(value), "unsupported tree type %s in case choice",
×
1707
               tree_kind_str(tree_kind(value)));
1708
   }
1709
}
1710

1711
int64_t encode_case_choice(tree_t value, int length, int bits)
1,630✔
1712
{
1713
   uint64_t enc = 0;
1,630✔
1714
   for (int i = 0; i < length; i++) {
13,506✔
1715
      if (bits > 0) {
11,876✔
1716
         enc <<= bits;
4,343✔
1717
         enc |= get_case_choice_char(value, i);
4,343✔
1718
      }
1719
      else {
1720
         enc *= 0x27d4eb2d;
7,533✔
1721
         enc += get_case_choice_char(value, i);
7,533✔
1722
      }
1723
   }
1724

1725
   return enc;
1,630✔
1726
}
1727

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

1745
      // Find the largest unit that evenly divides the given value
1746
      for (unsigned u = 0; u < nunits; u++) {
216✔
1747
         tree_t unit = type_unit(base, u);
192✔
1748
         const int64_t unit_value = assume_int(tree_value(unit));
192✔
1749
         if ((unit_value > max_unit_value) && (value % unit_value == 0)) {
192✔
1750
            max_unit = unit;
90✔
1751
            max_unit_value = unit_value;
90✔
1752
         }
1753
      }
1754
      assert(max_unit);
24✔
1755

1756
      tb_printf(tb, "%"PRIi64" %s", value / max_unit_value,
24✔
1757
                istr(tree_ident(max_unit)));
1758
   }
1759
   else if (type_is_real(type)) {
57✔
1760
      union { int64_t i; double r; } u = { .i = value };
51✔
1761
      tb_printf(tb, "%.17g", u.r);
51✔
1762
   }
1763
   else if (type_is_access(type)) {
6✔
1764
      if (value == 0)
6✔
1765
         tb_cat(tb, "NULL");
3✔
1766
      else
1767
         tb_printf(tb, "%p", (void *)value);
3✔
1768
   }
1769
}
587✔
1770

1771
static bool is_static(tree_t expr)
2,604✔
1772
{
1773
   switch (tree_kind(expr)) {
2,658✔
1774
   case T_REF:
670✔
1775
      {
1776
         tree_t decl = tree_ref(expr);
670✔
1777
         switch (tree_kind(decl)) {
670✔
1778
         case T_CONST_DECL:
137✔
1779
            return !!(tree_flags(decl) & TREE_F_GLOBALLY_STATIC);
137✔
1780
         case T_UNIT_DECL:
1781
         case T_ENUM_LIT:
1782
         case T_GENERIC_DECL:
1783
            return true;
1784
         case T_ALIAS:
×
UNCOV
1785
            return is_static(tree_value(decl));
×
1786
         default:
196✔
1787
            return false;
196✔
1788
         }
1789
      }
1790

1791
   case T_LITERAL:
1792
   case T_STRING:
1793
      return true;
1794

1795
   case T_FCALL:
172✔
1796
      return !!(tree_flags(expr) & (TREE_F_LOCALLY_STATIC
172✔
1797
                                    | TREE_F_GLOBALLY_STATIC));
1798

1799
   case T_RECORD_REF:
51✔
1800
      return is_static(tree_value(expr));
51✔
1801

1802
   case T_ARRAY_REF:
48✔
1803
      {
1804
         if (!is_static(tree_value(expr)))
48✔
1805
            return false;
1806

1807
         const int nparams = tree_params(expr);
48✔
1808
         for (int i = 0; i < nparams; i++) {
96✔
1809
            if (!is_static(tree_value(tree_param(expr, i))))
48✔
1810
               return false;
1811
         }
1812

1813
         return true;
1814
      }
1815

1816
   case T_ARRAY_SLICE:
24✔
1817
      {
1818
         if (!is_static(tree_value(expr)))
24✔
1819
            return false;
1820

1821
         assert(tree_ranges(expr) == 1);
24✔
1822

1823
         tree_t r = tree_range(expr, 0);
24✔
1824
         if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
24✔
UNCOV
1825
            return false;
×
1826

1827
         return true;
1828
      }
1829

1830
   case T_ATTR_REF:
31✔
1831
      {
1832
         switch (tree_subkind(expr)) {
31✔
1833
         case ATTR_EVENT:
1834
         case ATTR_ACTIVE:
1835
         case ATTR_LAST_EVENT:
1836
         case ATTR_LAST_ACTIVE:
1837
         case ATTR_LAST_VALUE:
1838
         case ATTR_DRIVING:
1839
         case ATTR_DRIVING_VALUE:
1840
         case ATTR_STABLE:
1841
         case ATTR_QUIET:
1842
            return false;
1843
         case ATTR_POS:
3✔
1844
         case ATTR_VAL:
1845
         case ATTR_LEFTOF:
1846
         case ATTR_RIGHTOF:
1847
         case ATTR_SUCC:
1848
         case ATTR_PRED:
1849
         case ATTR_VALUE:
1850
         case ATTR_IMAGE:
1851
            assert(tree_params(expr) == 1);
3✔
1852
            return is_static(tree_value(tree_param(expr, 0)));
3✔
1853
         case ATTR_LENGTH:
28✔
1854
         case ATTR_LEFT:
1855
         case ATTR_RIGHT:
1856
         case ATTR_LOW:
1857
         case ATTR_HIGH:
1858
         case ATTR_RANGE:
1859
         case ATTR_REVERSE_RANGE:
1860
            {
1861
               tree_t ref = name_to_ref(tree_name(expr));
28✔
1862
               if (ref == NULL)
28✔
1863
                  return false;
1864

1865
               switch (tree_kind(tree_ref(ref))) {
28✔
1866
               case T_GENERIC_DECL:
1867
               case T_PORT_DECL:
1868
               case T_SIGNAL_DECL:
1869
               case T_SUBTYPE_DECL:
1870
               case T_TYPE_DECL:
1871
                  return true;
1872
               default:
8✔
1873
                  return false;
8✔
1874
               }
1875
            }
1876
         default:
×
1877
            return true;
×
1878
         }
1879
      }
1880

UNCOV
1881
   default:
×
UNCOV
1882
      return false;
×
1883
   }
1884
}
1885

1886
tree_t longest_static_prefix(tree_t expr)
12,117✔
1887
{
1888
   switch (tree_kind(expr)) {
12,117✔
1889
   case T_ARRAY_REF:
1,754✔
1890
      {
1891
         tree_t value = tree_value(expr);
1,754✔
1892
         tree_t prefix = longest_static_prefix(value);
1,754✔
1893

1894
         if (prefix != value)
1,754✔
1895
            return prefix;
1896

1897
         const int nparams = tree_params(expr);
1,726✔
1898
         for (int i = 0; i < nparams; i++) {
3,411✔
1899
            if (!is_static(tree_value(tree_param(expr, i))))
1,933✔
1900
               return prefix;
1901
         }
1902

1903
         return expr;
1904
      }
1905

1906
   case T_ARRAY_SLICE:
271✔
1907
      {
1908
         tree_t value = tree_value(expr);
271✔
1909
         tree_t prefix = longest_static_prefix(value);
271✔
1910

1911
         if (prefix != value)
271✔
1912
            return prefix;
1913

1914
         assert(tree_ranges(expr) == 1);
264✔
1915

1916
         tree_t r = tree_range(expr, 0);
264✔
1917
         if (tree_subkind(r) == RANGE_EXPR) {
264✔
1918
            if (!is_static(tree_value(r)))
12✔
1919
               return prefix;
5✔
1920
         }
1921
         else if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
252✔
1922
            return prefix;
16✔
1923

1924
         return expr;
1925
      }
1926

1927
   case T_RECORD_REF:
773✔
1928
      {
1929
         tree_t value = tree_value(expr);
773✔
1930
         tree_t prefix = longest_static_prefix(value);
773✔
1931

1932
         if (prefix != value)
773✔
1933
            return prefix;
21✔
1934

1935
         return expr;
1936
      }
1937

1938
   default:
1939
      return expr;
1940
   }
1941
}
1942

1943
tree_t body_of(tree_t pack)
9,071✔
1944
{
1945
   const tree_kind_t kind = tree_kind(pack);
9,071✔
1946
   if (kind == T_PACK_INST)
9,071✔
1947
      return NULL;
1948

1949
   assert(tree_kind(pack) == T_PACKAGE);
9,071✔
1950

1951
   ident_t body_i = well_known(W_BODY);
9,071✔
1952
   ident_t body_name = ident_prefix(tree_ident(pack), body_i, '-');
9,071✔
1953
   return lib_get_qualified(body_name);
9,071✔
1954
}
1955

1956
tree_t find_generic_map(tree_t unit, int pos, tree_t g)
651✔
1957
{
1958
   const int ngenmaps = tree_genmaps(unit);
651✔
1959

1960
   if (pos < ngenmaps) {
651✔
1961
      tree_t m = tree_genmap(unit, pos);
513✔
1962
      if (tree_subkind(m) == P_POS && tree_pos(m) == pos)
513✔
1963
         return tree_value(m);
367✔
1964
   }
1965

1966
   for (int j = 0; j < ngenmaps; j++) {
998✔
1967
      tree_t m = tree_genmap(unit, j);
860✔
1968
      switch (tree_subkind(m)) {
860✔
1969
      case P_NAMED:
440✔
1970
         {
1971
            tree_t name = tree_name(m);
440✔
1972
            assert(tree_kind(name) == T_REF);
440✔
1973

1974
            if (tree_has_ref(name) && tree_ref(name) == g)
440✔
1975
               return tree_value(m);
15✔
1976
         }
1977
         break;
1978

1979
      case P_POS:
420✔
1980
         if (tree_pos(m) == pos)
420✔
1981
            return tree_value(m);
131✔
1982
         break;
1983

1984
      default:
1985
         break;
1986
      }
1987
   }
1988

1989
   return NULL;
1990
}
1991

1992
bool relaxed_rules(void)
544,774✔
1993
{
1994
   return opt_get_int(OPT_RELAXED);
544,774✔
1995
}
1996

1997
bool is_type_attribute(attr_kind_t kind)
72,803✔
1998
{
1999
   switch (kind) {
72,803✔
2000
   case ATTR_SUBTYPE:
2001
   case ATTR_BASE:
2002
   case ATTR_ELEMENT:
2003
   case ATTR_DESIGNATED_SUBTYPE:
2004
   case ATTR_INDEX:
2005
      return true;
2006
   default:
72,020✔
2007
      return false;
72,020✔
2008
   }
2009
}
2010

2011
bool attribute_has_param(attr_kind_t attr)
24,219✔
2012
{
2013
   switch (attr) {
24,219✔
2014
   case ATTR_IMAGE:
2015
   case ATTR_SUCC:
2016
   case ATTR_PRED:
2017
   case ATTR_DELAYED:
2018
   case ATTR_LEFTOF:
2019
   case ATTR_RIGHTOF:
2020
   case ATTR_VALUE:
2021
   case ATTR_POS:
2022
   case ATTR_LOW:
2023
   case ATTR_HIGH:
2024
   case ATTR_LEFT:
2025
   case ATTR_RIGHT:
2026
   case ATTR_LENGTH:
2027
   case ATTR_RANGE:
2028
   case ATTR_REVERSE_RANGE:
2029
   case ATTR_VAL:
2030
   case ATTR_QUIET:
2031
   case ATTR_STABLE:
2032
   case ATTR_INDEX:
2033
   case ATTR_ASCENDING:
2034
      return true;
2035
   default:
2,333✔
2036
      return false;
2,333✔
2037
   }
2038
}
2039

2040
type_t get_type_or_null(tree_t t)
2,300,158✔
2041
{
2042
   switch (tree_kind(t)) {
2,300,158✔
2043
   case T_LIBRARY:
2044
   case T_ATTR_SPEC:
2045
   case T_PACKAGE:
2046
   case T_PACK_INST:
2047
   case T_PACK_BODY:
2048
   case T_ENTITY:
2049
   case T_ARCH:
2050
   case T_PROCESS:
2051
   case T_COMPONENT:
2052
   case T_INSTANCE:
2053
   case T_CONCURRENT:
2054
   case T_BLOCK:
2055
   case T_WHILE:
2056
   case T_FOR:
2057
   case T_LOOP:
2058
   case T_GROUP_TEMPLATE:
2059
   case T_CONFIGURATION:
2060
   case T_GROUP:
2061
   case T_FOR_GENERATE:
2062
   case T_IF_GENERATE:
2063
   case T_CASE_GENERATE:
2064
   case T_USE:
2065
   case T_CONTEXT:
2066
   case T_PSL_DECL:
2067
   case T_PSL_DIRECT:
2068
   case T_WAVEFORM:
2069
      return NULL;
2070
   default:
2,206,599✔
2071
      if (tree_has_type(t))
2,206,599✔
2072
         return tree_type(t);
2,205,125✔
2073
      else
2074
         return NULL;
2075
   }
2076
}
2077

2078
type_t subtype_for_string(tree_t str, type_t base)
26,187✔
2079
{
2080
   if (type_const_bounds(base))
26,187✔
2081
      return base;    // Can be checked statically
2082
   else if (!type_is_unconstrained(base))
22,925✔
2083
      base = type_base_recur(base);
275✔
2084

2085
   // Construct a new constrained array subtype: the direction and
2086
   // bounds are the same as those for a positional array aggregate
2087
   type_t sub = type_new(T_SUBTYPE);
22,925✔
2088
   type_set_base(sub, base);
22,925✔
2089

2090
   type_t index_type = index_type_of(base, 0);
22,925✔
2091
   const bool is_enum = type_is_enum(index_type);
22,925✔
2092

2093
   // The direction is determined by the index type
2094
   range_kind_t dir = direction_of(index_type, 0);
22,925✔
2095
   tree_t index_r = range_of(index_type, 0);
22,925✔
2096

2097
   // The left bound is the left of the index type and the right bound
2098
   // is determined by the number of elements
2099

2100
   tree_t left = NULL, right = NULL;
22,925✔
2101
   const int nchars = tree_chars(str);
22,925✔
2102

2103
   if (is_enum) {
22,925✔
2104
      const int nlits = type_enum_literals(type_base_recur(index_type));
16✔
2105
      int64_t index_left = assume_int(tree_left(index_r));
16✔
2106

2107
      int64_t iright, ileft;
16✔
2108
      if (nchars == 0) {
16✔
2109
         iright = index_left;
1✔
2110
         ileft = assume_int(tree_right(index_r));
1✔
2111
      }
2112
      else if (dir == RANGE_DOWNTO) {
15✔
UNCOV
2113
         ileft = index_left;
×
UNCOV
2114
         iright = MIN(nlits - 1, MAX(0, index_left - nchars + 1));
×
2115
      }
2116
      else {
2117
         ileft = index_left;
15✔
2118
         iright = MIN(nlits - 1, MAX(0, index_left + nchars - 1));
15✔
2119
      }
2120

2121
      left = get_enum_lit(str, index_type, ileft);
16✔
2122
      right = get_enum_lit(str, index_type, iright);
16✔
2123
   }
2124
   else {
2125
      left = tree_left(index_r);
22,909✔
2126

2127
      int64_t iright;
22,909✔
2128
      if (dir == RANGE_DOWNTO)
22,909✔
UNCOV
2129
         iright = assume_int(left) - nchars + 1;
×
2130
      else
2131
         iright = assume_int(left) + nchars - 1;
22,909✔
2132

2133
      right = get_int_lit(str, index_type, iright);
22,909✔
2134
   }
2135

2136
   tree_t r = tree_new(T_RANGE);
22,925✔
2137
   tree_set_subkind(r, dir);
22,925✔
2138
   tree_set_left(r, left);
22,925✔
2139
   tree_set_right(r, right);
22,925✔
2140
   tree_set_loc(r, tree_loc(str));
22,925✔
2141
   tree_set_type(r, index_type);
22,925✔
2142

2143
   tree_t c = tree_new(T_CONSTRAINT);
22,925✔
2144
   tree_set_subkind(c, C_INDEX);
22,925✔
2145
   tree_add_range(c, r);
22,925✔
2146
   tree_set_loc(c, tree_loc(str));
22,925✔
2147

2148
   type_set_constraint(sub, c);
22,925✔
2149

2150
   return sub;
22,925✔
2151
}
2152

2153
tree_t change_ref(tree_t name, tree_t new)
2,344✔
2154
{
2155
   switch (tree_kind(name)) {
2,344✔
2156
   case T_REF:
1,619✔
2157
      {
2158
         tree_t ref = make_ref(new);
1,619✔
2159
         tree_set_loc(ref, tree_loc(name));
1,619✔
2160
         return ref;
1,619✔
2161
      }
2162

2163
   case T_ARRAY_REF:
112✔
2164
      {
2165
         tree_t value = change_ref(tree_value(name), new);
112✔
2166

2167
         tree_t t = tree_new(T_ARRAY_REF);
112✔
2168
         tree_set_loc(t, tree_loc(name));
112✔
2169
         tree_set_value(t, value);
112✔
2170
         tree_set_type(t, type_elem(tree_type(value)));
112✔
2171

2172
         const int nparams = tree_params(name);
112✔
2173
         for (int i = 0; i < nparams; i++)
224✔
2174
            tree_add_param(t, tree_param(name, i));
112✔
2175

2176
         return t;
2177
      }
2178

2179
   case T_ARRAY_SLICE:
47✔
2180
      {
2181
         tree_t value = change_ref(tree_value(name), new);
47✔
2182
         tree_t r = tree_range(name, 0);
47✔
2183

2184
         tree_t constraint = tree_new(T_CONSTRAINT);
47✔
2185
         tree_set_subkind(constraint, C_INDEX);
47✔
2186
         tree_add_range(constraint, r);
47✔
2187

2188
         type_t slice_type = type_new(T_SUBTYPE);
47✔
2189
         type_set_constraint(slice_type, constraint);
47✔
2190
         type_set_base(slice_type, tree_type(value));
47✔
2191

2192
         tree_t t = tree_new(T_ARRAY_SLICE);
47✔
2193
         tree_set_loc(t, tree_loc(name));
47✔
2194
         tree_set_value(t, value);
47✔
2195
         tree_set_type(t, slice_type);
47✔
2196
         tree_add_range(t, r);
47✔
2197

2198
         return t;
47✔
2199
      }
2200

2201
   case T_RECORD_REF:
404✔
2202
      {
2203
         tree_t t = tree_new(T_RECORD_REF);
404✔
2204
         tree_set_loc(t, tree_loc(name));
404✔
2205
         tree_set_value(t, change_ref(tree_value(name), new));
404✔
2206
         tree_set_type(t, tree_type(name));
404✔
2207
         tree_set_ident(t, tree_ident(name));
404✔
2208
         tree_set_ref(t, tree_ref(name));
404✔
2209

2210
         return t;
404✔
2211
      }
2212

2213
   case T_CONV_FUNC:
153✔
2214
      {
2215
         tree_t t = tree_new(T_CONV_FUNC);
153✔
2216
         tree_set_loc(t, tree_loc(name));
153✔
2217
         tree_set_value(t, change_ref(tree_value(name), new));
153✔
2218
         tree_set_ident(t, tree_ident(name));
153✔
2219
         tree_set_type(t, tree_type(name));
153✔
2220
         tree_set_ref(t, tree_ref(name));
153✔
2221

2222
         return t;
153✔
2223
      }
2224

2225
   case T_TYPE_CONV:
9✔
2226
      {
2227
         tree_t t = tree_new(T_TYPE_CONV);
9✔
2228
         tree_set_loc(t, tree_loc(name));
9✔
2229
         tree_set_type(t, tree_type(name));
9✔
2230
         tree_set_value(t, change_ref(tree_value(name), new));
9✔
2231

2232
         return t;
9✔
2233
      }
2234

UNCOV
2235
   default:
×
2236
      fatal_trace("cannot handle tree kind %s in elab_change_ref",
2237
                  tree_kind_str(tree_kind(name)));
2238
   }
2239
}
2240

2241
static void build_wait_for_target(tree_t expr, build_wait_fn_t fn, void *ctx)
3,028✔
2242
{
2243
   switch (tree_kind(expr)) {
3,028✔
2244
   case T_ARRAY_SLICE:
86✔
2245
      build_wait(tree_range(expr, 0), fn, ctx);
86✔
2246
      break;
86✔
2247

2248
   case T_ARRAY_REF:
576✔
2249
      {
2250
         const int nparams = tree_params(expr);
576✔
2251
         for (int i = 0; i < nparams; i++)
1,152✔
2252
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
576✔
2253
      }
2254
      break;
2255

2256
   default:
2257
      break;
2258
   }
2259
}
3,028✔
2260

2261
void build_wait(tree_t expr, build_wait_fn_t fn, void *ctx)
14,136✔
2262
{
2263
   // LRM 08 section 10.2 has rules for building a wait statement from a
2264
   // sensitivity list. LRM 08 section 11.3 extends these rules to
2265
   // all-sensitised processes.
2266

2267
   switch (tree_kind(expr)) {
17,555✔
2268
   case T_REF:
4,475✔
2269
      if (class_of(tree_ref(expr)) == C_SIGNAL)
4,475✔
2270
         (*fn)(expr, ctx);
2,614✔
2271
      break;
2272

2273
   case T_EXTERNAL_NAME:
7✔
2274
      if (tree_class(expr) == C_SIGNAL)
7✔
2275
         (*fn)(expr, ctx);
7✔
2276
      break;
2277

2278
   case T_WAVEFORM:
2,962✔
2279
   case T_QUALIFIED:
2280
   case T_TYPE_CONV:
2281
   case T_INERTIAL:
2282
      if (tree_has_value(expr))
2,962✔
2283
         build_wait(tree_value(expr), fn, ctx);
2,953✔
2284
      break;
2285

2286
   case T_ASSERT:
405✔
2287
      build_wait(tree_value(expr), fn, ctx);
405✔
2288
      // Fall-through
2289
   case T_REPORT:
409✔
2290
      if (tree_has_message(expr))
409✔
2291
         build_wait(tree_message(expr), fn, ctx);
280✔
2292
      break;
2293

2294
   case T_ARRAY_REF:
828✔
2295
   case T_ARRAY_SLICE:
2296
   case T_RECORD_REF:
2297
      {
2298
         tree_t ref = name_to_ref(expr);
828✔
2299
         if (ref != NULL && class_of(ref) == C_SIGNAL
828✔
2300
             && longest_static_prefix(expr) == expr)
529✔
2301
            (*fn)(expr, ctx);
453✔
2302
         else {
2303
            build_wait(tree_value(expr), fn, ctx);
375✔
2304
            build_wait_for_target(expr, fn, ctx);
375✔
2305
         }
2306
      }
2307
      break;
2308

2309
   case T_FCALL:
2,028✔
2310
   case T_PCALL:
2311
   case T_PROT_FCALL:
2312
   case T_PROT_PCALL:
2313
      {
2314
         tree_t decl = tree_ref(expr);
2,028✔
2315
         const int nparams = tree_params(expr);
2,028✔
2316
         for (int i = 0; i < nparams; i++) {
5,510✔
2317
            tree_t p = tree_param(expr, i), port;
3,482✔
2318
            switch (tree_subkind(p)) {
3,482✔
2319
            case P_POS:
3,482✔
2320
               port = tree_port(decl, tree_pos(p));
3,482✔
2321
               break;
3,482✔
UNCOV
2322
            case P_NAMED:
×
UNCOV
2323
               port = tree_ref(name_to_ref(tree_name(p)));
×
UNCOV
2324
               break;
×
UNCOV
2325
            default:
×
2326
               should_not_reach_here();
2327
            }
2328
            assert(tree_kind(port) == T_PARAM_DECL);
3,482✔
2329

2330
            switch (tree_subkind(port)) {
3,482✔
2331
            case PORT_IN:
3,475✔
2332
            case PORT_INOUT:
2333
            case PORT_ARRAY_VIEW:
2334
            case PORT_RECORD_VIEW:
2335
               build_wait(tree_value(p), fn, ctx);
3,475✔
2336
               break;
3,475✔
2337
            default:
2338
               break;
2339
            }
2340
         }
2341
      }
2342
      break;
2343

2344
   case T_AGGREGATE:
383✔
2345
      {
2346
         const int nassocs = tree_assocs(expr);
383✔
2347
         for (int i = 0; i < nassocs; i++) {
1,390✔
2348
            tree_t a = tree_assoc(expr, i);
1,007✔
2349
            build_wait(tree_value(a), fn, ctx);
1,007✔
2350

2351
            switch (tree_subkind(a)) {
1,007✔
2352
            case A_RANGE:
53✔
2353
            case A_SLICE:
2354
               build_wait(tree_range(a, 0), fn, ctx);
53✔
2355
               break;
53✔
2356
            case A_NAMED:
93✔
2357
               build_wait(tree_name(a), fn, ctx);
93✔
2358
               break;
93✔
2359
            }
2360
         }
2361
      }
2362
      break;
2363

2364
   case T_ATTR_REF:
367✔
2365
      {
2366
         const attr_kind_t predef = tree_subkind(expr);
367✔
2367
         if (predef == ATTR_EVENT || predef == ATTR_ACTIVE)
367✔
2368
            build_wait(tree_name(expr), fn, ctx);
169✔
2369

2370
         const int nparams = tree_params(expr);
367✔
2371
         for (int i = 0; i < nparams; i++)
384✔
2372
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
17✔
2373
      }
2374
      break;
2375

2376
   case T_LITERAL:
2377
   case T_STRING:
2378
   case T_DUMMY_DRIVER:
2379
      break;
2380

2381
   case T_IF:
235✔
2382
      {
2383
         const int nconds = tree_conds(expr);
235✔
2384
         for (int i = 0; i < nconds; i++)
641✔
2385
            build_wait(tree_cond(expr, i), fn, ctx);
406✔
2386
      }
2387
      break;
2388

2389
   case T_COND_STMT:
410✔
2390
      {
2391
         if (tree_has_value(expr))
410✔
2392
            build_wait(tree_value(expr), fn, ctx);
275✔
2393

2394
         const int nstmts = tree_stmts(expr);
410✔
2395
         for (int i = 0; i < nstmts; i++)
822✔
2396
            build_wait(tree_stmt(expr, i), fn, ctx);
412✔
2397
      }
2398
      break;
2399

2400
   case T_COND_VALUE:
3✔
2401
      {
2402
         const int nconds = tree_conds(expr);
3✔
2403
         for (int i = 0; i < nconds; i++)
12✔
2404
            build_wait(tree_cond(expr, i), fn, ctx);
9✔
2405
         break;
2406
      }
2407

2408
   case T_COND_EXPR:
9✔
2409
      {
2410
         if (tree_has_value(expr))
9✔
2411
            build_wait(tree_value(expr), fn, ctx);
6✔
2412

2413
         build_wait(tree_result(expr), fn, ctx);
9✔
2414
         break;
9✔
2415
      }
2416

2417
   case T_PROCESS:
53✔
2418
   case T_SEQUENCE:
2419
   case T_PROC_BODY:
2420
      {
2421
         const int ndecls = tree_decls(expr);
53✔
2422
         for (int i = 0; i < ndecls; i++) {
71✔
2423
            tree_t d = tree_decl(expr, i);
18✔
2424
            if (tree_kind(d) == T_PROC_BODY)
18✔
2425
               build_wait(d, fn, ctx);
2✔
2426
         }
2427

2428
         const int nstmts = tree_stmts(expr);
53✔
2429
         for (int i = 0; i < nstmts; i++)
121✔
2430
            build_wait(tree_stmt(expr, i), fn, ctx);
68✔
2431
      }
2432
      break;
2433

2434
   case T_SIGNAL_ASSIGN:
2,634✔
2435
      {
2436
         build_wait_for_target(tree_target(expr), fn, ctx);
2,634✔
2437

2438
         const int nwaves = tree_waveforms(expr);
2,634✔
2439
         for (int i = 0; i < nwaves; i++)
5,442✔
2440
            build_wait(tree_waveform(expr, i), fn, ctx);
2,808✔
2441
      }
2442
      break;
2443

2444
   case T_VAR_ASSIGN:
16✔
2445
   case T_FORCE:
2446
      build_wait_for_target(tree_target(expr), fn, ctx);
16✔
2447
      build_wait(tree_value(expr), fn, ctx);
16✔
2448
      break;
16✔
2449

2450
   case T_RELEASE:
3✔
2451
      build_wait_for_target(tree_target(expr), fn, ctx);
3✔
2452
      break;
3✔
2453

2454
   case T_CASE:
47✔
2455
   case T_MATCH_CASE:
2456
      {
2457
         build_wait(tree_value(expr), fn, ctx);
47✔
2458

2459
         const int nstmts = tree_stmts(expr);
47✔
2460
         for (int i = 0; i < nstmts; i++) {
285✔
2461
            tree_t alt = tree_stmt(expr, i);
238✔
2462

2463
            const int nstmts = tree_stmts(alt);
238✔
2464
            for (int j = 0; j < nstmts; j++)
476✔
2465
               build_wait(tree_stmt(alt, j), fn, ctx);
238✔
2466
         }
2467
      }
2468
      break;
2469

2470
   case T_FOR:
16✔
2471
      {
2472
         build_wait(tree_range(expr, 0), fn, ctx);
16✔
2473

2474
         const int nstmts = tree_stmts(expr);
16✔
2475
         for (int i = 0; i < nstmts; i++)
35✔
2476
            build_wait(tree_stmt(expr, i), fn, ctx);
19✔
2477
      }
2478
      break;
2479

2480
   case T_WHILE:
1✔
2481
      build_wait(tree_value(expr), fn, ctx);
1✔
2482
      // Fall-through
2483
   case T_LOOP:
4✔
2484
      {
2485
         const int nstmts = tree_stmts(expr);
4✔
2486
         for (int i = 0; i < nstmts; i++)
20✔
2487
            build_wait(tree_stmt(expr, i), fn, ctx);
16✔
2488
      }
2489
      break;
2490

2491
   case T_NEXT:
9✔
2492
   case T_EXIT:
2493
      if (tree_has_value(expr))
9✔
2494
         build_wait(tree_value(expr), fn, ctx);
6✔
2495
      break;
2496

2497
   case T_RANGE:
155✔
2498
      if (tree_subkind(expr) == RANGE_EXPR)
155✔
2499
         build_wait(tree_value(expr), fn, ctx);
16✔
2500
      else {
2501
         build_wait(tree_left(expr), fn, ctx);
139✔
2502
         build_wait(tree_right(expr), fn, ctx);
139✔
2503
      }
2504
      break;
2505

2506
   case T_OPEN:
2507
      break;
2508

UNCOV
2509
   default:
×
2510
      fatal_trace("Cannot handle tree kind %s in wait expression",
2511
                  tree_kind_str(tree_kind(expr)));
2512
   }
2513
}
14,136✔
2514

2515
void print_syntax(const char *fmt, ...)
2,128✔
2516
{
2517
   LOCAL_TEXT_BUF tb = tb_new();
2,128✔
2518
   bool highlighting = false;
2,128✔
2519
   static bool comment = false, last_was_newline = false;
2,128✔
2520
   for (const char *p = fmt; *p != '\0'; p++) {
11,125✔
2521
      if (comment) {
8,997✔
2522
         if (*p == '\n' || *p == '\r') {
3,244✔
2523
            comment = false;
94✔
2524
            last_was_newline = true;
94✔
2525
            tb_cat(tb, "$$\n");
94✔
2526
         }
2527
         else if (*p != '~' && *p != '#') {
3,150✔
2528
            tb_append(tb, *p);
2,990✔
2529
            last_was_newline = false;
2,990✔
2530
         }
2531
         if (p > fmt && *p == '/' && *(p - 1) == '*') {
3,244✔
2532
            tb_cat(tb, "$$");
16✔
2533
            comment = false;
16✔
2534
            last_was_newline = false;
16✔
2535
         }
2536
      }
2537
      else if (*p == '\r') {
5,753✔
2538
         if (!last_was_newline) {
22✔
UNCOV
2539
            tb_append(tb, '\n');
×
UNCOV
2540
            last_was_newline = true;
×
2541
         }
2542
      }
2543
      else if (*p == '#' && *(p + 1) != '#') {
5,731✔
2544
         tb_cat(tb, "$bold$$cyan$");
380✔
2545
         last_was_newline = false;
380✔
2546
         highlighting = true;
380✔
2547
      }
2548
      else if (*p == '~' && *(p + 1) != '~') {
5,351✔
2549
         tb_cat(tb, "$yellow$");
1✔
2550
         last_was_newline = false;
1✔
2551
         highlighting = true;
1✔
2552
      }
2553
      else if ((*p == '-' && *(p + 1) == '-')
5,350✔
2554
               || (*p == '/' && *(p + 1) == '/')
5,260✔
2555
               || (*p == '/' && *(p + 1) == '*')) {
5,256✔
2556
         tb_cat(tb, "$red$");
110✔
2557
         tb_append(tb, *p);
110✔
2558
         last_was_newline = false;
110✔
2559
         comment = true;
110✔
2560
      }
2561
      else if (!isalnum_iso88591(*p) && *p != '_'
5,240✔
2562
               && *p != '%' && highlighting) {
2,698✔
2563
         tb_cat(tb, "$$");
325✔
2564
         tb_append(tb, *p);
325✔
2565
         last_was_newline = false;
325✔
2566
         highlighting = false;
325✔
2567
      }
2568
      else {
2569
         tb_append(tb, *p);
4,915✔
2570
         last_was_newline = (*p == '\n');
4,915✔
2571
      }
2572
   }
2573

2574
   if (highlighting)
2,128✔
2575
      tb_cat(tb, "$$");
56✔
2576

2577
   va_list ap;
2,128✔
2578
   va_start(ap, fmt);
2,128✔
2579

2580
   if (syntax_buf != NULL) {
2,128✔
2581
      ostream_t os = { tb_ostream_write, syntax_buf, CHARSET_ISO88591, false };
2,128✔
2582
      nvc_vfprintf(&os, tb_get(tb), ap);
2,128✔
2583
   }
2584
   else
UNCOV
2585
      nvc_vprintf(tb_get(tb), ap);
×
2586

2587
   va_end(ap);
2,128✔
2588
}
2,128✔
2589

2590
void capture_syntax(text_buf_t *tb)
9✔
2591
{
2592
   assert(tb == NULL || syntax_buf == NULL);
9✔
2593
   syntax_buf = tb;
9✔
2594
}
9✔
2595

2596
void analyse_file(const char *file, jit_t *jit, unit_registry_t *ur,
4,066✔
2597
                  mir_context_t *mc)
2598
{
2599
   input_from_file(file);
4,066✔
2600

2601
   switch (source_kind()) {
4,066✔
2602
   case SOURCE_VHDL:
3,750✔
2603
      {
2604
         lib_t work = lib_work();
3,750✔
2605
         int base_errors = 0;
3,750✔
2606
         tree_t unit;
3,750✔
2607
         while (base_errors = error_count(), (unit = parse())) {
14,408✔
2608
            if (error_count() == base_errors) {
10,658✔
2609
               lib_put(work, unit);
10,655✔
2610
               unit_registry_purge(ur, tree_ident(unit));
10,655✔
2611

2612
               simplify_local(unit, jit, ur, mc);
10,655✔
2613
               bounds_check(unit);
10,655✔
2614
            }
2615
            else
2616
               lib_put_error(work, unit);
3✔
2617
         }
2618
      }
2619
      break;
2620

2621
   case SOURCE_VERILOG:
316✔
2622
      {
2623
         LOCAL_TEXT_BUF tb = tb_new();
632✔
2624
         vlog_preprocess(tb, true);
316✔
2625

2626
         file_ref_t file_ref = loc_file_ref(file, NULL);
316✔
2627
         input_from_buffer(tb_get(tb), tb_len(tb), file_ref, SOURCE_VERILOG);
316✔
2628

2629
         lib_t work = lib_work();
316✔
2630
         vlog_node_t module;
316✔
2631
         while ((module = vlog_parse())) {
1,003✔
2632
            if (error_count() == 0) {
371✔
2633
               vlog_check(module);
371✔
2634

2635
               if (error_count() == 0) {
371✔
2636
                  vlog_simp(module);
371✔
2637
                  lib_put_vlog(work, module);
371✔
2638
               }
2639
            }
2640
         }
2641
      }
2642
      break;
316✔
2643

2644
   case SOURCE_SDF:
×
2645
      {
UNCOV
2646
         sdf_file_t *sdf_file = sdf_parse(file, 0);
×
UNCOV
2647
         progress("analysed SDF file: %s", file);
×
2648

UNCOV
2649
         if (sdf_file != NULL) {
×
UNCOV
2650
            warnf("SDF is not yet supported");
×
UNCOV
2651
            sdf_file_free(sdf_file);
×
2652
         }
2653
      }
2654
      break;
2655
   }
2656
}
4,063✔
2657

2658
bool all_character_literals(type_t type)
15,586✔
2659
{
2660
   assert(type_is_enum(type));
15,586✔
2661

2662
   type_t base = type_base_recur(type);
15,586✔
2663
   const int nlits = type_enum_literals(base);
15,586✔
2664
   for (int i = 0; i < nlits; i++) {
76,591✔
2665
      if (ident_char(tree_ident(type_enum_literal(base, i)), 0) != '\'')
66,925✔
2666
         return false;
2667
   }
2668

2669
   return true;
2670
}
2671

2672
bool is_operator_symbol(ident_t ident)
28,741✔
2673
{
2674
   const well_known_t wk = is_well_known(ident);
28,741✔
2675
   if (wk >= NUM_WELL_KNOWN)
28,741✔
2676
      return false;
2677
   else if (standard() < STD_08)
16,430✔
2678
      return wk >= W_OP_AND && wk <= W_OP_NOT;
3,268✔
2679
   else
2680
      return wk >= W_OP_AND && wk <= W_OP_MATCH_GREATER_EQUAL;
13,162✔
2681
}
2682

2683
bool same_tree(tree_t a, tree_t b)
6,180✔
2684
{
2685
   const tree_kind_t akind = tree_kind(a);
6,180✔
2686
   if (akind != tree_kind(b))
6,180✔
2687
      return false;
2688

2689
   switch (akind) {
6,055✔
2690
   case T_REF:
2,704✔
2691
      return tree_has_ref(a) && tree_has_ref(b) && tree_ref(a) == tree_ref(b);
3,532✔
2692
   case T_ARRAY_REF:
937✔
2693
      {
2694
         if (!same_tree(tree_value(a), tree_value(b)))
937✔
2695
            return false;
2696

2697
         const int nparams = tree_params(a);
915✔
2698
         assert(nparams == tree_params(b));
915✔
2699

2700
         for (int i = 0; i < nparams; i++) {
1,737✔
2701
            tree_t pa = tree_value(tree_param(a, i));
1,590✔
2702
            tree_t pb = tree_value(tree_param(b, i));
1,590✔
2703
            if (!same_tree(pa, pb))
1,590✔
2704
               return false;
2705
         }
2706

2707
         return true;
2708
      }
2709
   case T_ARRAY_SLICE:
32✔
2710
      {
2711
         if (!same_tree(tree_value(a), tree_value(b)))
32✔
2712
            return false;
2713

2714
         tree_t ra = tree_range(a, 0);
32✔
2715
         tree_t rb = tree_range(b, 0);
32✔
2716

2717
         const range_kind_t rakind = tree_subkind(ra);
32✔
2718
         if (rakind != tree_subkind(rb) || rakind == RANGE_EXPR)
32✔
2719
            return false;
2720

2721
         return same_tree(tree_left(ra), tree_left(rb))
32✔
2722
            && same_tree(tree_right(ra), tree_right(rb));
35✔
2723
      }
2724
   case T_RECORD_REF:
226✔
2725
      return ident_casecmp(tree_ident(a), tree_ident(b))
226✔
2726
         && same_tree(tree_value(a), tree_value(b));
232✔
2727
   case T_LITERAL:
1,879✔
2728
      {
2729
         const literal_kind_t lkind = tree_subkind(a);
1,879✔
2730
         if (lkind != tree_subkind(b))
1,879✔
2731
            return false;
2732

2733
         switch (lkind) {
1,879✔
2734
         case L_PHYSICAL:
24✔
2735
            {
2736
               ident_t aid = tree_has_ident(a) ? tree_ident(a) : NULL;
24✔
2737
               ident_t bid = tree_has_ident(b) ? tree_ident(b) : NULL;
24✔
2738
               if (aid == bid)
24✔
2739
                  return tree_ival(a) == tree_ival(b);
24✔
2740
               else
2741
                  return false;
2742
            }
2743
         case L_INT:
1,830✔
2744
            return tree_ival(a) == tree_ival(b);
1,830✔
2745
         case L_REAL:
25✔
2746
            return tree_dval(a) == tree_dval(b);
25✔
2747
         case L_NULL:
2748
            return true;
UNCOV
2749
         default:
×
UNCOV
2750
            return false;
×
2751
         }
2752
      }
2753
   case T_STRING:
253✔
2754
      {
2755
         const int nchars = tree_chars(a);
253✔
2756
         if (tree_chars(b) != nchars)
253✔
2757
            return false;
2758

2759
         for (int i = 0; i < nchars; i++) {
308✔
2760
            if (!same_tree(tree_char(a, i), tree_char(b, i)))
56✔
2761
               return false;
2762
         }
2763

2764
         return true;
2765
      }
2766
   case T_OPEN:
2767
      return true;
2768
   default:
24✔
2769
      return false;
24✔
2770
   }
2771
}
2772

2773
static range_kind_t get_range_direction(tree_t r)
324✔
2774
{
2775
   assert(tree_kind(r) == T_RANGE);
324✔
2776

2777
   const range_kind_t dir = tree_subkind(r);
324✔
2778
   if (dir != RANGE_EXPR)
324✔
2779
      return dir;
2780

2781
   // Handle ranges like X'RANGE where X has known direction
2782

2783
   tree_t aref = tree_value(r);
50✔
2784
   assert(tree_kind(aref) == T_ATTR_REF);
50✔
2785

2786
   const attr_kind_t kind = tree_subkind(aref);
50✔
2787
   assert(kind == ATTR_RANGE || kind == ATTR_REVERSE_RANGE);
50✔
2788

2789
   type_t prefix_type = tree_type(tree_name(aref));
50✔
2790
   if (type_is_none(prefix_type))
50✔
2791
      return RANGE_ERROR;
2792
   if (type_is_unconstrained(prefix_type))
49✔
2793
      return RANGE_EXPR;
2794

2795
   tree_t prefix_r = range_of(prefix_type, 0);
46✔
2796

2797
   const range_kind_t prefix_dir = get_range_direction(prefix_r);
46✔
2798
   if (prefix_dir != RANGE_TO && prefix_dir != RANGE_DOWNTO)
46✔
2799
      return prefix_dir;
2800
   else if (kind == ATTR_REVERSE_RANGE)
46✔
2801
      return prefix_dir == RANGE_TO ? RANGE_DOWNTO : RANGE_TO;
3✔
2802
   else
2803
      return prefix_dir;
2804
}
2805

2806
bool calculate_aggregate_bounds(tree_t expr, range_kind_t *kind,
7,125✔
2807
                                int64_t *left, int64_t *right)
2808
{
2809
   // Calculate the direction and bounds of an array aggregate using the
2810
   // rules in LRM 93 7.3.2.2
2811

2812
   type_t type = tree_type(expr);
7,125✔
2813
   if (type_is_none(type))
7,125✔
2814
      return false;
2815

2816
   type_t index_type = index_type_of(type, 0);
7,125✔
2817
   if (index_type == NULL || type_is_none(index_type))
7,125✔
2818
      return false;
1✔
2819

2820
   tree_t index_r = range_of(index_type, 0), base_r = index_r;
7,124✔
2821

2822
   int64_t low, high;
7,124✔
2823
   if (!folded_bounds(index_r, &low, &high))
7,124✔
2824
      return false;
2825

2826
   int64_t clow = INT64_MAX, chigh = INT64_MIN;  // Actual bounds computed below
7,109✔
2827

2828
   range_kind_t dir;
7,109✔
2829
   if (type_is_unconstrained(type))
7,109✔
2830
      dir = tree_subkind(index_r);
6,831✔
2831
   else {
2832
      base_r = range_of(type, 0);
278✔
2833
      dir = get_range_direction(base_r);
278✔
2834
   }
2835

2836
   const int nassocs = tree_assocs(expr);
7,109✔
2837

2838
   if (standard() >= STD_08) {
7,109✔
2839
      // VHDL-2008 range association determines index direction for
2840
      // unconstrained aggregate when the expression type matches the
2841
      // array type
2842
      for (int i = 0; i < nassocs; i++) {
15,148✔
2843
         tree_t a = tree_assoc(expr, i);
10,961✔
2844
         if (tree_subkind(a) == A_SLICE)
10,961✔
2845
            dir = tree_subkind(tree_range(a, 0));
56✔
2846
      }
2847
   }
2848

2849
   if (dir != RANGE_TO && dir != RANGE_DOWNTO)
7,109✔
2850
      return false;
2851

2852
   int64_t pos = 0;
2853
   for (int i = 0; i < nassocs; i++) {
19,779✔
2854
      tree_t a = tree_assoc(expr, i);
17,504✔
2855
      int64_t ilow = 0, ihigh = 0;
17,504✔
2856
      const assoc_kind_t akind = tree_subkind(a);
17,504✔
2857

2858
      switch (akind) {
17,504✔
2859
      case A_NAMED:
628✔
2860
         {
2861
            tree_t name = tree_name(a);
628✔
2862
            if (folded_int(name, &ilow))
628✔
2863
               ihigh = ilow;
618✔
2864
            else
2865
               return false;
4,821✔
2866
         }
2867
         break;
618✔
2868

2869
      case A_RANGE:
1,169✔
2870
      case A_SLICE:
2871
         {
2872
            tree_t r = tree_range(a, 0);
1,169✔
2873
            const range_kind_t rkind = tree_subkind(r);
1,169✔
2874
            if (rkind == RANGE_TO || rkind == RANGE_DOWNTO) {
1,169✔
2875
               tree_t left = tree_left(r), right = tree_right(r);
858✔
2876

2877
               int64_t ileft, iright;
858✔
2878
               if (folded_int(left, &ileft) && folded_int(right, &iright)) {
858✔
2879
                  ilow = (rkind == RANGE_TO ? ileft : iright);
437✔
2880
                  ihigh = (rkind == RANGE_TO ? iright : ileft);
437✔
2881
               }
2882
               else
2883
                  return false;
421✔
2884
            }
2885
            else
2886
               return false;
2887
         }
2888
         break;
2889

2890
      case A_OTHERS:
2891
         return false;
2892

2893
      case A_POS:
9,856✔
2894
         if (i == 0) {
9,856✔
2895
            int64_t ileft;
1,570✔
2896
            if (folded_int(tree_left(base_r), &ileft))
1,570✔
2897
               ilow = ihigh = ileft;
1,570✔
2898
            else
UNCOV
2899
               return false;
×
2900
         }
2901
         else if (dir == RANGE_TO)
8,286✔
2902
            ilow = ihigh = clow + pos;
8,284✔
2903
         else
2904
            ilow = ihigh = chigh - pos;
2✔
2905
         pos++;
9,856✔
2906
         break;
9,856✔
2907

2908
      case A_CONCAT:
5,840✔
2909
         {
2910
            type_t value_type = tree_type(tree_value(a));
5,840✔
2911

2912
            int64_t length;
5,840✔
2913
            if (type_is_unconstrained(value_type))
5,840✔
2914
               return false;
4,068✔
2915
            else if (folded_length(range_of(value_type, 0), &length)) {
2,094✔
2916
               if (i == 0) {
1,772✔
2917
                  int64_t ileft;
1,475✔
2918
                  if (folded_int(tree_left(base_r), &ileft))
1,475✔
2919
                     ilow = ihigh = ileft;
1,475✔
2920
                  else
UNCOV
2921
                     return false;
×
2922
               }
2923
               else if (dir == RANGE_TO) {
297✔
2924
                  ilow = clow + pos;
279✔
2925
                  ihigh = ilow + length - 1;
279✔
2926
               }
2927
               else {
2928
                  ihigh = chigh - pos;
18✔
2929
                  ilow = ihigh - length + 1;
18✔
2930
               }
2931
               pos += length;
1,772✔
2932
            }
2933
            else
2934
               return false;
2935
         }
2936
         break;
2937
      }
2938

2939
      clow = MIN(clow, ilow);
12,683✔
2940
      chigh = MAX(chigh, ihigh);
12,683✔
2941
   }
2942

2943
   if (clow < low || chigh > high)
2,275✔
2944
      return false;   // Will raise a bounds check error later
2945

2946
   *kind = dir;
2,270✔
2947
   *left = dir == RANGE_TO ? clow : chigh;
2,270✔
2948
   *right = dir == RANGE_TO ? chigh : clow;
2,270✔
2949

2950
   return true;
2,270✔
2951
}
2952

2953
type_t calculate_aggregate_subtype(tree_t expr)
5,995✔
2954
{
2955
   range_kind_t dir;
5,995✔
2956
   int64_t ileft, iright;
5,995✔
2957
   if (!calculate_aggregate_bounds(expr, &dir, &ileft, &iright))
5,995✔
2958
      return NULL;
2959

2960
   type_t type = tree_type(expr);
2,254✔
2961

2962
   const int ndims = dimension_of(type);
2,254✔
2963
   type_t a0_type = NULL;
2,254✔
2964
   if (ndims > 1) {
2,254✔
2965
      a0_type = tree_type(tree_value(tree_assoc(expr, 0)));
72✔
2966
      if (type_is_unconstrained(a0_type))
72✔
2967
         return NULL;
2968

2969
      assert(dimension_of(a0_type) == ndims - 1);
72✔
2970
   }
2971

2972
   type_t index_type = index_type_of(type, 0);
2,254✔
2973

2974
   tree_t left = get_discrete_lit(expr, index_type, ileft);
2,254✔
2975
   tree_t right = get_discrete_lit(expr, index_type, iright);
2,254✔
2976
   assert(left != NULL && right != NULL);
2,254✔
2977

2978
   type_t sub = type_new(T_SUBTYPE);
2,254✔
2979
   type_set_base(sub, type_base_recur(type));
2,254✔
2980

2981
   type_t elem = type_elem(type);
2,254✔
2982
   if (type_is_unconstrained(elem)) {
2,254✔
2983
      tree_t a0 = tree_assoc(expr, 0);
106✔
2984
      switch (tree_subkind(a0)) {
106✔
2985
      case A_CONCAT:
6✔
2986
      case A_SLICE:
2987
         a0_type = type_elem(tree_type(tree_value(a0)));
6✔
2988
         break;
6✔
2989
      default:
100✔
2990
         a0_type = tree_type(tree_value(a0));
100✔
2991
         break;
100✔
2992
      }
2993

2994
      if (!type_is_unconstrained(a0_type))
106✔
2995
         elem = a0_type;
62✔
2996
   }
2997

2998
   type_set_elem(sub, elem);
2,254✔
2999

3000
   tree_t cons = tree_new(T_CONSTRAINT);
2,254✔
3001
   tree_set_subkind(cons, C_INDEX);
2,254✔
3002

3003
   tree_t r = tree_new(T_RANGE);
2,254✔
3004
   tree_set_subkind(r, dir);
2,254✔
3005
   tree_set_type(r, index_type);
2,254✔
3006
   tree_set_left(r, left);
2,254✔
3007
   tree_set_right(r, right);
2,254✔
3008

3009
   tree_add_range(cons, r);
2,254✔
3010

3011
   for (int i = 1; i < ndims; i++)
2,326✔
3012
      tree_add_range(cons, range_of(a0_type, i - 1));
72✔
3013

3014
   type_set_constraint(sub, cons);
2,254✔
3015

3016
   return sub;
2,254✔
3017
}
3018

3019
bool can_be_signal(type_t type)
16,285✔
3020
{
3021
   switch (type_kind(type)) {
28,666✔
3022
   case T_RECORD:
3,401✔
3023
      {
3024
         const int nfields = type_fields(type);
3,401✔
3025
         for (int i = 0; i < nfields; i++) {
13,304✔
3026
            if (!can_be_signal(tree_type(type_field(type, i))))
10,719✔
3027
               return false;
3028
         }
3029

3030
         return true;
3031
      }
3032
   case T_ARRAY:
4,800✔
3033
      return can_be_signal(type_elem(type));
4,800✔
3034
   case T_SUBTYPE:
7,581✔
3035
      return can_be_signal(type_base(type));
7,581✔
3036
   case T_ACCESS:
3037
   case T_FILE:
3038
   case T_PROTECTED:
3039
   case T_INCOMPLETE:
3040
      return false;
3041
   default:
9,369✔
3042
      return true;
9,369✔
3043
   }
3044
}
3045

3046
type_t merge_constraints(type_t to, type_t from)
1,079✔
3047
{
3048
   assert(type_is_unconstrained(to));
1,079✔
3049
   assert(type_eq(to, from));
1,079✔
3050

3051
   tree_t cto = NULL;
1,079✔
3052
   if (type_kind(to) == T_SUBTYPE && type_has_constraint(to))
1,079✔
3053
      cto = type_constraint(to);
23✔
3054

3055
   tree_t cfrom = NULL;
1,079✔
3056
   if (type_kind(from) == T_SUBTYPE && type_has_constraint(from))
1,079✔
3057
      cfrom = type_constraint(from);
863✔
3058

3059
   if (cfrom == NULL)
863✔
3060
      return to;
216✔
3061

3062
   type_t sub = type_new(T_SUBTYPE);
863✔
3063
   type_set_base(sub, type_base_recur(to));
863✔
3064

3065
   if (type_is_array(to)) {
863✔
3066
      type_set_constraint(sub, cto ?: cfrom);
1,706✔
3067

3068
      type_t elem = type_elem(to);
858✔
3069
      if (type_is_unconstrained(elem))
858✔
3070
         type_set_elem(sub, merge_constraints(elem, type_elem(from)));
14✔
3071
      else
3072
         type_set_elem(sub, elem);
844✔
3073
   }
3074
   else {
3075
      tree_t cnew = tree_new(T_CONSTRAINT);
5✔
3076
      tree_set_subkind(cnew, C_RECORD);
5✔
3077
      tree_set_loc(cnew, tree_loc(cto ?: cfrom));
6✔
3078

3079
      type_set_constraint(sub, cnew);
5✔
3080

3081
      if (cto != NULL) {
5✔
3082
         const int nto = tree_ranges(cto);
4✔
3083
         for (int i = 0; i < nto; i++)
8✔
3084
            tree_add_range(cnew, tree_range(cto, i));
4✔
3085
      }
3086

3087
      const int nfrom = tree_ranges(cfrom), base = tree_ranges(cnew);
5✔
3088
      for (int i = 0; i < nfrom; i++) {
13✔
3089
         tree_t ec = tree_range(cfrom, i);
8✔
3090
         assert(tree_kind(ec) == T_ELEM_CONSTRAINT);
8✔
3091

3092
         ident_t id = tree_ident(ec);
8✔
3093
         bool found = false;
8✔
3094
         for (int j = 0; j < base && !found; j++)
15✔
3095
            found |= tree_ident(tree_range(cnew, j)) == id;
7✔
3096

3097
         if (!found)
8✔
3098
            tree_add_range(cnew, ec);
4✔
3099
      }
3100
   }
3101

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

© 2026 Coveralls, Inc