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

nickg / nvc / 6410775874

04 Oct 2023 07:25PM UTC coverage: 91.223% (-0.006%) from 91.229%
6410775874

push

github

nickg
Implement LCS2016-032 changes to instance/path name

94 of 94 new or added lines in 3 files covered. (100.0%)

48795 of 53490 relevant lines covered (91.22%)

624869.59 hits per line

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

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

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

32
#include <assert.h>
33
#include <ctype.h>
34
#include <string.h>
35
#include <stdlib.h>
36
#include <inttypes.h>
37

38
typedef struct {
39
   ptr_list_t copied_subs;
40
   ptr_list_t copied_types;
41
} copy_ctx_t;
42

43
static vhdl_standard_t  current_std  = STD_02;
44
static bool             have_set_std = false;
45
static ident_t          id_cache[NUM_WELL_KNOWN];
46
static text_buf_t      *syntax_buf = NULL;
47

48
int64_t assume_int(tree_t t)
125,916✔
49
{
50
   int64_t value;
125,916✔
51
   if (folded_int(t, &value))
125,916✔
52
      return value;
125,916✔
53

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

58
void range_bounds(tree_t r, int64_t *low, int64_t *high)
41,292✔
59
{
60
   assert(tree_kind(r) == T_RANGE);
41,292✔
61

62
   const int64_t left = assume_int(tree_left(r));
41,292✔
63
   const int64_t right = assume_int(tree_right(r));
41,292✔
64

65
   *low  = tree_subkind(r) == RANGE_TO ? left : right;
41,292✔
66
   *high = tree_subkind(r) == RANGE_TO ? right : left;
41,292✔
67
}
41,292✔
68

69
bool folded_int(tree_t t, int64_t *l)
1,778,220✔
70
{
71
   switch (tree_kind(t)) {
1,793,680✔
72
   case T_LITERAL:
1,361,070✔
73
      switch (tree_subkind(t)) {
1,361,070✔
74
      case L_PHYSICAL:
12,904✔
75
         if (tree_has_ref(t))
12,904✔
76
            return false;
77
         // Fall-through
78
      case L_INT:
79
         *l = tree_ival(t);
1,343,690✔
80
         return true;
1,343,690✔
81
      default:
82
         return false;
83
      }
84
   case T_QUALIFIED:
283✔
85
      return folded_int(tree_value(t), l);
283✔
86
   case T_REF:
312,481✔
87
      {
88
         tree_t decl = tree_ref(t);
312,481✔
89
         switch (tree_kind(decl)) {
312,481✔
90
         case T_CONST_DECL:
16,412✔
91
            if (tree_has_value(decl))
16,412✔
92
               return folded_int(tree_value(decl), l);
15,180✔
93
            else
94
               return false;
95
         case T_ENUM_LIT:
238,330✔
96
            *l = tree_pos(decl);
238,330✔
97
            return true;
238,330✔
98
         default:
99
            return false;
100
         }
101
      }
102
   default:
103
      return false;
104
   }
105
}
106

107
bool folded_real(tree_t t, double *l)
130,971✔
108
{
109
   switch (tree_kind(t)) {
130,992✔
110
   case T_LITERAL:
123,877✔
111
      if (tree_subkind(t) == L_REAL) {
123,877✔
112
         *l = tree_dval(t);
123,875✔
113
         return true;
123,875✔
114
      }
115
      else
116
         return false;
117
   case T_QUALIFIED:
21✔
118
      return folded_real(tree_value(t), l);
21✔
119
   default:
120
      return false;
121
   }
122
}
123

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

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

139
   const range_kind_t rkind = tree_subkind(r);
689,761✔
140

141
   if (rkind != RANGE_TO && rkind != RANGE_DOWNTO)
689,761✔
142
      return false;
143

144
   int64_t left, right;
688,316✔
145
   if (!folded_int(tree_left(r), &left))
688,316✔
146
      return false;
147
   else if (!folded_int(tree_right(r), &right))
665,175✔
148
      return false;
149

150
   switch (rkind) {
662,658✔
151
   case RANGE_TO:
631,467✔
152
      *low  = left;
631,467✔
153
      *high = right;
631,467✔
154
      return true;
631,467✔
155
   case RANGE_DOWNTO:
31,191✔
156
      *low  = right;
31,191✔
157
      *high = left;
31,191✔
158
      return true;
31,191✔
159
   default:
160
      return false;
161
   }
162
}
163

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

168
   const range_kind_t rkind = tree_subkind(r);
60,518✔
169

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

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

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

203
   return false;
204
}
205

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

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

217
   return b;
7,183✔
218
}
219

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

228
   return f;
32,529✔
229
}
230

231
tree_t get_real_lit(tree_t t, type_t type, double r)
×
232
{
233
   tree_t f = tree_new(T_LITERAL);
×
234
   tree_set_loc(f, tree_loc(t));
×
235
   tree_set_subkind(f, L_REAL);
×
236
   tree_set_dval(f, r);
×
237
   tree_set_type(f, type ?: tree_type(t));
×
238

239
   return f;
×
240
}
241

242
bool parse_value(type_t type, const char *str, parsed_value_t *value)
86✔
243
{
244
   type_t base = type_base_recur(type);
86✔
245
   const type_kind_t basek = type_kind(base);
86✔
246

247
   if (basek == T_ARRAY && type_is_character_array(base)) {
86✔
248
      value->enums = NULL;
17✔
249

250
      int map[256];
17✔
251
      for (int i = 0; i < ARRAY_LEN(map); i++)
4,369✔
252
         map[i] = INT_MAX;
4,352✔
253

254
      type_t elem = type_elem(base);
17✔
255

256
      const int nlits = type_enum_literals(elem);
17✔
257
      for (int i = 0; i < nlits; i++) {
2,591✔
258
         ident_t id = tree_ident(type_enum_literal(elem, i));
2,574✔
259
         if (ident_char(id, 0) == '\'')
2,574✔
260
            map[(uint8_t)ident_char(id, 1)] = i;
1,924✔
261
      }
262

263
      while (map[(uint8_t)*str] == INT_MAX && isspace_iso88591(*str))
20✔
264
         ++str;
3✔
265

266
      const bool quoted = map['\"'] == INT_MAX && *str == '\"';
17✔
267
      if (quoted) str++;
17✔
268

269
      const size_t max = strlen(str);
17✔
270
      enum_array_t *array = xmalloc_flex(sizeof(enum_array_t), max, 1);
17✔
271

272
      int n = 0, m;
17✔
273
      for (; *str != '\0' && (m = map[(uint8_t)*str]) != INT_MAX; str++, n++)
99✔
274
         array->values[n] = m;
65✔
275

276
      assert(n <= max);
17✔
277
      array->count = n;
17✔
278

279
      if (quoted && *str++ != '\"') {
17✔
280
         free(array);
1✔
281
         return false;
1✔
282
      }
283

284
      for (; *str; str++) {
20✔
285
         if (!isspace_iso88591(*str)) {
5✔
286
            free(array);
1✔
287
            return false;
1✔
288
         }
289
      }
290

291
      value->enums = array;
15✔
292
      return true;
15✔
293
   }
294

295
   while (isspace_iso88591(*str))
79✔
296
      ++str;
10✔
297

298
   switch (basek) {
69✔
299
   case T_INTEGER:
44✔
300
      {
301
         const bool is_negative = *str == '-';
44✔
302
         int num_digits = 0;
44✔
303

304
         if (is_negative) ++str;
44✔
305

306
         int64_t sum = 0;
307
         for (; isdigit_iso88591(*str) || (*str == '_'); str++) {
132✔
308
            if (*str != '_') {
88✔
309
               sum *= 10;
86✔
310
               sum += (*str - '0');
86✔
311
               num_digits++;
86✔
312
            }
313
         }
314

315
         value->integer = is_negative ? -sum : sum;
44✔
316

317
         if (num_digits == 0)
44✔
318
            return false;
319
      }
320
      break;
321

322
   case T_ENUM:
14✔
323
      {
324
         bool upcase = true;
14✔
325
         char *copy LOCAL = xstrdup(str), *p;
27✔
326
         for (p = copy; (*p != '\0') && !isspace_iso88591(*p); p++, str++) {
55✔
327
            if (*p == '\'')
41✔
328
               upcase = false;
329
            if (upcase)
23✔
330
               *p = toupper_iso88591(*p);
14✔
331
         }
332
         *p = '\0';
14✔
333

334
         ident_t id = ident_new(copy);
14✔
335

336
         value->integer = -1;
14✔
337

338
         const int nlits = type_enum_literals(base);
14✔
339
         for (int i = 0; i < nlits; i++) {
38✔
340
            if (tree_ident(type_enum_literal(base, i)) == id) {
37✔
341
               value->integer = i;
13✔
342
               break;
13✔
343
            }
344
         }
345

346
         if (value->integer == -1)
14✔
347
            return false;
1✔
348
      }
349
      break;
350

351
   case T_REAL:
6✔
352
      {
353
         char *eptr = NULL;
6✔
354
         value->real = strtod(str, &eptr);
6✔
355
         str = eptr;
6✔
356
      }
357
      break;
6✔
358

359
   case T_PHYSICAL:
5✔
360
      {
361
         char *eptr = NULL;
5✔
362
         double scale = strtod(str, &eptr);
5✔
363
         str = eptr;
5✔
364

365
         while (isspace_iso88591(*str)) ++str;
10✔
366

367
         char *copy LOCAL = xstrdup(str), *p;
10✔
368
         for (p = copy; *p && !isspace_iso88591(*p); p++, str++)
13✔
369
            *p = toupper_iso88591(*p);
8✔
370
         *p = '\0';
5✔
371

372
         if (p == copy)
5✔
373
            return false;
374

375
         ident_t id = ident_new(copy);
4✔
376

377
         value->integer = -1;
4✔
378

379
         const int nunits = type_units(base);
4✔
380
         for (int i = 0; i < nunits; i++) {
11✔
381
            tree_t u = type_unit(base, i);
11✔
382
            if (tree_ident(u) == id) {
11✔
383
               value->integer = scale * assume_int(tree_value(u));
4✔
384
               break;
4✔
385
            }
386
         }
387

388
         if (value->integer == -1)
4✔
389
            return false;
390
      }
391
      break;
392

393
   default:
394
      return false;
395
   }
396

397
   for (; *str; str++) {
78✔
398
      if (!isspace_iso88591(*str))
11✔
399
         return false;
400
   }
401

402
   return true;
403
}
404

405
tree_t make_ref(tree_t to)
13,938✔
406
{
407
   tree_t t = tree_new(T_REF);
13,938✔
408
   tree_set_ident(t, tree_ident(to));
13,938✔
409
   tree_set_ref(t, to);
13,938✔
410
   tree_set_type(t, tree_type(to));
13,938✔
411
   return t;
13,938✔
412
}
413

414
vhdl_standard_t standard(void)
5,079,440✔
415
{
416
   return current_std;
5,079,440✔
417
}
418

419
void set_standard(vhdl_standard_t s)
3,908✔
420
{
421
   current_std = s;
3,908✔
422
   have_set_std = true;
3,908✔
423
}
3,908✔
424

425
void set_default_standard(vhdl_standard_t s)
317✔
426
{
427
   if (!have_set_std)
317✔
428
      set_standard(s);
57✔
429
}
317✔
430

431
const char *standard_text(vhdl_standard_t s)
3,567✔
432
{
433
   static const char *text[] = {
3,567✔
434
      "1987", "1993", "2000", "2002", "2008", "2019"
435
   };
436

437
   if ((unsigned)s < ARRAY_LEN(text))
3,567✔
438
      return text[s];
3,567✔
439
   else
440
      return "????";
441
}
442

443
int record_field_to_net(type_t type, unsigned pos)
×
444
{
445
   int offset = 0;
×
446
   for (int i = 0; i < pos; i++)
×
447
      offset += type_width(tree_type(type_field(type, i)));
×
448

449
   return offset;
×
450
}
451

452
tree_t find_record_field(tree_t rref)
8,461✔
453
{
454
   ident_t fname = tree_ident(rref);
8,461✔
455
   type_t value_type = tree_type(tree_value(rref));
8,461✔
456

457
   if (!type_is_record(value_type))
8,461✔
458
      return NULL;
459

460
   const int nfields = type_fields(value_type);
8,461✔
461
   for (int i = 0; i < nfields; i++) {
27,874✔
462
      tree_t field = type_field(value_type, i);
27,869✔
463
      if (tree_ident(field) == fname)
27,869✔
464
         return field;
8,456✔
465
   }
466

467
   return NULL;
468
}
469

470
tree_t find_element_mode_indication(tree_t view, tree_t field, bool *converse)
277✔
471
{
472
   switch (tree_kind(view)) {
915✔
473
   case T_REF:
397✔
474
      return find_element_mode_indication(tree_ref(view), field, converse);
397✔
475

476
   case T_ALIAS:
120✔
477
      return find_element_mode_indication(tree_value(view), field, converse);
120✔
478

479
   case T_ATTR_REF:
121✔
480
      assert(tree_subkind(view) == ATTR_CONVERSE);
121✔
481
      *converse = !*converse;
121✔
482
      return find_element_mode_indication(tree_name(view), field, converse);
121✔
483

484
   case T_VIEW_DECL:
277✔
485
      {
486
         type_t view_type = tree_type(view);
277✔
487
         assert(type_kind(view_type) == T_VIEW);
277✔
488

489
         const int nelems = type_fields(view_type);
277✔
490
         for (int i = 0; i < nelems; i++) {
491✔
491
            tree_t e = type_field(view_type, i);
491✔
492
            if (tree_ref(e) == field)
491✔
493
               return e;
277✔
494
         }
495

496
         return NULL;
497
      }
498

499
   default:
×
500
      fatal_trace("unhandled tree kind %s in find_element_mode_indication",
×
501
                  tree_kind_str(tree_kind(view)));
502
   }
503
}
504

505
port_mode_t converse_mode(tree_t port, bool converse)
181✔
506
{
507
   const port_mode_t mode = tree_subkind(port);
181✔
508
   switch (mode) {
181✔
509
   case PORT_IN: return converse ? PORT_OUT : PORT_IN;
101✔
510
   case PORT_OUT: return converse ? PORT_IN : PORT_OUT;
71✔
511
   default: return mode;
512
   }
513
}
514

515
class_t class_of(tree_t t)
1,446,930✔
516
{
517
   switch (tree_kind(t)) {
1,491,330✔
518
   case T_VAR_DECL:
519
   case T_PROT_REF:
520
      return C_VARIABLE;
521
   case T_SIGNAL_DECL:
49,690✔
522
   case T_IMPLICIT_SIGNAL:
523
      return C_SIGNAL;
49,690✔
524
   case T_CONST_DECL:
44,033✔
525
      return C_CONSTANT;
44,033✔
526
   case T_PORT_DECL:
176,638✔
527
   case T_GENERIC_DECL:
528
   case T_PARAM_DECL:
529
   case T_EXTERNAL_NAME:
530
      return tree_class(t);
176,638✔
531
   case T_ENUM_LIT:
912,322✔
532
   case T_LITERAL:
533
   case T_STRING:
534
      return C_LITERAL;
912,322✔
535
   case T_FIELD_DECL:
1,634✔
536
   case T_ATTR_DECL:
537
      return C_DEFAULT;
1,634✔
538
   case T_VIEW_DECL:
131✔
539
      return C_VIEW;
131✔
540
   case T_UNIT_DECL:
224✔
541
      return C_UNITS;
224✔
542
   case T_ARCH:
40✔
543
      return C_ARCHITECTURE;
40✔
544
   case T_FUNC_DECL:
2,243✔
545
   case T_FUNC_BODY:
546
   case T_FUNC_INST:
547
   case T_FCALL:
548
      return C_FUNCTION;
2,243✔
549
   case T_PROC_DECL:
353✔
550
   case T_PROC_BODY:
551
   case T_PROC_INST:
552
   case T_PCALL:
553
      return C_PROCEDURE;
353✔
554
   case T_ENTITY:
132✔
555
      return C_ENTITY;
132✔
556
   case T_SUBTYPE_DECL:
26,933✔
557
      return C_SUBTYPE;
26,933✔
558
   case T_TYPE_DECL:
130,024✔
559
   case T_PROT_DECL:
560
      return C_TYPE;
130,024✔
561
   case T_FILE_DECL:
1,856✔
562
      return C_FILE;
1,856✔
563
   case T_PROCESS:
73✔
564
   case T_BLOCK:
565
   case T_FOR:
566
   case T_INSTANCE:
567
   case T_CONCURRENT:
568
   case T_ELAB:
569
      return C_LABEL;
73✔
570
   case T_COMPONENT:
1✔
571
      return C_COMPONENT;
1✔
572
   case T_REF:
37,211✔
573
      return tree_has_ref(t) ? class_of(tree_ref(t)) : C_DEFAULT;
37,211✔
574
   case T_ARRAY_REF:
7,200✔
575
   case T_ARRAY_SLICE:
576
   case T_RECORD_REF:
577
   case T_ALL:
578
   case T_ALIAS:
579
   case T_QUALIFIED:
580
      return class_of(tree_value(t));
7,200✔
581
   case T_PACKAGE:
1,222✔
582
   case T_PACK_BODY:
583
   case T_PACK_INST:
584
      return C_PACKAGE;
1,222✔
585
   case T_CONFIGURATION:
1✔
586
      return C_CONFIGURATION;
1✔
587
   case T_LIBRARY:
×
588
      return C_LIBRARY;
×
589
   case T_ATTR_REF:
161✔
590
      switch (tree_subkind(t)) {
161✔
591
      case ATTR_DELAYED:
592
      case ATTR_STABLE:
593
      case ATTR_QUIET:
594
      case ATTR_TRANSACTION:
595
         return C_SIGNAL;
596
      default:
158✔
597
         return C_DEFAULT;
158✔
598
      }
599
   case T_CONTEXT:
×
600
      return C_CONTEXT;
×
601
   default:
×
602
      fatal_trace("missing class_of for %s", tree_kind_str(tree_kind(t)));
×
603
   }
604
}
605

606
bool class_has_type(class_t c)
810,634✔
607
{
608
   switch (c) {
810,634✔
609
   case C_LABEL:
610
   case C_ENTITY:
611
   case C_ARCHITECTURE:
612
   case C_COMPONENT:
613
   case C_CONFIGURATION:
614
   case C_PACKAGE:
615
   case C_LIBRARY:
616
      return false;
617
   default:
809,416✔
618
      return true;
809,416✔
619
   }
620
}
621

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

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

645
bool is_subprogram(tree_t t)
1,712,000✔
646
{
647
   switch (tree_kind(t)) {
1,712,000✔
648
   case T_FUNC_DECL:
649
   case T_FUNC_BODY:
650
   case T_FUNC_INST:
651
   case T_PROC_DECL:
652
   case T_PROC_BODY:
653
   case T_PROC_INST:
654
      return true;
655
   case T_GENERIC_DECL:
1,499✔
656
      {
657
         const class_t class = tree_class(t);
1,499✔
658
         return class == C_FUNCTION || class == C_PROCEDURE;
1,499✔
659
      }
660
   default:
1,238,750✔
661
      return false;
1,238,750✔
662
   }
663
}
664

665
bool is_loop_stmt(tree_t t)
407✔
666
{
667
   const tree_kind_t kind = tree_kind(t);
407✔
668
   return kind == T_WHILE || kind == T_FOR;
407✔
669
}
670

671
bool is_container(tree_t t)
41,394✔
672
{
673
   switch (tree_kind(t)) {
41,394✔
674
   case T_FUNC_BODY:
675
   case T_PROC_BODY:
676
   case T_ENTITY:
677
   case T_ARCH:
678
   case T_PACKAGE:
679
   case T_PACK_BODY:
680
   case T_CONFIGURATION:
681
   case T_BLOCK:
682
   case T_PROT_BODY:
683
   case T_ELAB:
684
   case T_FOR:
685
   case T_PROCESS:
686
   case T_PACK_INST:
687
      return true;
688
   default:
7,561✔
689
      return false;
7,561✔
690
   }
691
}
692

693
bool is_concurrent_block(tree_t t)
193✔
694
{
695
   switch (tree_kind(t)) {
193✔
696
   case T_ARCH:
697
   case T_ENTITY:
698
   case T_BLOCK:
699
   case T_IF_GENERATE:
700
   case T_FOR_GENERATE:
701
      return true;
702
   default:
95✔
703
      return false;
95✔
704
   }
705
}
706

707
bool is_package(tree_t t)
38,827✔
708
{
709
   switch (tree_kind(t)) {
38,827✔
710
   case T_PACKAGE:
711
   case T_PACK_BODY:
712
   case T_PACK_INST:
713
      return true;
714
   default:
3,288✔
715
      return false;
3,288✔
716
   }
717
}
718

719
bool is_design_unit(tree_t t)
19,235✔
720
{
721
   switch (tree_kind(t)) {
19,235✔
722
   case T_ENTITY:
723
   case T_ARCH:
724
   case T_PACKAGE:
725
   case T_PACK_BODY:
726
   case T_CONFIGURATION:
727
   case T_CONTEXT:
728
   case T_PACK_INST:
729
      return true;
730
   default:
2,868✔
731
      return false;
2,868✔
732
   }
733
}
734

735
bool is_guarded_signal(tree_t decl)
4,574✔
736
{
737
   return !!(tree_flags(decl) & (TREE_F_BUS | TREE_F_REGISTER));
4,574✔
738
}
739

740
bool is_type_decl(tree_t t)
19,736✔
741
{
742
   switch (tree_kind(t)) {
19,736✔
743
   case T_TYPE_DECL:
744
   case T_SUBTYPE_DECL:
745
   case T_PROT_DECL:
746
      return true;
747
   default:
18,450✔
748
      return false;
18,450✔
749
   }
750
}
751

752
tree_t aliased_type_decl(tree_t decl)
2,273,790✔
753
{
754
   switch (tree_kind(decl)) {
2,288,510✔
755
   case T_ALIAS:
14,938✔
756
      {
757
         tree_t value = tree_value(decl);
14,938✔
758
         if (tree_kind(value) == T_REF && tree_has_ref(value))
14,938✔
759
            return aliased_type_decl(tree_ref(value));
14,717✔
760
         else
761
            return NULL;
221✔
762
      }
763
   case T_TYPE_DECL:
764
   case T_SUBTYPE_DECL:
765
   case T_PROT_DECL:
766
      return decl;
767
   case T_GENERIC_DECL:
8,516✔
768
      if (tree_class(decl) == C_TYPE)
8,516✔
769
         return decl;
770
      else
771
         return NULL;
7,586✔
772
   default:
2,101,540✔
773
      return NULL;
2,101,540✔
774
   }
775
}
776

777
tree_t add_param(tree_t call, tree_t value, param_kind_t kind, tree_t name)
142,328✔
778
{
779
   tree_t p = tree_new(T_PARAM);
142,328✔
780
   tree_set_loc(p, tree_loc(value));
142,328✔
781
   tree_set_subkind(p, kind);
142,328✔
782
   tree_set_value(p, value);
142,328✔
783

784
   switch (kind) {
142,328✔
785
   case P_NAMED:
×
786
      assert(name != NULL);
×
787
      tree_set_name(p, name);
×
788
      break;
×
789
   case P_POS:
142,328✔
790
      tree_set_pos(p, tree_params(call));
142,328✔
791
      break;
142,328✔
792
   }
793

794
   tree_add_param(call, p);
142,328✔
795
   return p;
142,328✔
796
}
797

798
type_t array_aggregate_type(type_t array, int from_dim)
260✔
799
{
800
   if (type_is_none(array))
260✔
801
      return type_new(T_NONE);
1✔
802

803
   if (type_is_unconstrained(array)) {
259✔
804
      const int nindex = type_indexes(array);
36✔
805
      assert(from_dim < nindex);
36✔
806

807
      type_t type = type_new(T_ARRAY);
36✔
808
      type_set_ident(type, type_ident(array));
36✔
809
      type_set_elem(type, type_elem(array));
36✔
810

811
      for (int i = from_dim; i < nindex; i++)
72✔
812
         type_add_index(type, type_index(array, i));
36✔
813

814
      return type;
815
   }
816
   else {
817
      const int ndims = dimension_of(array);
223✔
818
      assert(from_dim < ndims);
223✔
819

820
      type_t base = type_new(T_ARRAY);
223✔
821
      type_set_ident(base, type_ident(array));
223✔
822
      type_set_elem(base, type_elem(array));
223✔
823

824
      tree_t constraint = tree_new(T_CONSTRAINT);
223✔
825
      tree_set_subkind(constraint, C_INDEX);
223✔
826

827
      type_t sub = type_new(T_SUBTYPE);
223✔
828
      type_set_base(sub, base);
223✔
829
      type_add_constraint(sub, constraint);
223✔
830

831
      for (int i = from_dim; i < ndims; i++) {
465✔
832
         tree_t r = range_of(array, i);
242✔
833
         type_add_index(base, tree_type(r));
242✔
834
         tree_add_range(constraint, r);
242✔
835
      }
836

837
      return sub;
838
   }
839
}
840

841
unsigned bits_for_range(int64_t low, int64_t high)
1,463,990✔
842
{
843
   assert(low <= high);
1,463,990✔
844

845
   if (low < 0) {
1,463,990✔
846
      // Signed integers
847
      if (low >= INT8_MIN && high <= INT8_MAX)
398,167✔
848
         return 8;
849
      else if (low >= INT16_MIN && high <= INT16_MAX)
391,605✔
850
         return 16;
851
      else if (low >= INT32_MIN && high <= INT32_MAX)
391,395✔
852
         return 32;
853
      else
854
         return 64;
101,980✔
855
   }
856
   else {
857
      // Unsigned integers
858
      if (high <= 1)
1,065,830✔
859
         return 1;
860
      else if (high <= UINT8_MAX)
476,076✔
861
         return 8;
862
      else if (high <= UINT16_MAX)
66,001✔
863
         return 16;
864
      else if (high <= UINT32_MAX)
63,765✔
865
         return 32;
866
      else
867
         return 64;
13,079✔
868
   }
869
}
870

871
unsigned dimension_of(type_t type)
1,080,570✔
872
{
873
   switch (type_kind(type)) {
1,977,940✔
874
   case T_SUBTYPE:
897,370✔
875
      return dimension_of(type_base(type));
897,370✔
876
   case T_GENERIC:
15✔
877
      assert(type_subkind(type) == GTYPE_ARRAY);
15✔
878
      // Fall-through
879
   case T_ARRAY:
880
      return type_indexes(type);
1,077,310✔
881
   case T_NONE:
882
   case T_ACCESS:
883
   case T_RECORD:
884
      return 0;
885
   case T_INTEGER:
3,211✔
886
   case T_REAL:
887
   case T_PHYSICAL:
888
   case T_ENUM:
889
      return type_dims(type);
3,211✔
890
   default:
×
891
      fatal_trace("invalid type kind %s in dimension_of",
×
892
                  type_kind_str(type_kind(type)));
893
   }
894
}
895

896
tree_t range_of(type_t type, unsigned dim)
1,222,770✔
897
{
898
   switch (type_kind(type)) {
1,252,090✔
899
   case T_SUBTYPE:
1,018,800✔
900
      if (type_constraints(type) > 0) {
1,018,800✔
901
         tree_t c0 = type_constraint(type, 0);
989,590✔
902
         switch (tree_subkind(c0)) {
989,590✔
903
         case C_OPEN:
110✔
904
            return range_of(type_base(type), dim);
110✔
905
         case C_INDEX:
989,480✔
906
         case C_RANGE:
907
            return tree_range(type_constraint(type, 0), dim);
989,480✔
908
         default:
×
909
            fatal_trace("invalid constraint in range_of");
×
910
         }
911
      }
912
      else
913
         return range_of(type_base(type), dim);
29,214✔
914
   case T_INTEGER:
233,287✔
915
   case T_REAL:
916
   case T_PHYSICAL:
917
   case T_ENUM:
918
      return type_dim(type, dim);
233,287✔
919
   default:
×
920
      fatal_trace("invalid type kind %s in range_of",
×
921
                  type_kind_str(type_kind(type)));
922
   }
923
}
924

925
range_kind_t direction_of(type_t type, unsigned dim)
22,873✔
926
{
927
   switch (type_kind(type)) {
22,917✔
928
   case T_ENUM:
929
      return RANGE_TO;
930
   case T_NONE:
×
931
      return RANGE_ERROR;
×
932
   case T_INTEGER:
22,844✔
933
   case T_REAL:
934
   case T_PHYSICAL:
935
   case T_SUBTYPE:
936
      {
937
         tree_t r = range_of(type, dim);
22,844✔
938
         const range_kind_t rkind = tree_subkind(r);
22,844✔
939
         if (rkind == RANGE_EXPR) {
22,844✔
940
            // Return a fixed direction if possible
941
            tree_t value = tree_value(r);
107✔
942
            assert(tree_kind(value) == T_ATTR_REF);
107✔
943

944
            DEBUG_ONLY({
107✔
945
                  const attr_kind_t attr = tree_subkind(value);
946
                  assert(attr == ATTR_RANGE || attr == ATTR_REVERSE_RANGE);
947
               });
107✔
948

949
            tree_t name = tree_name(value);
107✔
950
            if (tree_kind(name) == T_REF && tree_has_ref(name)) {
107✔
951
               tree_t decl = tree_ref(name);
106✔
952
               if (is_type_decl(decl))
106✔
953
                  return direction_of(tree_type(decl), 0);
44✔
954
            }
955
         }
956

957
         return rkind;
958
      }
959
   default:
×
960
      fatal_trace("invalid type kind %s in direction_of",
×
961
                  type_kind_str(type_kind(type)));
962
   }
963
}
964

965
type_t index_type_of(type_t type, unsigned dim)
192,655✔
966
{
967
   if (dim >= dimension_of(type))
192,655✔
968
      return NULL;
969

970
   type_t base = type_base_recur(type);
192,641✔
971
   type_kind_t base_kind = type_kind(base);
192,641✔
972
   if (base_kind == T_ARRAY)
192,641✔
973
      return type_index(base, dim);
189,749✔
974
   else if (base_kind == T_ENUM || base_kind == T_NONE)
2,892✔
975
      return type;
976
   else if (base_kind == T_GENERIC && type_subkind(base) == GTYPE_ARRAY)
2,746✔
977
      return type_index(base, dim);
9✔
978
   else if (base_kind == T_RECORD || base_kind == T_GENERIC)
2,737✔
979
      return NULL;
980
   else
981
      return tree_type(range_of(base, dim));
2,737✔
982
}
983

984
int64_t rebase_index(type_t array_type, int dim, int64_t value)
240✔
985
{
986
   // Convert value which is in the range of array_type to a zero-based index
987
   tree_t r = range_of(array_type, dim);
240✔
988
   const int64_t left = assume_int(tree_left(r));
240✔
989
   return (tree_subkind(r) == RANGE_TO) ? value - left : left - value;
240✔
990
}
991

992
ident_t well_known(well_known_t id)
232,018✔
993
{
994
   assert(id < NUM_WELL_KNOWN);
232,018✔
995
   return id_cache[id];
232,018✔
996
}
997

998
well_known_t is_well_known(ident_t ident)
215,392✔
999
{
1000
   well_known_t pos = 0;
215,392✔
1001
   for (; pos < NUM_WELL_KNOWN; pos++) {
6,664,900✔
1002
      if (id_cache[pos] == ident)
6,541,620✔
1003
         break;
1004
   }
1005

1006
   return pos;
215,392✔
1007
}
1008

1009
void intern_strings(void)
4,041✔
1010
{
1011
   id_cache[W_STD_STANDARD]   = ident_new("STD.STANDARD");
4,041✔
1012
   id_cache[W_ALL]            = ident_new("all");
4,041✔
1013
   id_cache[W_STD_BIT]        = ident_new("STD.STANDARD.BIT");
4,041✔
1014
   id_cache[W_STD_BOOL]       = ident_new("STD.STANDARD.BOOLEAN");
4,041✔
1015
   id_cache[W_STD_CHAR]       = ident_new("STD.STANDARD.CHARACTER");
4,041✔
1016
   id_cache[W_STD_NATURAL]    = ident_new("STD.STANDARD.NATURAL");
4,041✔
1017
   id_cache[W_STD_POSITIVE]   = ident_new("STD.STANDARD.POSITIVE");
4,041✔
1018
   id_cache[W_STD_INTEGER]    = ident_new("STD.STANDARD.INTEGER");
4,041✔
1019
   id_cache[W_STD_STRING]     = ident_new("STD.STANDARD.STRING");
4,041✔
1020
   id_cache[W_STD_REAL]       = ident_new("STD.STANDARD.REAL");
4,041✔
1021
   id_cache[W_STD_TIME]       = ident_new("STD.STANDARD.TIME");
4,041✔
1022
   id_cache[W_STD_BIT_VECTOR] = ident_new("STD.STANDARD.BIT_VECTOR");
4,041✔
1023
   id_cache[W_IEEE_SIGNED]    = ident_new("IEEE.NUMERIC_STD.SIGNED");
4,041✔
1024
   id_cache[W_IEEE_UNSIGNED]  = ident_new("IEEE.NUMERIC_STD.UNSIGNED");
4,041✔
1025
   id_cache[W_IEEE_LOGIC]     = ident_new("IEEE.STD_LOGIC_1164.STD_LOGIC");
4,041✔
1026
   id_cache[W_IEEE_ULOGIC]    = ident_new("IEEE.STD_LOGIC_1164.STD_ULOGIC");
4,041✔
1027
   id_cache[W_IEEE_1164_AND]  = ident_new("IEEE.STD_LOGIC_1164.\"and\"");
4,041✔
1028
   id_cache[W_IEEE_1164_NAND] = ident_new("IEEE.STD_LOGIC_1164.\"nand\"");
4,041✔
1029
   id_cache[W_IEEE_1164_OR]   = ident_new("IEEE.STD_LOGIC_1164.\"or\"");
4,041✔
1030
   id_cache[W_IEEE_1164_NOR]  = ident_new("IEEE.STD_LOGIC_1164.\"nor\"");
4,041✔
1031
   id_cache[W_IEEE_1164_XOR]  = ident_new("IEEE.STD_LOGIC_1164.\"xor\"");
4,041✔
1032
   id_cache[W_IEEE_1164_XNOR] = ident_new("IEEE.STD_LOGIC_1164.\"xnor\"");
4,041✔
1033
   id_cache[W_FOREIGN]        = ident_new("FOREIGN");
4,041✔
1034
   id_cache[W_WORK]           = ident_new("WORK");
4,041✔
1035
   id_cache[W_STD]            = ident_new("STD");
4,041✔
1036
   id_cache[W_THUNK]          = ident_new("thunk");
4,041✔
1037
   id_cache[W_BODY]           = ident_new("body");
4,041✔
1038
   id_cache[W_CARET]          = ident_new("^");
4,041✔
1039
   id_cache[W_IEEE]           = ident_new("IEEE");
4,041✔
1040
   id_cache[W_IEEE_1164]      = ident_new("IEEE.STD_LOGIC_1164");
4,041✔
1041
   id_cache[W_ERROR]          = ident_new("error");
4,041✔
1042
   id_cache[W_CCONV]          = ident_new("\"??\"");
4,041✔
1043
   id_cache[W_ELAB]           = ident_new("elab");
4,041✔
1044
   id_cache[W_NUMERIC_STD]    = ident_new("IEEE.NUMERIC_STD");
4,041✔
1045
   id_cache[W_NUMERIC_BIT]    = ident_new("IEEE.NUMERIC_BIT");
4,041✔
1046
   id_cache[W_NVC]            = ident_new("NVC");
4,041✔
1047
   id_cache[W_DEFAULT_CLOCK]  = ident_new("default clock");
4,041✔
1048
   id_cache[W_DOLLAR_DISPLAY] = ident_new("$display");
4,041✔
1049
   id_cache[W_DOLLAR_FINISH]  = ident_new("$finish");
4,041✔
1050
   id_cache[W_DOLLAR_WRITE]   = ident_new("$write");
4,041✔
1051
   id_cache[W_STD_REFLECTION] = ident_new("STD.REFLECTION");
4,041✔
1052

1053
   id_cache[W_NVC_PSL_SUPPORT] = ident_new("NVC.PSL_SUPPORT");
4,041✔
1054

1055
   id_cache[W_IEEE_LOGIC_VECTOR] =
8,082✔
1056
      ident_new("IEEE.STD_LOGIC_1164.STD_LOGIC_VECTOR");
4,041✔
1057
   id_cache[W_IEEE_ULOGIC_VECTOR] =
8,082✔
1058
      ident_new("IEEE.STD_LOGIC_1164.STD_ULOGIC_VECTOR");
4,041✔
1059

1060
   id_cache[W_NUMERIC_STD_UNSIGNED] = ident_new("IEEE.NUMERIC_STD_UNSIGNED");
4,041✔
1061
   id_cache[W_NUMERIC_BIT_UNSIGNED] = ident_new("IEEE.NUMERIC_BIT_UNSIGNED");
4,041✔
1062
}
4,041✔
1063

1064
bool is_uninstantiated_package(tree_t pack)
26,116✔
1065
{
1066
   return tree_kind(pack) == T_PACKAGE
26,116✔
1067
      && tree_generics(pack) > 0
25,794✔
1068
      && tree_genmaps(pack) == 0;
26,796✔
1069
}
1070

1071
bool is_uninstantiated_subprogram(tree_t decl)
91,178✔
1072
{
1073
   switch (tree_kind(decl)) {
91,178✔
1074
   case T_FUNC_DECL:
90,992✔
1075
   case T_FUNC_BODY:
1076
   case T_PROC_DECL:
1077
   case T_PROC_BODY:
1078
      return tree_generics(decl) > 0;
90,992✔
1079
   default:
1080
      return false;
1081
   }
1082
}
1083

1084
bool unit_needs_cgen(tree_t unit)
136✔
1085
{
1086
   switch (tree_kind(unit)) {
136✔
1087
   case T_PACK_INST:
1088
      return true;
1089
   case T_PACK_BODY:
×
1090
      {
1091
         tree_t pack = tree_primary(unit);
×
1092
         return package_needs_body(pack) && !is_uninstantiated_package(pack);
×
1093
      }
1094
   case T_PACKAGE:
9✔
1095
      return !package_needs_body(unit) && !is_uninstantiated_package(unit);
18✔
1096
   default:
×
1097
      return false;
×
1098
   }
1099
}
1100

1101
bool package_needs_body(tree_t pack)
1,374✔
1102
{
1103
   assert(tree_kind(pack) == T_PACKAGE);
1,374✔
1104

1105
   const int ndecls = tree_decls(pack);
1,374✔
1106
   for (int i = 0; i < ndecls; i++) {
97,679✔
1107
      tree_t d = tree_decl(pack, i);
96,938✔
1108

1109
      switch (tree_kind(d)) {
96,938✔
1110
      case T_FUNC_DECL:
86,348✔
1111
      case T_PROC_DECL:
1112
         if (tree_flags(d) & TREE_F_PREDEFINED)
86,348✔
1113
            continue;
85,466✔
1114
         else if (tree_subkind(d) == S_FOREIGN)
882✔
1115
            continue;
386✔
1116
         return true;
1117

1118
      case T_CONST_DECL:
649✔
1119
         if (!tree_has_value(d))
649✔
1120
            return true;
1121
         continue;
590✔
1122

1123
      case T_PROT_DECL:
1124
         return true;
1125

1126
      default:
9,863✔
1127
         continue;
9,863✔
1128
      }
1129
   }
1130

1131
   return false;
1132
}
1133

1134
tree_t search_decls(tree_t container, ident_t name, int nth)
32,170✔
1135
{
1136
   tree_kind_t kind = tree_kind(container);
32,170✔
1137
   if (kind == T_LIBRARY) {
32,170✔
1138
      if (nth == 0) {
×
1139
         lib_t lib = lib_require(tree_ident(container));
×
1140
         return lib_get(lib, name);
×
1141
      }
1142
      else
1143
         return NULL;
1144
   }
1145
   else if (kind == T_ENTITY || kind == T_BLOCK) {
32,170✔
1146
      const int nports = tree_ports(container);
265✔
1147
      for (int i = 0; i < nports; i++) {
290✔
1148
         tree_t p = tree_port(container, i);
25✔
1149
         if (tree_ident(p) == name && nth-- == 0)
25✔
1150
            return p;
×
1151
      }
1152
   }
1153
   else if (!is_container(container))
31,905✔
1154
      return NULL;
1155

1156
   // TODO: how to improve this?
1157
   const int ndecls = tree_decls(container);
32,170✔
1158
   tree_t best = NULL;
32,170✔
1159

1160
   for (int i = 0; i < ndecls; i++) {
1,790,800✔
1161
      tree_t d = tree_decl(container, i);
1,790,640✔
1162
      if (!tree_has_ident(d))
1,790,640✔
1163
         continue;
×
1164
      else if (tree_ident(d) == name) {
1,790,640✔
1165
         if (tree_kind(d) == T_TYPE_DECL
20,577✔
1166
             && type_kind(tree_type(d)) == T_INCOMPLETE)
19,342✔
1167
            best = d;
1168
         else if (nth-- == 0)
20,545✔
1169
            return d;
20,370✔
1170
      }
1171
      else if (tree_kind(d) == T_TYPE_DECL) {
1,770,060✔
1172
         type_t type = tree_type(d);
139,133✔
1173
         switch (type_kind(type)) {
139,133✔
1174
         case T_ENUM:
104,909✔
1175
            {
1176
               const int nlits = type_enum_literals(type);
104,909✔
1177
               for (int j = 0; j < nlits; j++) {
7,054,320✔
1178
                  tree_t lit = type_enum_literal(type, j);
6,961,050✔
1179
                  if (tree_ident(lit) == name && nth-- == 0)
6,961,050✔
1180
                     return lit;
11,636✔
1181
               }
1182
            }
1183
            break;
1184
         default:
1185
            break;
1186
         }
1187
      }
1,630,930✔
1188
   }
1189

1190
   return best;
1191
}
1192

1193
static tree_t cached_unit(tree_t hint, tree_t *cache, well_known_t lib_name,
19,169✔
1194
                          well_known_t unit_name)
1195
{
1196
   const vhdl_standard_t curr = standard();
19,169✔
1197

1198
   if (cache[curr] == NULL) {
19,169✔
1199
      if (hint != NULL)
3,433✔
1200
         cache[curr] = hint;
956✔
1201
      else {
1202
         lib_t std = lib_require(well_known(lib_name));
2,477✔
1203
         cache[curr] = lib_get(std, well_known(unit_name));
2,477✔
1204
         assert(cache[curr] != NULL);
2,477✔
1205
      }
1206
   }
1207

1208
   assert(hint == NULL || hint == cache[curr]);
19,169✔
1209
   return cache[curr];
19,169✔
1210
}
1211

1212
static tree_t cached_std(tree_t hint)
19,094✔
1213
{
1214
   static tree_t standard_cache[STD_19 + 1] = {};
19,094✔
1215
   return cached_unit(hint, standard_cache, W_STD, W_STD_STANDARD);
19,094✔
1216
}
1217

1218
type_t std_type(tree_t std, std_type_t which)
2,122,130✔
1219
{
1220
   static type_t cache[STD_FILE_OPEN_STATE + 1] = {};
2,122,130✔
1221
   assert(which < ARRAY_LEN(cache));
2,122,130✔
1222

1223
   if (cache[which] == NULL) {
2,122,130✔
1224
      const char *names[] = {
19,094✔
1225
         "universal_integer",
1226
         "universal_real",
1227
         "INTEGER",
1228
         "REAL",
1229
         "BOOLEAN",
1230
         "STRING",
1231
         "TIME",
1232
         "BIT",
1233
         "FILE_OPEN_KIND",
1234
         "FILE_OPEN_STATUS",
1235
         "NATURAL",
1236
         "BIT_VECTOR",
1237
         "SEVERITY_LEVEL",
1238
         "FILE_ORIGIN_KIND",
1239
         "FILE_OPEN_STATE",
1240
      };
1241

1242
      tree_t d = search_decls(cached_std(std), ident_new(names[which]), 0);
19,094✔
1243
      if (d == NULL)
19,094✔
1244
         fatal_trace("cannot find standard type %s", names[which]);
×
1245

1246
      // Do not cache standard types while bootstrapping as the GC will
1247
      // move the objects after parsing
1248
      static int can_cache = -1;
19,094✔
1249
      if (can_cache == -1) can_cache = !opt_get_int(OPT_BOOTSTRAP);
19,094✔
1250

1251
      if (can_cache)
19,094✔
1252
         return (cache[which] = tree_type(d));
18,344✔
1253
      else
1254
         return tree_type(d);
750✔
1255
   }
1256
   else
1257
      return cache[which];
1258
}
1259

1260
type_t ieee_type(ieee_type_t which)
310✔
1261
{
1262
   static type_t cache[IEEE_STD_LOGIC + 1] = {};
310✔
1263
   assert(which < ARRAY_LEN(cache));
310✔
1264

1265
   if (cache[which] == NULL) {
310✔
1266
      const char *names[] = {
43✔
1267
         "STD_ULOGIC",
1268
         "STD_LOGIC",
1269
      };
1270

1271
      static tree_t ieee_cache[STD_19 + 1] = {};
43✔
1272
      tree_t unit = cached_unit(NULL, ieee_cache, W_IEEE, W_IEEE_1164);
43✔
1273

1274
      tree_t d = search_decls(unit, ident_new(names[which]), 0);
43✔
1275
      if (d == NULL)
43✔
1276
         fatal_trace("cannot find IEEE type %s", names[which]);
×
1277

1278
      // STD.STANDARD cannot depend on IEEE
1279
      assert(!opt_get_int(OPT_BOOTSTRAP));
43✔
1280

1281
      return (cache[which] = tree_type(d));
43✔
1282
   }
1283
   else
1284
      return cache[which];
1285
}
1286

1287
type_t reflection_type(reflect_type_t which)
183✔
1288
{
1289
   static type_t cache[REFLECT_SUBTYPE_MIRROR + 1] = {};
183✔
1290
   assert(which < ARRAY_LEN(cache));
183✔
1291

1292
   if (cache[which] == NULL) {
183✔
1293
      const char *names[] = {
32✔
1294
         "VALUE_MIRROR",
1295
         "SUBTYPE_MIRROR",
1296
      };
1297

1298
      static tree_t reflect_cache[STD_19 + 1] = {};
32✔
1299
      tree_t unit = cached_unit(NULL, reflect_cache, W_STD, W_STD_REFLECTION);
32✔
1300

1301
      tree_t d = search_decls(unit, ident_new(names[which]), 0);
32✔
1302
      if (d == NULL)
32✔
1303
         fatal_trace("cannot find REFLECTION type %s", names[which]);
×
1304

1305
      // STD.STANDARD cannot depend on REFLECTION
1306
      assert(!opt_get_int(OPT_BOOTSTRAP));
32✔
1307

1308
      return (cache[which] = tree_type(d));
32✔
1309
   }
1310
   else
1311
      return cache[which];
1312
}
1313

1314
bool is_builtin(subprogram_kind_t kind)
12,845,700✔
1315
{
1316
   return kind != S_USER && kind != S_FOREIGN;
12,845,700✔
1317
}
1318

1319
bool is_open_coded_builtin(subprogram_kind_t kind)
348,083✔
1320
{
1321
   switch (kind) {
348,083✔
1322
   case S_USER:
1323
   case S_FOREIGN:
1324
   case S_ARRAY_EQ:
1325
   case S_ARRAY_NEQ:
1326
   case S_ARRAY_LT:
1327
   case S_ARRAY_LE:
1328
   case S_ARRAY_GT:
1329
   case S_ARRAY_GE:
1330
   case S_RECORD_EQ:
1331
   case S_RECORD_NEQ:
1332
   case S_TO_STRING:
1333
   case S_SLL:
1334
   case S_SRL:
1335
   case S_SLA:
1336
   case S_SRA:
1337
   case S_ROL:
1338
   case S_ROR:
1339
   case S_ARRAY_NOT:
1340
   case S_ARRAY_AND:
1341
   case S_ARRAY_OR:
1342
   case S_ARRAY_XOR:
1343
   case S_ARRAY_XNOR:
1344
   case S_ARRAY_NAND:
1345
   case S_ARRAY_NOR:
1346
   case S_MIXED_AND:
1347
   case S_MIXED_OR:
1348
   case S_MIXED_XOR:
1349
   case S_MIXED_XNOR:
1350
   case S_MIXED_NAND:
1351
   case S_MIXED_NOR:
1352
   case S_REDUCE_OR:
1353
   case S_REDUCE_AND:
1354
   case S_REDUCE_NAND:
1355
   case S_REDUCE_NOR:
1356
   case S_REDUCE_XOR:
1357
   case S_REDUCE_XNOR:
1358
   case S_MATCH_EQ:
1359
   case S_MATCH_NEQ:
1360
   case S_MATCH_LT:
1361
   case S_MATCH_LE:
1362
   case S_MATCH_GT:
1363
   case S_MATCH_GE:
1364
   case S_MINIMUM:
1365
   case S_MAXIMUM:
1366
      return false;
1367
   default:
214,422✔
1368
      return true;
214,422✔
1369
   }
1370
}
1371

1372
tree_t std_func(ident_t mangled)
×
1373
{
1374
   tree_t std = cached_std(NULL);
×
1375

1376
   const int ndecls = tree_decls(std);
×
1377
   for (int i = 0; i < ndecls; i++) {
×
1378
      tree_t d = tree_decl(std, i);
×
1379
      if (is_subprogram(d) && tree_has_ident2(d) && tree_ident2(d) == mangled)
×
1380
         return d;
×
1381
   }
1382

1383
   return NULL;
1384
}
1385

1386
tree_t name_to_ref(tree_t name)
79,188✔
1387
{
1388
   tree_kind_t kind;
79,188✔
1389
   while ((kind = tree_kind(name)) != T_REF) {
89,869✔
1390
      switch (kind) {
12,020✔
1391
      case T_ARRAY_REF:
10,681✔
1392
      case T_ARRAY_SLICE:
1393
      case T_RECORD_REF:
1394
      case T_ALL:
1395
         name = tree_value(name);
10,681✔
1396
         break;
10,681✔
1397
      default:
1398
         return NULL;
1399
      }
1400
   }
1401

1402
   return name;
1403
}
1404

1405
const char *port_mode_str(port_mode_t mode)
22✔
1406
{
1407
   const char *mode_str[] = {
22✔
1408
      "INVALID", "IN", "OUT", "INOUT", "BUFFER", "LINKAGE", "VIEW", "VIEW"
1409
   };
1410
   assert(mode < ARRAY_LEN(mode_str));
22✔
1411
   return mode_str[mode];
22✔
1412
}
1413

1414
void mangle_one_type(text_buf_t *buf, type_t type)
154,969✔
1415
{
1416
   ident_t ident = type_ident(type);
154,969✔
1417

1418
   char code = 0;
154,969✔
1419
   switch (is_well_known(ident)) {
154,969✔
1420
   case W_STD_INTEGER:        code = 'I'; break;
1421
   case W_STD_STRING:         code = 'S'; break;
3,021✔
1422
   case W_STD_REAL:           code = 'R'; break;
3,275✔
1423
   case W_STD_BOOL:           code = 'B'; break;
20,771✔
1424
   case W_STD_CHAR:           code = 'C'; break;
651✔
1425
   case W_STD_TIME:           code = 'T'; break;
891✔
1426
   case W_STD_NATURAL:        code = 'N'; break;
3,929✔
1427
   case W_STD_POSITIVE:       code = 'P'; break;
324✔
1428
   case W_STD_BIT:            code = 'J'; break;
2,345✔
1429
   case W_STD_BIT_VECTOR:     code = 'Q'; break;
2,263✔
1430
   case W_IEEE_LOGIC:         code = 'L'; break;
244✔
1431
   case W_IEEE_ULOGIC:        code = 'U'; break;
4,694✔
1432
   case W_IEEE_LOGIC_VECTOR:  code = 'V'; break;
1,539✔
1433
   case W_IEEE_ULOGIC_VECTOR: code = 'Y'; break;
1,398✔
1434
   default: break;
1435
   }
1436

1437
   if (code)
45,345✔
1438
      tb_append(buf, code);
57,139✔
1439
   else {
1440
      tb_printf(buf, "%zu", ident_len(ident));
97,830✔
1441
      tb_istr(buf, ident);
97,830✔
1442
   }
1443
}
154,969✔
1444

1445
tree_t primary_unit_of(tree_t unit)
7,212✔
1446
{
1447
   switch (tree_kind(unit)) {
7,212✔
1448
   case T_ENTITY:
1449
   case T_COMPONENT:
1450
   case T_PACKAGE:
1451
   case T_BLOCK:
1452
      return unit;
1453
   case T_ARCH:
687✔
1454
   case T_CONFIGURATION:
1455
   case T_PACK_BODY:
1456
      return tree_primary(unit);
687✔
1457
   default:
×
1458
      fatal_trace("invalid kind %s in primary_unit_of",
×
1459
                  tree_kind_str(tree_kind(unit)));
1460
   }
1461
}
1462

1463
unsigned get_case_choice_char(tree_t value, int depth)
7,541✔
1464
{
1465
   switch (tree_kind(value)) {
7,541✔
1466
   case T_STRING:
6,791✔
1467
      if (depth < tree_chars(value)) {
6,791✔
1468
         tree_t ch = tree_char(value, depth);
6,790✔
1469
         return tree_pos(tree_ref(ch));
6,790✔
1470
      }
1471
      else
1472
         return ~0;   // Out of bounds
1473

1474
   case T_AGGREGATE:
14✔
1475
      {
1476
         const int nassocs = tree_assocs(value);
14✔
1477
         type_t type = tree_type(value);
14✔
1478

1479
         for (int i = 0; i < nassocs; i++) {
24✔
1480
            tree_t a = tree_assoc(value, i);
23✔
1481
            switch (tree_subkind(a)) {
23✔
1482
            case A_NAMED:
×
1483
               if (rebase_index(type, 0, assume_int(tree_name(a))) == depth)
×
1484
                  return assume_int(tree_value(a));
×
1485
               break;
1486

1487
            case A_POS:
23✔
1488
               if (tree_pos(a) == (unsigned)depth)
23✔
1489
                  return assume_int(tree_value(a));
13✔
1490
               break;
1491

1492
            case A_OTHERS:
×
1493
               return assume_int(tree_value(a));
×
1494
            }
1495
         }
10✔
1496

1497
         // This will produce an error during bounds checking
1498
         return ~0;
1499
      }
1500

1501
   case T_REF:
392✔
1502
      {
1503
         tree_t decl = tree_ref(value);
392✔
1504
         assert(tree_kind(decl) == T_CONST_DECL || tree_kind(decl) == T_ALIAS);
392✔
1505
         assert(tree_has_value(decl));
392✔
1506
         return get_case_choice_char(tree_value(decl), depth);
392✔
1507
      }
1508

1509
   case T_ARRAY_SLICE:
240✔
1510
      {
1511
         tree_t base = tree_value(value);
240✔
1512
         tree_t r = tree_range(value, 0);
240✔
1513
         const int64_t rleft = assume_int(tree_left(r));
240✔
1514
         const int64_t offset = rebase_index(tree_type(base), 0, rleft);
240✔
1515
         return get_case_choice_char(base, depth + offset);
240✔
1516
      }
1517

1518
   case T_FCALL:
104✔
1519
      if (tree_subkind(tree_ref(value)) == S_CONCAT) {
104✔
1520
         const int nparams = tree_params(value);
104✔
1521
         for (int i = 0; i < nparams; i++) {
156✔
1522
            tree_t left = tree_value(tree_param(value, i));
156✔
1523

1524
            tree_t lr = range_of(tree_type(left), 0);
156✔
1525
            int64_t left_len;
156✔
1526
            if (!folded_length(lr, &left_len))
156✔
1527
               fatal_at(tree_loc(left), "cannot determine length of left hand "
×
1528
                        "side of concatenation");
1529

1530
            if (depth < left_len || i + 1 == nparams)
156✔
1531
               return get_case_choice_char(left, depth);
104✔
1532

1533
            depth -= left_len;
52✔
1534
         }
1535
      }
1536
      // Fall-through
1537

1538
   default:
1539
      fatal_at(tree_loc(value), "unsupported tree type %s in case choice",
×
1540
               tree_kind_str(tree_kind(value)));
1541
   }
1542
}
1543

1544
int64_t encode_case_choice(tree_t value, int length, int bits)
977✔
1545
{
1546
   uint64_t enc = 0;
977✔
1547
   for (int i = 0; i < length; i++) {
7,776✔
1548
      if (bits > 0) {
6,799✔
1549
         enc <<= bits;
1,631✔
1550
         enc |= get_case_choice_char(value, i);
1,631✔
1551
      }
1552
      else {
1553
         enc *= 0x27d4eb2d;
5,168✔
1554
         enc += get_case_choice_char(value, i);
5,168✔
1555
      }
1556
   }
1557

1558
   return enc;
977✔
1559
}
1560

1561
void to_string(text_buf_t *tb, type_t type, int64_t value)
544✔
1562
{
1563
   if (type_is_integer(type))
544✔
1564
      tb_printf(tb, "%"PRIi64, value);
410✔
1565
   else if (type_is_enum(type)) {
134✔
1566
      type_t base = type_base_recur(type);
62✔
1567
      if (value < 0 || value >= type_enum_literals(base))
62✔
1568
         tb_printf(tb, "%"PRIi64, value);
3✔
1569
      else
1570
         tb_cat(tb, istr(tree_ident(type_enum_literal(base, value))));
59✔
1571
   }
1572
   else if (type_is_physical(type)) {
72✔
1573
      type_t base = type_base_recur(type);
24✔
1574
      const unsigned nunits = type_units(base);
24✔
1575
      tree_t max_unit = NULL;
24✔
1576
      int64_t max_unit_value = 0;
24✔
1577

1578
      // Find the largest unit that evenly divides the given value
1579
      for (unsigned u = 0; u < nunits; u++) {
216✔
1580
         tree_t unit = type_unit(base, u);
192✔
1581
         const int64_t unit_value = assume_int(tree_value(unit));
192✔
1582
         if ((unit_value > max_unit_value) && (value % unit_value == 0)) {
192✔
1583
            max_unit = unit;
90✔
1584
            max_unit_value = unit_value;
90✔
1585
         }
1586
      }
1587
      assert(max_unit);
24✔
1588

1589
      tb_printf(tb, "%"PRIi64" %s", value / max_unit_value,
24✔
1590
                istr(tree_ident(max_unit)));
1591
   }
1592
   else if (type_is_real(type)) {
48✔
1593
      union { int64_t i; double r; } u = { .i = value };
42✔
1594
      tb_printf(tb, "%.17g", u.r);
42✔
1595
   }
1596
   else if (type_is_access(type)) {
6✔
1597
      if (value == 0)
6✔
1598
         tb_cat(tb, "NULL");
3✔
1599
      else
1600
         tb_printf(tb, "%p", (void *)value);
3✔
1601
   }
1602
}
544✔
1603

1604
static bool is_static(tree_t expr)
4,859✔
1605
{
1606
   switch (tree_kind(expr)) {
4,958✔
1607
   case T_REF:
428✔
1608
      {
1609
         tree_t decl = tree_ref(expr);
428✔
1610
         switch (tree_kind(decl)) {
428✔
1611
         case T_CONST_DECL:
117✔
1612
            return !(tree_flags(decl) & TREE_F_SEQ_BLOCK);
117✔
1613
         case T_UNIT_DECL:
1614
         case T_ENUM_LIT:
1615
         case T_GENERIC_DECL:
1616
            return true;
1617
         case T_ALIAS:
×
1618
            return is_static(tree_value(decl));
×
1619
         default:
113✔
1620
            return false;
113✔
1621
         }
1622
      }
1623

1624
   case T_LITERAL:
1625
   case T_STRING:
1626
      return true;
1627

1628
   case T_FCALL:
310✔
1629
      return !!(tree_flags(expr) & (TREE_F_LOCALLY_STATIC
310✔
1630
                                    | TREE_F_GLOBALLY_STATIC));
1631

1632
   case T_RECORD_REF:
99✔
1633
      return is_static(tree_value(expr));
99✔
1634

1635
   default:
×
1636
      return false;
×
1637
   }
1638
}
1639

1640
tree_t longest_static_prefix(tree_t expr)
17,166✔
1641
{
1642
   switch (tree_kind(expr)) {
17,166✔
1643
   case T_ARRAY_REF:
3,382✔
1644
      {
1645
         tree_t value = tree_value(expr);
3,382✔
1646
         tree_t prefix = longest_static_prefix(value);
3,382✔
1647

1648
         if (prefix != value)
3,382✔
1649
            return prefix;
1650

1651
         const int nparams = tree_params(expr);
3,369✔
1652
         for (int i = 0; i < nparams; i++) {
7,018✔
1653
            if (!is_static(tree_value(tree_param(expr, i))))
3,795✔
1654
               return prefix;
1655
         }
1656

1657
         return expr;
1658
      }
1659

1660
   case T_ARRAY_SLICE:
548✔
1661
      {
1662
         tree_t value = tree_value(expr);
548✔
1663
         tree_t prefix = longest_static_prefix(value);
548✔
1664

1665
         if (prefix != value)
548✔
1666
            return prefix;
1667

1668
         const int nranges = tree_ranges(expr);
541✔
1669
         for (int i = 0; i < nranges; i++) {
1,066✔
1670
            tree_t r = tree_range(expr, i);
541✔
1671
            if (tree_subkind(r) == RANGE_EXPR)
541✔
1672
               return prefix;
1673
            else if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
538✔
1674
               return prefix;
13✔
1675
         }
1676

1677
         return expr;
1678
      }
1679

1680
   case T_RECORD_REF:
938✔
1681
      {
1682
         tree_t value = tree_value(expr);
938✔
1683
         tree_t prefix = longest_static_prefix(value);
938✔
1684

1685
         if (prefix != value)
938✔
1686
            return prefix;
×
1687

1688
         return expr;
1689
      }
1690

1691
   default:
1692
      return expr;
1693
   }
1694
}
1695

1696
tree_t body_of(tree_t pack)
646✔
1697
{
1698
   const tree_kind_t kind = tree_kind(pack);
646✔
1699
   if (kind == T_PACK_INST)
646✔
1700
      return NULL;
1701

1702
   assert(tree_kind(pack) == T_PACKAGE);
646✔
1703

1704
   ident_t body_i = well_known(W_BODY);
646✔
1705
   ident_t body_name = ident_prefix(tree_ident(pack), body_i, '-');
646✔
1706
   return lib_get_qualified(body_name);
646✔
1707
}
1708

1709
tree_t find_generic_map(tree_t unit, int pos, tree_t g)
1,105✔
1710
{
1711
   const int ngenmaps = tree_genmaps(unit);
1,105✔
1712

1713
   if (pos < ngenmaps) {
1,105✔
1714
      tree_t m = tree_genmap(unit, pos);
1,102✔
1715
      if (tree_subkind(m) == P_POS && tree_pos(m) == pos)
1,102✔
1716
         return tree_value(m);
593✔
1717
   }
1718

1719
   for (int j = 0; j < ngenmaps; j++) {
1,345✔
1720
      tree_t m = tree_genmap(unit, j);
1,342✔
1721
      switch (tree_subkind(m)) {
1,342✔
1722
      case P_NAMED:
979✔
1723
         {
1724
            tree_t name = tree_name(m);
979✔
1725
            assert(tree_kind(name) == T_REF);
979✔
1726

1727
            if (tree_ref(name) == g)
979✔
1728
               return tree_value(m);
313✔
1729
         }
1730
         break;
1731

1732
      case P_POS:
363✔
1733
         if (tree_pos(m) == pos)
363✔
1734
            return tree_value(m);
196✔
1735
         break;
1736

1737
      default:
1738
         break;
1739
      }
1740
   }
1741

1742
   return NULL;
1743
}
1744

1745
bool relaxed_rules(void)
826,995✔
1746
{
1747
   return opt_get_int(OPT_RELAXED);
826,995✔
1748
}
1749

1750
bool is_type_attribute(attr_kind_t kind)
61,307✔
1751
{
1752
   switch (kind) {
61,307✔
1753
   case ATTR_SUBTYPE:
1754
   case ATTR_BASE:
1755
   case ATTR_ELEMENT:
1756
   case ATTR_DESIGNATED_SUBTYPE:
1757
   case ATTR_INDEX:
1758
      return true;
1759
   default:
60,980✔
1760
      return false;
60,980✔
1761
   }
1762
}
1763

1764
bool attribute_has_param(attr_kind_t attr)
20,413✔
1765
{
1766
   switch (attr) {
20,413✔
1767
   case ATTR_IMAGE:
1768
   case ATTR_SUCC:
1769
   case ATTR_PRED:
1770
   case ATTR_DELAYED:
1771
   case ATTR_LEFTOF:
1772
   case ATTR_RIGHTOF:
1773
   case ATTR_VALUE:
1774
   case ATTR_POS:
1775
   case ATTR_LOW:
1776
   case ATTR_HIGH:
1777
   case ATTR_LEFT:
1778
   case ATTR_RIGHT:
1779
   case ATTR_LENGTH:
1780
   case ATTR_RANGE:
1781
   case ATTR_REVERSE_RANGE:
1782
   case ATTR_VAL:
1783
   case ATTR_QUIET:
1784
   case ATTR_STABLE:
1785
   case ATTR_INDEX:
1786
   case ATTR_ASCENDING:
1787
      return true;
1788
   default:
1,808✔
1789
      return false;
1,808✔
1790
   }
1791
}
1792

1793
type_t get_type_or_null(tree_t t)
1,745,390✔
1794
{
1795
   switch (tree_kind(t)) {
1,745,390✔
1796
   case T_LIBRARY:
1797
   case T_ATTR_SPEC:
1798
   case T_PACKAGE:
1799
   case T_PACK_INST:
1800
   case T_PACK_BODY:
1801
   case T_ENTITY:
1802
   case T_ARCH:
1803
   case T_PROCESS:
1804
   case T_COMPONENT:
1805
   case T_INSTANCE:
1806
   case T_CONCURRENT:
1807
   case T_BLOCK:
1808
   case T_WHILE:
1809
   case T_FOR:
1810
   case T_GROUP_TEMPLATE:
1811
   case T_CONFIGURATION:
1812
   case T_GROUP:
1813
   case T_FOR_GENERATE:
1814
   case T_IF_GENERATE:
1815
   case T_USE:
1816
   case T_CONTEXT:
1817
   case T_PSL:
1818
      return NULL;
1819
   default:
1,677,040✔
1820
      if (tree_has_type(t))
1,677,040✔
1821
         return tree_type(t);
1,676,070✔
1822
      else
1823
         return NULL;
1824
   }
1825
}
1826

1827
type_t subtype_for_string(tree_t str, type_t base)
23,756✔
1828
{
1829
   if (!type_is_unconstrained(base))
23,756✔
1830
      return base;
1831

1832
   // Construct a new constrained array subtype: the direction and
1833
   // bounds are the same as those for a positional array aggregate
1834
   type_t sub = type_new(T_SUBTYPE);
21,031✔
1835
   type_set_base(sub, base);
21,031✔
1836

1837
   type_t index_type = index_type_of(base, 0);
21,031✔
1838
   const bool is_enum = type_is_enum(index_type);
21,031✔
1839

1840
   // The direction is determined by the index type
1841
   range_kind_t dir = direction_of(index_type, 0);
21,031✔
1842

1843
   // The left bound is the left of the index type and the right bound
1844
   // is determined by the number of elements
1845

1846
   tree_t left = NULL, right = NULL;
21,031✔
1847

1848
   if (is_enum)
21,031✔
1849
      left = make_ref(type_enum_literal(type_base_recur(index_type), 0));
1✔
1850
   else
1851
      left = tree_left(range_of(index_type, 0));
21,030✔
1852

1853
   const int nchars = tree_chars(str);
21,031✔
1854
   int64_t iright;
21,031✔
1855
   if (dir == RANGE_DOWNTO)
21,031✔
1856
      iright = assume_int(left) - nchars + 1;
×
1857
   else
1858
      iright = assume_int(left) + nchars - 1;
21,031✔
1859

1860
   if (is_enum)
21,031✔
1861
      right = get_enum_lit(str, index_type, iright);
1✔
1862
   else
1863
      right = get_int_lit(str, index_type, iright);
21,030✔
1864

1865
   tree_t r = tree_new(T_RANGE);
21,031✔
1866
   tree_set_subkind(r, dir);
21,031✔
1867
   tree_set_left(r, left);
21,031✔
1868
   tree_set_right(r, right);
21,031✔
1869
   tree_set_loc(r, tree_loc(str));
21,031✔
1870
   tree_set_type(r, index_type);
21,031✔
1871

1872
   tree_t c = tree_new(T_CONSTRAINT);
21,031✔
1873
   tree_set_subkind(c, C_INDEX);
21,031✔
1874
   tree_add_range(c, r);
21,031✔
1875
   tree_set_loc(c, tree_loc(str));
21,031✔
1876

1877
   type_add_constraint(sub, c);
21,031✔
1878

1879
   return sub;
21,031✔
1880
}
1881

1882
tree_t change_ref(tree_t name, tree_t new)
1,678✔
1883
{
1884
   switch (tree_kind(name)) {
1,678✔
1885
   case T_REF:
1,138✔
1886
      return make_ref(new);
1,138✔
1887

1888
   case T_ARRAY_REF:
89✔
1889
      {
1890
         tree_t t = tree_new(T_ARRAY_REF);
89✔
1891
         tree_set_loc(t, tree_loc(name));
89✔
1892
         tree_set_value(t, change_ref(tree_value(name), new));
89✔
1893
         tree_set_type(t, tree_type(name));
89✔
1894

1895
         const int nparams = tree_params(name);
89✔
1896
         for (int i = 0; i < nparams; i++)
178✔
1897
            tree_add_param(t, tree_param(name, i));
89✔
1898

1899
         return t;
1900
      }
1901

1902
   case T_ARRAY_SLICE:
43✔
1903
      {
1904
         tree_t t = tree_new(T_ARRAY_SLICE);
43✔
1905
         tree_set_loc(t, tree_loc(name));
43✔
1906
         tree_set_value(t, change_ref(tree_value(name), new));
43✔
1907
         tree_set_type(t, tree_type(name));
43✔
1908
         tree_add_range(t, tree_range(name, 0));
43✔
1909

1910
         return t;
43✔
1911
      }
1912

1913
   case T_RECORD_REF:
351✔
1914
      {
1915
         tree_t t = tree_new(T_RECORD_REF);
351✔
1916
         tree_set_loc(t, tree_loc(name));
351✔
1917
         tree_set_value(t, change_ref(tree_value(name), new));
351✔
1918
         tree_set_type(t, tree_type(name));
351✔
1919
         tree_set_ident(t, tree_ident(name));
351✔
1920
         tree_set_ref(t, tree_ref(name));
351✔
1921

1922
         return t;
351✔
1923
      }
1924

1925
   case T_CONV_FUNC:
54✔
1926
      {
1927
         tree_t t = tree_new(T_CONV_FUNC);
54✔
1928
         tree_set_loc(t, tree_loc(name));
54✔
1929
         tree_set_value(t, change_ref(tree_value(name), new));
54✔
1930
         tree_set_ident(t, tree_ident(name));
54✔
1931
         tree_set_type(t, tree_type(name));
54✔
1932
         tree_set_ref(t, tree_ref(name));
54✔
1933

1934
         return t;
54✔
1935
      }
1936

1937
   case T_TYPE_CONV:
3✔
1938
      {
1939
         tree_t t = tree_new(T_TYPE_CONV);
3✔
1940
         tree_set_loc(t, tree_loc(name));
3✔
1941
         tree_set_type(t, tree_type(name));
3✔
1942
         tree_set_value(t, change_ref(tree_value(name), new));
3✔
1943

1944
         return t;
3✔
1945
      }
1946

1947
   default:
×
1948
      fatal_trace("cannot handle tree kind %s in elab_change_ref",
×
1949
                  tree_kind_str(tree_kind(name)));
1950
   }
1951
}
1952

1953
static void build_wait_for_target(tree_t expr, build_wait_fn_t fn, void *ctx)
2,013✔
1954
{
1955
   switch (tree_kind(expr)) {
2,013✔
1956
   case T_ARRAY_SLICE:
60✔
1957
      build_wait(tree_range(expr, 0), fn, ctx);
60✔
1958
      break;
60✔
1959

1960
   case T_ARRAY_REF:
280✔
1961
      {
1962
         const int nparams = tree_params(expr);
280✔
1963
         for (int i = 0; i < nparams; i++)
560✔
1964
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
280✔
1965
      }
1966
      break;
1967

1968
   default:
1969
      break;
1970
   }
1971
}
2,013✔
1972

1973
void build_wait(tree_t expr, build_wait_fn_t fn, void *ctx)
9,308✔
1974
{
1975
   // LRM 08 section 10.2 has rules for building a wait statement from a
1976
   // sensitivity list. LRM 08 section 11.3 extends these rules to
1977
   // all-sensitised processes.
1978

1979
   switch (tree_kind(expr)) {
11,797✔
1980
   case T_REF:
2,936✔
1981
      if (class_of(tree_ref(expr)) == C_SIGNAL)
2,936✔
1982
         (*fn)(expr, ctx);
1,614✔
1983
      break;
1984

1985
   case T_EXTERNAL_NAME:
3✔
1986
      if (tree_class(expr) == C_SIGNAL)
3✔
1987
         (*fn)(expr, ctx);
3✔
1988
      break;
1989

1990
   case T_WAVEFORM:
2,415✔
1991
   case T_QUALIFIED:
1992
   case T_TYPE_CONV:
1993
   case T_ASSERT:
1994
      if (tree_has_value(expr))
2,415✔
1995
         build_wait(tree_value(expr), fn, ctx);
2,415✔
1996
      break;
1997

1998
   case T_ARRAY_REF:
538✔
1999
   case T_ARRAY_SLICE:
2000
   case T_RECORD_REF:
2001
      {
2002
         tree_t ref = name_to_ref(expr);
538✔
2003
         if (ref != NULL && class_of(ref) == C_SIGNAL
538✔
2004
             && longest_static_prefix(expr) == expr)
419✔
2005
            (*fn)(expr, ctx);
385✔
2006
         else {
2007
            build_wait(tree_value(expr), fn, ctx);
153✔
2008
            build_wait_for_target(expr, fn, ctx);
153✔
2009
         }
2010
      }
2011
      break;
2012

2013
   case T_FCALL:
1,721✔
2014
   case T_PCALL:
2015
   case T_PROT_FCALL:
2016
   case T_PROT_PCALL:
2017
      {
2018
         tree_t decl = tree_ref(expr);
1,721✔
2019
         const int nparams = tree_params(expr);
1,721✔
2020
         for (int i = 0; i < nparams; i++) {
4,773✔
2021
            tree_t p = tree_param(expr, i);
3,052✔
2022
            assert(tree_subkind(p) == P_POS);
3,052✔
2023
            const port_mode_t mode = tree_subkind(tree_port(decl, tree_pos(p)));
3,052✔
2024
            if (mode == PORT_IN || mode == PORT_INOUT)
3,052✔
2025
               build_wait(tree_value(p), fn, ctx);
3,045✔
2026
         }
2027
      }
2028
      break;
2029

2030
   case T_AGGREGATE:
173✔
2031
      {
2032
         const int nassocs = tree_assocs(expr);
173✔
2033
         for (int i = 0; i < nassocs; i++)
629✔
2034
            build_wait(tree_value(tree_assoc(expr, i)), fn, ctx);
456✔
2035
      }
2036
      break;
2037

2038
   case T_ATTR_REF:
78✔
2039
      {
2040
         const attr_kind_t predef = tree_subkind(expr);
78✔
2041
         if (predef == ATTR_EVENT || predef == ATTR_ACTIVE)
78✔
2042
            build_wait(tree_name(expr), fn, ctx);
27✔
2043

2044
         const int nparams = tree_params(expr);
78✔
2045
         for (int i = 0; i < nparams; i++)
79✔
2046
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
1✔
2047
      }
2048
      break;
2049

2050
   case T_LITERAL:
2051
   case T_STRING:
2052
      break;
2053

2054
   case T_IF:
144✔
2055
      {
2056
         const int nconds = tree_conds(expr);
144✔
2057
         for (int i = 0; i < nconds; i++)
426✔
2058
            build_wait(tree_cond(expr, i), fn, ctx);
282✔
2059
      }
2060
      break;
2061

2062
   case T_COND_STMT:
282✔
2063
      {
2064
         if (tree_has_value(expr))
282✔
2065
            build_wait(tree_value(expr), fn, ctx);
166✔
2066

2067
         const int nstmts = tree_stmts(expr);
282✔
2068
         for (int i = 0; i < nstmts; i++)
564✔
2069
            build_wait(tree_stmt(expr, i), fn, ctx);
282✔
2070
      }
2071
      break;
2072

2073
   case T_PROCESS:
18✔
2074
   case T_SEQUENCE:
2075
   case T_PROC_BODY:
2076
      {
2077
         const int ndecls = tree_decls(expr);
18✔
2078
         for (int i = 0; i < ndecls; i++) {
26✔
2079
            tree_t d = tree_decl(expr, i);
8✔
2080
            if (tree_kind(d) == T_PROC_BODY)
8✔
2081
               build_wait(d, fn, ctx);
1✔
2082
         }
2083

2084
         const int nstmts = tree_stmts(expr);
18✔
2085
         for (int i = 0; i < nstmts; i++)
40✔
2086
            build_wait(tree_stmt(expr, i), fn, ctx);
22✔
2087
      }
2088
      break;
2089

2090
   case T_SIGNAL_ASSIGN:
1,853✔
2091
      {
2092
         build_wait_for_target(tree_target(expr), fn, ctx);
1,853✔
2093

2094
         const int nwaves = tree_waveforms(expr);
1,853✔
2095
         for (int i = 0; i < nwaves; i++)
3,774✔
2096
            build_wait(tree_waveform(expr, i), fn, ctx);
1,921✔
2097
      }
2098
      break;
2099

2100
   case T_VAR_ASSIGN:
7✔
2101
      build_wait_for_target(tree_target(expr), fn, ctx);
7✔
2102
      build_wait(tree_value(expr), fn, ctx);
7✔
2103
      break;
7✔
2104

2105
   case T_CASE:
33✔
2106
   case T_MATCH_CASE:
2107
      {
2108
         build_wait(tree_value(expr), fn, ctx);
33✔
2109

2110
         const int nstmts = tree_stmts(expr);
33✔
2111
         for (int i = 0; i < nstmts; i++) {
237✔
2112
            tree_t alt = tree_stmt(expr, i);
204✔
2113

2114
            const int nstmts = tree_stmts(alt);
204✔
2115
            for (int j = 0; j < nstmts; j++)
408✔
2116
               build_wait(tree_stmt(alt, j), fn, ctx);
204✔
2117
         }
2118
      }
2119
      break;
2120

2121
   case T_FOR:
1✔
2122
      {
2123
         build_wait(tree_range(expr, 0), fn, ctx);
1✔
2124

2125
         const int nstmts = tree_stmts(expr);
1✔
2126
         for (int i = 0; i < nstmts; i++)
2✔
2127
            build_wait(tree_stmt(expr, i), fn, ctx);
1✔
2128
      }
2129
      break;
2130

2131
   case T_WHILE:
4✔
2132
      {
2133
         build_wait(tree_value(expr), fn, ctx);
4✔
2134

2135
         const int nstmts = tree_stmts(expr);
4✔
2136
         for (int i = 0; i < nstmts; i++)
20✔
2137
            build_wait(tree_stmt(expr, i), fn, ctx);
16✔
2138
      }
2139
      break;
2140

2141
   case T_NEXT:
9✔
2142
   case T_EXIT:
2143
      if (tree_has_value(expr))
9✔
2144
         build_wait(tree_value(expr), fn, ctx);
6✔
2145
      break;
2146

2147
   case T_RANGE:
61✔
2148
      if (tree_subkind(expr) == RANGE_EXPR)
61✔
2149
         build_wait(tree_value(expr), fn, ctx);
×
2150
      else {
2151
         build_wait(tree_left(expr), fn, ctx);
61✔
2152
         build_wait(tree_right(expr), fn, ctx);
61✔
2153
      }
2154
      break;
2155

2156
   default:
×
2157
      fatal_trace("Cannot handle tree kind %s in wait expression",
×
2158
                  tree_kind_str(tree_kind(expr)));
2159
   }
2160
}
9,308✔
2161

2162
void print_syntax(const char *fmt, ...)
1,332✔
2163
{
2164
   LOCAL_TEXT_BUF tb = tb_new();
1,332✔
2165
   bool highlighting = false;
1,332✔
2166
   static bool comment = false, last_was_newline = false;
1,332✔
2167
   for (const char *p = fmt; *p != '\0'; p++) {
7,579✔
2168
      if (comment) {
6,247✔
2169
         if (*p == '\n' || *p == '\r') {
2,954✔
2170
            comment = false;
90✔
2171
            last_was_newline = true;
90✔
2172
            tb_printf(tb, "$$\n");
90✔
2173
         }
2174
         else if (*p != '~' && *p != '#') {
2,864✔
2175
            tb_append(tb, *p);
2,704✔
2176
            last_was_newline = false;
2,704✔
2177
         }
2178
         if (p > fmt && *p == '/' && *(p - 1) == '*') {
2,954✔
2179
            tb_printf(tb, "$$");
1✔
2180
            comment = false;
1✔
2181
            last_was_newline = false;
1✔
2182
         }
2183
      }
2184
      else if (*p == '\r') {
3,293✔
2185
         if (!last_was_newline) {
18✔
2186
            tb_append(tb, '\n');
×
2187
            last_was_newline = true;
×
2188
         }
2189
      }
2190
      else if (*p == '#') {
3,275✔
2191
         tb_printf(tb, "$bold$$cyan$");
230✔
2192
         last_was_newline = false;
230✔
2193
         highlighting = true;
230✔
2194
      }
2195
      else if (*p == '~') {
3,045✔
2196
         tb_printf(tb, "$yellow$");
×
2197
         last_was_newline = false;
×
2198
         highlighting = true;
×
2199
      }
2200
      else if ((*p == '-' && *(p + 1) == '-')
3,045✔
2201
               || (*p == '/' && *(p + 1) == '/')
2,957✔
2202
               || (*p == '/' && *(p + 1) == '*')) {
2,955✔
2203
         tb_printf(tb, "$red$%c", *p);
91✔
2204
         last_was_newline = false;
91✔
2205
         comment = true;
91✔
2206
      }
2207
      else if (!isalnum_iso88591(*p) && *p != '_'
2,954✔
2208
               && *p != '%' && highlighting) {
1,467✔
2209
         tb_printf(tb, "$$%c", *p);
211✔
2210
         last_was_newline = false;
211✔
2211
         highlighting = false;
211✔
2212
      }
2213
      else {
2214
         tb_append(tb, *p);
2,743✔
2215
         last_was_newline = (*p == '\n');
2,743✔
2216
      }
2217
   }
2218

2219
   if (highlighting)
1,332✔
2220
      tb_cat(tb, "$$");
19✔
2221

2222
   va_list ap;
1,332✔
2223
   va_start(ap, fmt);
1,332✔
2224

2225
   if (syntax_buf != NULL) {
1,332✔
2226
      char *stripped LOCAL = strip_color(tb_get(tb), ap);
2,664✔
2227
      tb_cat(syntax_buf, stripped);
1,332✔
2228
   }
2229
   else
2230
      color_vprintf(tb_get(tb), ap);
×
2231

2232
   va_end(ap);
1,332✔
2233
}
1,332✔
2234

2235
void capture_syntax(text_buf_t *tb)
7✔
2236
{
2237
   assert(tb == NULL || syntax_buf == NULL);
7✔
2238
   syntax_buf = tb;
7✔
2239
}
7✔
2240

2241
void analyse_file(const char *file, jit_t *jit, unit_registry_t *ur)
2,853✔
2242
{
2243
   input_from_file(file);
2,853✔
2244

2245
   switch (source_kind()) {
2,853✔
2246
   case SOURCE_VHDL:
2,840✔
2247
      {
2248
         lib_t work = lib_work();
2,840✔
2249
         int base_errors = 0;
2,840✔
2250
         tree_t unit;
2,840✔
2251
         while (base_errors = error_count(), (unit = parse())) {
10,914✔
2252
            if (error_count() == base_errors) {
8,074✔
2253
               lib_put(work, unit);
8,073✔
2254
               unit_registry_purge(ur, tree_ident(unit));
8,073✔
2255

2256
               simplify_local(unit, jit, ur);
8,073✔
2257
               bounds_check(unit);
8,073✔
2258
            }
2259
            else
2260
               lib_put_error(work, unit);
1✔
2261
         }
2262
      }
2263
      break;
2264

2265
   case SOURCE_VERILOG:
13✔
2266
#ifdef ENABLE_VERILOG
2267
      {
2268
         lib_t work = lib_work();
13✔
2269
         vlog_node_t module;
13✔
2270
         while ((module = vlog_parse())) {
39✔
2271
            if (error_count() == 0) {
13✔
2272
               vlog_check(module);
13✔
2273

2274
               if (error_count() == 0)
13✔
2275
                  lib_put_vlog(work, module);
13✔
2276
            }
2277
         }
2278
      }
2279
#else
2280
      fatal("Verilog is not currently supported");
2281
#endif
2282
      break;
2283
   }
2284
}
2,850✔
2285

2286
static void tree_copy_cb(tree_t t, void *__ctx)
276,057✔
2287
{
2288
   copy_ctx_t *ctx = __ctx;
276,057✔
2289

2290
   if (is_subprogram(t))
276,057✔
2291
      list_add(&ctx->copied_subs, t);
11,518✔
2292
}
276,057✔
2293

2294
static void type_copy_cb(type_t type, void *__ctx)
16,284✔
2295
{
2296
   copy_ctx_t *ctx = __ctx;
16,284✔
2297

2298
   if (type_has_ident(type))
16,284✔
2299
      list_add(&ctx->copied_types, type);
10,314✔
2300
}
16,284✔
2301

2302
void copy_with_renaming(tree_t *roots, int nroots, tree_copy_pred_t tree_pred,
6,563✔
2303
                        type_copy_pred_t type_pred, void *context,
2304
                        ident_t dotted, ident_t *prefixes, int nprefix)
2305
{
2306
   copy_ctx_t copy_ctx = {};
6,563✔
2307

2308
   tree_copy(roots, nroots, tree_pred, type_pred, context,
6,563✔
2309
             tree_copy_cb, type_copy_cb, &copy_ctx);
2310

2311
   // Change the name of any copied types to reflect the new hiearchy
2312
   for (list_iter(type_t, type, copy_ctx.copied_types)) {
16,877✔
2313
      ident_t orig = type_ident(type);
10,314✔
2314
      for (int j = 0; j < nprefix; j++) {
31,111✔
2315
         if (ident_starts_with(orig, prefixes[j])) {
11,134✔
2316
            LOCAL_TEXT_BUF tb = tb_new();
651✔
2317
            tb_cat(tb, istr(dotted));
651✔
2318
            tb_cat(tb, istr(orig) + ident_len(prefixes[j]));
651✔
2319

2320
            type_set_ident(type, ident_new(tb_get(tb)));
651✔
2321
            break;
651✔
2322
         }
2323
      }
2324
   }
2325
   list_free(&copy_ctx.copied_types);
6,563✔
2326

2327
   // Change the mangled name of copied subprograms so that copies in
2328
   // different instances do not collide
2329
   for (list_iter(tree_t, decl, copy_ctx.copied_subs)) {
18,081✔
2330
      if (tree_kind(decl) == T_GENERIC_DECL)
11,518✔
2331
         continue;   // Does not yet have mangled name
372✔
2332

2333
      ident_t orig = tree_ident2(decl);
11,146✔
2334
      for (int j = 0; j < nprefix; j++) {
12,421✔
2335
         if (ident_starts_with(orig, prefixes[j])) {
11,220✔
2336
            ident_t prefix = ident_runtil(orig, '(');
9,945✔
2337

2338
            LOCAL_TEXT_BUF tb = tb_new();
9,945✔
2339
            tb_cat(tb, istr(dotted));
9,945✔
2340
            tb_cat(tb, istr(prefix) + ident_len(prefixes[j]));
9,945✔
2341

2342
            const tree_kind_t kind = tree_kind(decl);
9,945✔
2343
            const bool is_func = kind == T_FUNC_BODY || kind == T_FUNC_DECL;
9,945✔
2344
            const int nports = tree_ports(decl);
9,945✔
2345
            if (nports > 0 || is_func)
9,945✔
2346
               tb_append(tb, '(');
9,767✔
2347

2348
            for (int k = 0; k < nports; k++) {
29,318✔
2349
               tree_t p = tree_port(decl, k);
19,373✔
2350
               if (tree_class(p) == C_SIGNAL)
19,373✔
2351
                  tb_printf(tb, "s");
187✔
2352
               mangle_one_type(tb, tree_type(p));
19,373✔
2353
            }
2354

2355
            if (nports > 0 || is_func)
9,945✔
2356
               tb_printf(tb, ")");
9,767✔
2357

2358
            if (is_func)
9,945✔
2359
               mangle_one_type(tb, type_result(tree_type(decl)));
8,554✔
2360

2361
            ident_t mangled = ident_new(tb_get(tb));
9,945✔
2362
            tree_set_ident2(decl, mangled);
9,945✔
2363

2364
            break;
9,945✔
2365
         }
2366
      }
2367
   }
2368
   list_free(&copy_ctx.copied_subs);
6,563✔
2369
}
6,563✔
2370

2371
bool all_character_literals(type_t type)
192✔
2372
{
2373
   assert(type_is_enum(type));
192✔
2374

2375
   type_t base = type_base_recur(type);
192✔
2376
   const int nlits = type_enum_literals(base);
192✔
2377
   for (int i = 0; i < nlits; i++) {
1,017✔
2378
      if (ident_char(tree_ident(type_enum_literal(base, i)), 0) != '\'')
886✔
2379
         return false;
2380
   }
2381

2382
   return true;
2383
}
2384

2385
bool is_operator_symbol(ident_t ident)
7,356✔
2386
{
2387
   const int len = ident_len(ident);
7,356✔
2388
   if (len < 3)
7,356✔
2389
      return false;
2390
   else if (ident_char(ident, 0) != '"')
7,356✔
2391
      return false;
2392
   else if (ident_char(ident, len - 1) != '"')
7,314✔
2393
      return false;
2394
   else if (ident_char(ident, 1) == '?' && standard() < STD_08)
7,314✔
2395
      return false;
2396

2397
   static const char *const strings[] = {
7,314✔
2398
      "\"??\"", "\"and\"", "\"or\"", "\"nand\"", "\"nor\"",
2399
      "\"xor\"", "\"xnor\"", "\"=\"", "\"/=\"", "\"<\"", "\"<=\"",
2400
      "\">\"", "\">=\"", "\"?=\"", "\"?/=\"", "\"?<\"", "\"?<=\"",
2401
      "\"?>\"", "\"?>=\"", "\"sll\"", "\"srl\"", "\"sla\"", "\"sra\"",
2402
      "\"rol\"", "\"ror\"", "\"+\"", "\"-\"", "\"&\"", "\"*\"",
2403
      "\"/\"", "\"mod\"", "\"rem\"", "\"**\"", "\"abs\"", "\"not\""
2404
   };
2405

2406
   static ident_t operators[ARRAY_LEN(strings)];
7,314✔
2407
   INIT_ONCE({
12,529✔
2408
         for (int i = 0; i < ARRAY_LEN(strings); i++)
2409
            operators[i] = ident_new(strings[i]);
2410
      });
2411

2412
   for (int i = 0; i < ARRAY_LEN(operators); i++) {
125,528✔
2413
      if (ident == operators[i])
125,527✔
2414
         return true;
2415
   }
2416

2417
   return false;
2418
}
2419

2420
bool same_tree(tree_t a, tree_t b)
2,689✔
2421
{
2422
   const tree_kind_t akind = tree_kind(a);
2,689✔
2423
   if (akind != tree_kind(b))
2,689✔
2424
      return false;
2425

2426
   switch (akind) {
2,635✔
2427
   case T_REF:
1,389✔
2428
      return tree_ref(a) == tree_ref(b);
1,389✔
2429
   case T_ARRAY_REF:
228✔
2430
      {
2431
         if (!same_tree(tree_value(a), tree_value(b)))
228✔
2432
            return false;
2433

2434
         const int nparams = tree_params(a);
216✔
2435
         assert(nparams == tree_params(b));
216✔
2436

2437
         for (int i = 0; i < nparams; i++) {
383✔
2438
            tree_t pa = tree_value(tree_param(a, i));
219✔
2439
            tree_t pb = tree_value(tree_param(b, i));
219✔
2440
            if (!same_tree(pa, pb))
219✔
2441
               return false;
2442
         }
2443

2444
         return true;
2445
      }
2446
   case T_ARRAY_SLICE:
32✔
2447
      {
2448
         if (!same_tree(tree_value(a), tree_value(b)))
32✔
2449
            return false;
2450

2451
         tree_t ra = tree_range(a, 0);
32✔
2452
         tree_t rb = tree_range(b, 0);
32✔
2453

2454
         const range_kind_t rakind = tree_subkind(ra);
32✔
2455
         if (rakind != tree_subkind(rb) || rakind == RANGE_EXPR)
32✔
2456
            return false;
2457

2458
         return same_tree(tree_left(ra), tree_left(rb))
32✔
2459
            && same_tree(tree_right(ra), tree_right(rb));
32✔
2460
      }
2461

2462
   case T_RECORD_REF:
729✔
2463
      return tree_ident(a) == tree_ident(b)
729✔
2464
         && same_tree(tree_value(a), tree_value(b));
729✔
2465

2466
   case T_LITERAL:
257✔
2467
      {
2468
         const literal_kind_t alkind = tree_subkind(a);
257✔
2469
         if (alkind != tree_subkind(b) || alkind != L_INT)
257✔
2470
            return false;
2471
         else
2472
            return tree_ival(a) == tree_ival(b);
257✔
2473
      }
2474
   default:
2475
      return false;
2476
   }
2477
}
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