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

nickg / nvc / 6709062420

31 Oct 2023 04:04PM UTC coverage: 91.262% (+0.01%) from 91.249%
6709062420

push

github

nickg
Add specialised exit handler for 'last_event

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

49769 of 54534 relevant lines covered (91.26%)

598003.15 hits per line

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

92.9
/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)
130,751✔
49
{
50
   int64_t value;
130,751✔
51
   if (folded_int(t, &value))
130,751✔
52
      return value;
130,751✔
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)
42,999✔
59
{
60
   assert(tree_kind(r) == T_RANGE);
42,999✔
61

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

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

69
bool folded_int(tree_t t, int64_t *l)
2,419,560✔
70
{
71
   switch (tree_kind(t)) {
2,452,640✔
72
   case T_LITERAL:
1,869,000✔
73
      switch (tree_subkind(t)) {
1,869,000✔
74
      case L_PHYSICAL:
13,084✔
75
         if (tree_has_ref(t))
13,084✔
76
            return false;
77
         // Fall-through
78
      case L_INT:
79
         *l = tree_ival(t);
1,851,610✔
80
         return true;
1,851,610✔
81
      default:
82
         return false;
83
      }
84
   case T_QUALIFIED:
289✔
85
      return folded_int(tree_value(t), l);
289✔
86
   case T_REF:
398,480✔
87
      {
88
         tree_t decl = tree_ref(t);
398,480✔
89
         switch (tree_kind(decl)) {
398,480✔
90
         case T_CONST_DECL:
40,319✔
91
            if (tree_has_value(decl))
40,319✔
92
               return folded_int(tree_value(decl), l);
32,623✔
93
            else
94
               return false;
95
         case T_ENUM_LIT:
294,339✔
96
            *l = tree_pos(decl);
294,339✔
97
            return true;
294,339✔
98
         case T_ALIAS:
163✔
99
            return folded_int(tree_value(decl), l);
163✔
100
         default:
101
            return false;
102
         }
103
      }
104
   default:
105
      return false;
106
   }
107
}
108

109
bool folded_real(tree_t t, double *l)
132,328✔
110
{
111
   switch (tree_kind(t)) {
132,349✔
112
   case T_LITERAL:
125,230✔
113
      if (tree_subkind(t) == L_REAL) {
125,230✔
114
         *l = tree_dval(t);
125,228✔
115
         return true;
125,228✔
116
      }
117
      else
118
         return false;
119
   case T_QUALIFIED:
21✔
120
      return folded_real(tree_value(t), l);
21✔
121
   default:
122
      return false;
123
   }
124
}
125

126
bool folded_length(tree_t r, int64_t *l)
40,228✔
127
{
128
   int64_t low, high;
40,228✔
129
   if (folded_bounds(r, &low, &high)) {
40,228✔
130
      *l = MAX(high - low + 1, 0);
37,908✔
131
      return true;
37,908✔
132
   }
133
   else
134
      return false;
135
}
136

137
bool folded_bounds(tree_t r, int64_t *low, int64_t *high)
1,049,720✔
138
{
139
   assert(tree_kind(r) == T_RANGE);
1,049,720✔
140

141
   const range_kind_t rkind = tree_subkind(r);
1,049,720✔
142

143
   if (rkind != RANGE_TO && rkind != RANGE_DOWNTO)
1,049,720✔
144
      return false;
145

146
   int64_t left, right;
1,038,830✔
147
   if (!folded_int(tree_left(r), &left))
1,038,830✔
148
      return false;
149
   else if (!folded_int(tree_right(r), &right))
953,466✔
150
      return false;
151

152
   switch (rkind) {
936,006✔
153
   case RANGE_TO:
843,956✔
154
      *low  = left;
843,956✔
155
      *high = right;
843,956✔
156
      return true;
843,956✔
157
   case RANGE_DOWNTO:
92,050✔
158
      *low  = right;
92,050✔
159
      *high = left;
92,050✔
160
      return true;
92,050✔
161
   default:
162
      return false;
163
   }
164
}
165

166
bool folded_bounds_real(tree_t r, double *low, double *high)
61,194✔
167
{
168
   assert(tree_kind(r) == T_RANGE);
61,194✔
169

170
   const range_kind_t rkind = tree_subkind(r);
61,194✔
171

172
   if (rkind != RANGE_TO && rkind != RANGE_DOWNTO)
61,194✔
173
      return false;
174

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

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

205
   return false;
206
}
207

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

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

219
   return b;
7,193✔
220
}
221

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

230
   return f;
32,864✔
231
}
232

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

241
   return f;
×
242
}
243

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

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

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

256
      type_t elem = type_elem(base);
17✔
257

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

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

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

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

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

278
      assert(n <= max);
17✔
279
      array->count = n;
17✔
280

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

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

293
      value->enums = array;
15✔
294
      return true;
15✔
295
   }
296

297
   while (isspace_iso88591(*str))
79✔
298
      ++str;
10✔
299

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

306
         if (is_negative) ++str;
44✔
307

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

317
         value->integer = is_negative ? -sum : sum;
44✔
318

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

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

336
         ident_t id = ident_new(copy);
14✔
337

338
         value->integer = -1;
14✔
339

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

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

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

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

367
         while (isspace_iso88591(*str)) ++str;
10✔
368

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

374
         if (p == copy)
5✔
375
            return false;
376

377
         ident_t id = ident_new(copy);
4✔
378

379
         value->integer = -1;
4✔
380

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

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

395
   default:
396
      return false;
397
   }
398

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

404
   return true;
405
}
406

407
tree_t make_ref(tree_t to)
15,278✔
408
{
409
   tree_t t = tree_new(T_REF);
15,278✔
410
   tree_set_ident(t, tree_ident(to));
15,278✔
411
   tree_set_ref(t, to);
15,278✔
412
   tree_set_type(t, tree_type(to));
15,278✔
413
   return t;
15,278✔
414
}
415

416
vhdl_standard_t standard(void)
2,395,090✔
417
{
418
   return current_std;
2,395,090✔
419
}
420

421
void set_standard(vhdl_standard_t s)
3,981✔
422
{
423
   current_std = s;
3,981✔
424
   have_set_std = true;
3,981✔
425
}
3,981✔
426

427
void set_default_standard(vhdl_standard_t s)
335✔
428
{
429
   if (!have_set_std)
335✔
430
      set_standard(s);
57✔
431
}
335✔
432

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

439
   if ((unsigned)s < ARRAY_LEN(text))
3,633✔
440
      return text[s];
3,633✔
441
   else
442
      return "????";
443
}
444

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

451
   return offset;
×
452
}
453

454
tree_t find_record_field(tree_t rref)
8,466✔
455
{
456
   ident_t fname = tree_ident(rref);
8,466✔
457
   type_t value_type = tree_type(tree_value(rref));
8,466✔
458

459
   if (!type_is_record(value_type))
8,466✔
460
      return NULL;
461

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

469
   return NULL;
470
}
471

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

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

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

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

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

498
         return NULL;
499
      }
500

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

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

517
class_t class_of(tree_t t)
1,498,770✔
518
{
519
   switch (tree_kind(t)) {
1,584,750✔
520
   case T_VAR_DECL:
521
      return C_VARIABLE;
522
   case T_SIGNAL_DECL:
50,505✔
523
   case T_IMPLICIT_SIGNAL:
524
      return C_SIGNAL;
50,505✔
525
   case T_CONST_DECL:
44,619✔
526
      return C_CONSTANT;
44,619✔
527
   case T_PORT_DECL:
177,080✔
528
   case T_GENERIC_DECL:
529
   case T_PARAM_DECL:
530
   case T_EXTERNAL_NAME:
531
      return tree_class(t);
177,080✔
532
   case T_ENUM_LIT:
918,461✔
533
   case T_LITERAL:
534
   case T_STRING:
535
      return C_LITERAL;
918,461✔
536
   case T_FIELD_DECL:
1,644✔
537
   case T_ATTR_DECL:
538
      return C_DEFAULT;
1,644✔
539
   case T_VIEW_DECL:
131✔
540
      return C_VIEW;
131✔
541
   case T_UNIT_DECL:
6,139✔
542
      return C_UNITS;
6,139✔
543
   case T_ARCH:
40✔
544
      return C_ARCHITECTURE;
40✔
545
   case T_FUNC_DECL:
27,453✔
546
   case T_FUNC_BODY:
547
   case T_FUNC_INST:
548
   case T_FCALL:
549
      return C_FUNCTION;
27,453✔
550
   case T_PROC_DECL:
12,112✔
551
   case T_PROC_BODY:
552
   case T_PROC_INST:
553
   case T_PCALL:
554
      return C_PROCEDURE;
12,112✔
555
   case T_ENTITY:
132✔
556
      return C_ENTITY;
132✔
557
   case T_SUBTYPE_DECL:
27,133✔
558
      return C_SUBTYPE;
27,133✔
559
   case T_TYPE_DECL:
130,667✔
560
   case T_PROT_DECL:
561
      return C_TYPE;
130,667✔
562
   case T_FILE_DECL:
1,856✔
563
      return C_FILE;
1,856✔
564
   case T_PROCESS:
75✔
565
   case T_BLOCK:
566
   case T_FOR:
567
   case T_INSTANCE:
568
   case T_CONCURRENT:
569
   case T_ELAB:
570
      return C_LABEL;
75✔
571
   case T_COMPONENT:
1✔
572
      return C_COMPONENT;
1✔
573
   case T_REF:
77,583✔
574
   case T_PROT_REF:
575
      return tree_has_ref(t) ? class_of(tree_ref(t)) : C_DEFAULT;
77,583✔
576
   case T_ARRAY_REF:
8,415✔
577
   case T_ARRAY_SLICE:
578
   case T_RECORD_REF:
579
   case T_ALL:
580
   case T_ALIAS:
581
   case T_QUALIFIED:
582
      return class_of(tree_value(t));
8,415✔
583
   case T_PACKAGE:
1,222✔
584
   case T_PACK_BODY:
585
   case T_PACK_INST:
586
      return C_PACKAGE;
1,222✔
587
   case T_CONFIGURATION:
1✔
588
      return C_CONFIGURATION;
1✔
589
   case T_LIBRARY:
×
590
      return C_LIBRARY;
×
591
   case T_ATTR_REF:
174✔
592
      switch (tree_subkind(t)) {
174✔
593
      case ATTR_DELAYED:
594
      case ATTR_STABLE:
595
      case ATTR_QUIET:
596
      case ATTR_TRANSACTION:
597
         return C_SIGNAL;
598
      default:
171✔
599
         return C_DEFAULT;
171✔
600
      }
601
   case T_CONTEXT:
×
602
      return C_CONTEXT;
×
603
   default:
×
604
      fatal_trace("missing class_of for %s", tree_kind_str(tree_kind(t)));
×
605
   }
606
}
607

608
bool class_has_type(class_t c)
814,840✔
609
{
610
   switch (c) {
814,840✔
611
   case C_LABEL:
612
   case C_ENTITY:
613
   case C_ARCHITECTURE:
614
   case C_COMPONENT:
615
   case C_CONFIGURATION:
616
   case C_PACKAGE:
617
   case C_LIBRARY:
618
      return false;
619
   default:
813,622✔
620
      return true;
813,622✔
621
   }
622
}
623

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

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

647
bool is_subprogram(tree_t t)
1,724,350✔
648
{
649
   switch (tree_kind(t)) {
1,724,350✔
650
   case T_FUNC_DECL:
651
   case T_FUNC_BODY:
652
   case T_FUNC_INST:
653
   case T_PROC_DECL:
654
   case T_PROC_BODY:
655
   case T_PROC_INST:
656
      return true;
657
   case T_GENERIC_DECL:
1,544✔
658
      {
659
         const class_t class = tree_class(t);
1,544✔
660
         return class == C_FUNCTION || class == C_PROCEDURE;
1,544✔
661
      }
662
   default:
1,245,770✔
663
      return false;
1,245,770✔
664
   }
665
}
666

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

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

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

709
bool is_package(tree_t t)
39,525✔
710
{
711
   switch (tree_kind(t)) {
39,525✔
712
   case T_PACKAGE:
713
   case T_PACK_BODY:
714
   case T_PACK_INST:
715
      return true;
716
   default:
3,309✔
717
      return false;
3,309✔
718
   }
719
}
720

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

737
bool is_guarded_signal(tree_t decl)
4,678✔
738
{
739
   return !!(tree_flags(decl) & (TREE_F_BUS | TREE_F_REGISTER));
4,678✔
740
}
741

742
bool is_type_decl(tree_t t)
2,229,680✔
743
{
744
   switch (tree_kind(t)) {
2,229,680✔
745
   case T_TYPE_DECL:
746
   case T_SUBTYPE_DECL:
747
   case T_PROT_DECL:
748
      return true;
749
   default:
2,149,410✔
750
      return false;
2,149,410✔
751
   }
752
}
753

754
tree_t aliased_type_decl(tree_t decl)
104,814✔
755
{
756
   switch (tree_kind(decl)) {
105,057✔
757
   case T_ALIAS:
243✔
758
      {
759
         tree_t value = tree_value(decl);
243✔
760
         if (tree_kind(value) == T_REF && tree_has_ref(value))
243✔
761
            return aliased_type_decl(tree_ref(value));
243✔
762
         else
763
            return NULL;
×
764
      }
765
   case T_TYPE_DECL:
766
   case T_SUBTYPE_DECL:
767
   case T_PROT_DECL:
768
      return decl;
769
   case T_GENERIC_DECL:
376✔
770
      if (tree_class(decl) == C_TYPE)
376✔
771
         return decl;
772
      else
773
         return NULL;
44✔
774
   default:
19,588✔
775
      return NULL;
19,588✔
776
   }
777
}
778

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

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

796
   tree_add_param(call, p);
142,706✔
797
   return p;
142,706✔
798
}
799

800
type_t array_aggregate_type(type_t array, int from_dim)
262✔
801
{
802
   if (type_is_none(array))
262✔
803
      return type_new(T_NONE);
2✔
804

805
   if (type_is_unconstrained(array)) {
260✔
806
      const int nindex = type_indexes(array);
37✔
807
      assert(from_dim < nindex);
37✔
808

809
      type_t type = type_new(T_ARRAY);
37✔
810
      type_set_ident(type, type_ident(array));
37✔
811
      type_set_elem(type, type_elem(array));
37✔
812

813
      for (int i = from_dim; i < nindex; i++)
74✔
814
         type_add_index(type, type_index(array, i));
37✔
815

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

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

826
      tree_t constraint = tree_new(T_CONSTRAINT);
223✔
827
      tree_set_subkind(constraint, C_INDEX);
223✔
828

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

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

839
      return sub;
840
   }
841
}
842

843
unsigned bits_for_range(int64_t low, int64_t high)
1,505,460✔
844
{
845
   assert(low <= high);
1,505,460✔
846

847
   if (low < 0) {
1,505,460✔
848
      // Signed integers
849
      if (low >= INT8_MIN && high <= INT8_MAX)
406,803✔
850
         return 8;
851
      else if (low >= INT16_MIN && high <= INT16_MAX)
400,217✔
852
         return 16;
853
      else if (low >= INT32_MIN && high <= INT32_MAX)
400,010✔
854
         return 32;
855
      else
856
         return 64;
103,336✔
857
   }
858
   else {
859
      // Unsigned integers
860
      if (high <= 1)
1,098,660✔
861
         return 1;
862
      else if (high <= UINT8_MAX)
492,155✔
863
         return 8;
864
      else if (high <= UINT16_MAX)
66,995✔
865
         return 16;
866
      else if (high <= UINT32_MAX)
64,603✔
867
         return 32;
868
      else
869
         return 64;
13,238✔
870
   }
871
}
872

873
unsigned dimension_of(type_t type)
1,115,400✔
874
{
875
   switch (type_kind(type)) {
2,028,210✔
876
   case T_SUBTYPE:
912,815✔
877
      return dimension_of(type_base(type));
912,815✔
878
   case T_GENERIC:
15✔
879
      assert(type_subkind(type) == GTYPE_ARRAY);
15✔
880
      // Fall-through
881
   case T_ARRAY:
882
      return type_indexes(type);
1,112,130✔
883
   case T_NONE:
884
   case T_ACCESS:
885
   case T_RECORD:
886
      return 0;
887
   case T_INTEGER:
3,219✔
888
   case T_REAL:
889
   case T_PHYSICAL:
890
   case T_ENUM:
891
      return type_dims(type);
3,219✔
892
   default:
×
893
      fatal_trace("invalid type kind %s in dimension_of",
×
894
                  type_kind_str(type_kind(type)));
895
   }
896
}
897

898
tree_t range_of(type_t type, unsigned dim)
1,249,900✔
899
{
900
   switch (type_kind(type)) {
1,279,950✔
901
   case T_SUBTYPE:
1,044,130✔
902
      if (type_constraints(type) > 0) {
1,044,130✔
903
         tree_t c0 = type_constraint(type, 0);
1,014,190✔
904
         switch (tree_subkind(c0)) {
1,014,190✔
905
         case C_OPEN:
110✔
906
            return range_of(type_base(type), dim);
110✔
907
         case C_INDEX:
1,014,080✔
908
         case C_RANGE:
909
            return tree_range(type_constraint(type, 0), dim);
1,014,080✔
910
         default:
×
911
            fatal_trace("invalid constraint in range_of");
×
912
         }
913
      }
914
      else
915
         return range_of(type_base(type), dim);
29,943✔
916
   case T_INTEGER:
235,815✔
917
   case T_REAL:
918
   case T_PHYSICAL:
919
   case T_ENUM:
920
      return type_dim(type, dim);
235,815✔
921
   default:
×
922
      fatal_trace("invalid type kind %s in range_of",
×
923
                  type_kind_str(type_kind(type)));
924
   }
925
}
926

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

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

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

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

967
type_t index_type_of(type_t type, unsigned dim)
195,509✔
968
{
969
   if (dim >= dimension_of(type))
195,509✔
970
      return NULL;
971

972
   type_t base = type_base_recur(type);
195,494✔
973
   type_kind_t base_kind = type_kind(base);
195,494✔
974
   if (base_kind == T_ARRAY)
195,494✔
975
      return type_index(base, dim);
192,594✔
976
   else if (base_kind == T_ENUM || base_kind == T_NONE)
2,900✔
977
      return type;
978
   else if (base_kind == T_GENERIC && type_subkind(base) == GTYPE_ARRAY)
2,750✔
979
      return type_index(base, dim);
9✔
980
   else if (base_kind == T_RECORD || base_kind == T_GENERIC)
2,741✔
981
      return NULL;
982
   else
983
      return tree_type(range_of(base, dim));
2,741✔
984
}
985

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

994
ident_t well_known(well_known_t id)
232,014✔
995
{
996
   assert(id < NUM_WELL_KNOWN);
232,014✔
997
   return id_cache[id];
232,014✔
998
}
999

1000
well_known_t is_well_known(ident_t ident)
217,929✔
1001
{
1002
   well_known_t pos = 0;
217,929✔
1003
   for (; pos < NUM_WELL_KNOWN; pos++) {
6,871,460✔
1004
      if (id_cache[pos] == ident)
6,746,630✔
1005
         break;
1006
   }
1007

1008
   return pos;
217,929✔
1009
}
1010

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

1055
   id_cache[W_NVC_PSL_SUPPORT] = ident_new("NVC.PSL_SUPPORT");
4,128✔
1056

1057
   id_cache[W_IEEE_LOGIC_VECTOR] =
8,256✔
1058
      ident_new("IEEE.STD_LOGIC_1164.STD_LOGIC_VECTOR");
4,128✔
1059
   id_cache[W_IEEE_ULOGIC_VECTOR] =
8,256✔
1060
      ident_new("IEEE.STD_LOGIC_1164.STD_ULOGIC_VECTOR");
4,128✔
1061

1062
   id_cache[W_NUMERIC_STD_UNSIGNED] = ident_new("IEEE.NUMERIC_STD_UNSIGNED");
4,128✔
1063
   id_cache[W_NUMERIC_BIT_UNSIGNED] = ident_new("IEEE.NUMERIC_BIT_UNSIGNED");
4,128✔
1064

1065
   id_cache[W_VITAL] = ident_new("VITAL");
4,128✔
1066
}
4,128✔
1067

1068
bool is_uninstantiated_package(tree_t pack)
26,878✔
1069
{
1070
   return tree_kind(pack) == T_PACKAGE
26,878✔
1071
      && tree_generics(pack) > 0
26,550✔
1072
      && tree_genmaps(pack) == 0;
27,569✔
1073
}
1074

1075
bool is_uninstantiated_subprogram(tree_t decl)
91,460✔
1076
{
1077
   switch (tree_kind(decl)) {
91,460✔
1078
   case T_FUNC_DECL:
91,271✔
1079
   case T_FUNC_BODY:
1080
   case T_PROC_DECL:
1081
   case T_PROC_BODY:
1082
      return tree_generics(decl) > 0;
91,271✔
1083
   default:
1084
      return false;
1085
   }
1086
}
1087

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

1105
bool package_needs_body(tree_t pack)
1,476✔
1106
{
1107
   assert(tree_kind(pack) == T_PACKAGE);
1,476✔
1108

1109
   const int ndecls = tree_decls(pack);
1,476✔
1110
   for (int i = 0; i < ndecls; i++) {
109,073✔
1111
      tree_t d = tree_decl(pack, i);
108,274✔
1112

1113
      switch (tree_kind(d)) {
108,274✔
1114
      case T_FUNC_DECL:
95,943✔
1115
      case T_PROC_DECL:
1116
         if (tree_flags(d) & TREE_F_PREDEFINED)
95,943✔
1117
            continue;
94,969✔
1118
         else if (is_foreign(tree_subkind(d)))
974✔
1119
            continue;
434✔
1120
         return true;
1121

1122
      case T_CONST_DECL:
691✔
1123
         if (!tree_has_value(d))
691✔
1124
            return true;
1125
         continue;
632✔
1126

1127
      case T_PROT_DECL:
1128
         return true;
1129

1130
      default:
11,562✔
1131
         continue;
11,562✔
1132
      }
1133
   }
1134

1135
   return false;
1136
}
1137

1138
tree_t search_decls(tree_t container, ident_t name, int nth)
32,380✔
1139
{
1140
   tree_kind_t kind = tree_kind(container);
32,380✔
1141
   if (kind == T_LIBRARY) {
32,380✔
1142
      if (nth == 0) {
×
1143
         lib_t lib = lib_require(tree_ident(container));
×
1144
         return lib_get(lib, name);
×
1145
      }
1146
      else
1147
         return NULL;
1148
   }
1149
   else if (kind == T_ENTITY || kind == T_BLOCK) {
32,380✔
1150
      const int nports = tree_ports(container);
168✔
1151
      for (int i = 0; i < nports; i++) {
193✔
1152
         tree_t p = tree_port(container, i);
25✔
1153
         if (tree_ident(p) == name && nth-- == 0)
25✔
1154
            return p;
×
1155
      }
1156
   }
1157
   else if (!is_container(container))
32,212✔
1158
      return NULL;
1159

1160
   // TODO: how to improve this?
1161
   const int ndecls = tree_decls(container);
32,380✔
1162
   tree_t best = NULL;
32,380✔
1163

1164
   for (int i = 0; i < ndecls; i++) {
1,816,840✔
1165
      tree_t d = tree_decl(container, i);
1,816,800✔
1166
      if (!tree_has_ident(d))
1,816,800✔
1167
         continue;
×
1168
      else if (tree_ident(d) == name) {
1,816,800✔
1169
         if (tree_kind(d) == T_TYPE_DECL
20,957✔
1170
             && type_kind(tree_type(d)) == T_INCOMPLETE)
19,576✔
1171
            best = d;
1172
         else if (nth-- == 0)
20,925✔
1173
            return d;
20,650✔
1174
      }
1175
      else if (tree_kind(d) == T_TYPE_DECL) {
1,795,850✔
1176
         type_t type = tree_type(d);
140,772✔
1177
         switch (type_kind(type)) {
140,772✔
1178
         case T_ENUM:
105,973✔
1179
            {
1180
               const int nlits = type_enum_literals(type);
105,973✔
1181
               for (int j = 0; j < nlits; j++) {
7,121,930✔
1182
                  tree_t lit = type_enum_literal(type, j);
7,027,660✔
1183
                  if (tree_ident(lit) == name && nth-- == 0)
7,027,660✔
1184
                     return lit;
11,699✔
1185
               }
1186
            }
1187
            break;
1188
         default:
1189
            break;
1190
         }
1191
      }
1,655,080✔
1192
   }
1193

1194
   return best;
1195
}
1196

1197
static tree_t cached_unit(tree_t hint, tree_t *cache, well_known_t lib_name,
19,397✔
1198
                          well_known_t unit_name)
1199
{
1200
   const vhdl_standard_t curr = standard();
19,397✔
1201

1202
   if (cache[curr] == NULL) {
19,397✔
1203
      if (hint != NULL)
3,493✔
1204
         cache[curr] = hint;
972✔
1205
      else {
1206
         lib_t std = lib_require(well_known(lib_name));
2,521✔
1207
         cache[curr] = lib_get(std, well_known(unit_name));
2,521✔
1208
         assert(cache[curr] != NULL);
2,521✔
1209
      }
1210
   }
1211

1212
   assert(hint == NULL || hint == cache[curr]);
19,397✔
1213
   return cache[curr];
19,397✔
1214
}
1215

1216
static tree_t cached_std(tree_t hint)
19,313✔
1217
{
1218
   static tree_t standard_cache[STD_19 + 1] = {};
19,313✔
1219
   return cached_unit(hint, standard_cache, W_STD, W_STD_STANDARD);
19,313✔
1220
}
1221

1222
type_t std_type(tree_t std, std_type_t which)
2,126,220✔
1223
{
1224
   static type_t cache[STD_FILE_OPEN_STATE + 1] = {};
2,126,220✔
1225
   assert(which < ARRAY_LEN(cache));
2,126,220✔
1226

1227
   if (cache[which] == NULL) {
2,126,220✔
1228
      const char *names[] = {
19,313✔
1229
         "universal_integer",
1230
         "universal_real",
1231
         "INTEGER",
1232
         "REAL",
1233
         "BOOLEAN",
1234
         "STRING",
1235
         "TIME",
1236
         "BIT",
1237
         "FILE_OPEN_KIND",
1238
         "FILE_OPEN_STATUS",
1239
         "NATURAL",
1240
         "BIT_VECTOR",
1241
         "SEVERITY_LEVEL",
1242
         "FILE_ORIGIN_KIND",
1243
         "FILE_OPEN_STATE",
1244
      };
1245

1246
      tree_t d = search_decls(cached_std(std), ident_new(names[which]), 0);
19,313✔
1247
      if (d == NULL)
19,313✔
1248
         fatal_trace("cannot find standard type %s", names[which]);
×
1249

1250
      // Do not cache standard types while bootstrapping as the GC will
1251
      // move the objects after parsing
1252
      static int can_cache = -1;
19,313✔
1253
      if (can_cache == -1) can_cache = !opt_get_int(OPT_BOOTSTRAP);
19,313✔
1254

1255
      if (can_cache)
19,313✔
1256
         return (cache[which] = tree_type(d));
18,565✔
1257
      else
1258
         return tree_type(d);
748✔
1259
   }
1260
   else
1261
      return cache[which];
1262
}
1263

1264
type_t ieee_type(ieee_type_t which)
377✔
1265
{
1266
   static type_t cache[IEEE_STD_LOGIC + 1] = {};
377✔
1267
   assert(which < ARRAY_LEN(cache));
377✔
1268

1269
   if (cache[which] == NULL) {
377✔
1270
      const char *names[] = {
52✔
1271
         "STD_ULOGIC",
1272
         "STD_LOGIC",
1273
      };
1274

1275
      static tree_t ieee_cache[STD_19 + 1] = {};
52✔
1276
      tree_t unit = cached_unit(NULL, ieee_cache, W_IEEE, W_IEEE_1164);
52✔
1277

1278
      tree_t d = search_decls(unit, ident_new(names[which]), 0);
52✔
1279
      if (d == NULL)
52✔
1280
         fatal_trace("cannot find IEEE type %s", names[which]);
×
1281

1282
      // STD.STANDARD cannot depend on IEEE
1283
      assert(!opt_get_int(OPT_BOOTSTRAP));
52✔
1284

1285
      return (cache[which] = tree_type(d));
52✔
1286
   }
1287
   else
1288
      return cache[which];
1289
}
1290

1291
type_t reflection_type(reflect_type_t which)
183✔
1292
{
1293
   static type_t cache[REFLECT_SUBTYPE_MIRROR + 1] = {};
183✔
1294
   assert(which < ARRAY_LEN(cache));
183✔
1295

1296
   if (cache[which] == NULL) {
183✔
1297
      const char *names[] = {
32✔
1298
         "VALUE_MIRROR",
1299
         "SUBTYPE_MIRROR",
1300
      };
1301

1302
      static tree_t reflect_cache[STD_19 + 1] = {};
32✔
1303
      tree_t unit = cached_unit(NULL, reflect_cache, W_STD, W_STD_REFLECTION);
32✔
1304

1305
      tree_t d = search_decls(unit, ident_new(names[which]), 0);
32✔
1306
      if (d == NULL)
32✔
1307
         fatal_trace("cannot find REFLECTION type %s", names[which]);
×
1308

1309
      // STD.STANDARD cannot depend on REFLECTION
1310
      assert(!opt_get_int(OPT_BOOTSTRAP));
32✔
1311

1312
      return (cache[which] = tree_type(d));
32✔
1313
   }
1314
   else
1315
      return cache[which];
1316
}
1317

1318
bool is_builtin(subprogram_kind_t kind)
12,965,300✔
1319
{
1320
   return kind != S_USER && kind != S_FOREIGN && kind != S_INTERNAL;
12,965,300✔
1321
}
1322

1323
bool is_foreign(subprogram_kind_t kind)
58,445✔
1324
{
1325
   return kind == S_FOREIGN || kind == S_INTERNAL;
58,445✔
1326
}
1327

1328
bool is_open_coded_builtin(subprogram_kind_t kind)
361,075✔
1329
{
1330
   switch (kind) {
361,075✔
1331
   case S_USER:
1332
   case S_FOREIGN:
1333
   case S_INTERNAL:
1334
   case S_ARRAY_EQ:
1335
   case S_ARRAY_NEQ:
1336
   case S_ARRAY_LT:
1337
   case S_ARRAY_LE:
1338
   case S_ARRAY_GT:
1339
   case S_ARRAY_GE:
1340
   case S_RECORD_EQ:
1341
   case S_RECORD_NEQ:
1342
   case S_TO_STRING:
1343
   case S_SLL:
1344
   case S_SRL:
1345
   case S_SLA:
1346
   case S_SRA:
1347
   case S_ROL:
1348
   case S_ROR:
1349
   case S_ARRAY_NOT:
1350
   case S_ARRAY_AND:
1351
   case S_ARRAY_OR:
1352
   case S_ARRAY_XOR:
1353
   case S_ARRAY_XNOR:
1354
   case S_ARRAY_NAND:
1355
   case S_ARRAY_NOR:
1356
   case S_MIXED_AND:
1357
   case S_MIXED_OR:
1358
   case S_MIXED_XOR:
1359
   case S_MIXED_XNOR:
1360
   case S_MIXED_NAND:
1361
   case S_MIXED_NOR:
1362
   case S_REDUCE_OR:
1363
   case S_REDUCE_AND:
1364
   case S_REDUCE_NAND:
1365
   case S_REDUCE_NOR:
1366
   case S_REDUCE_XOR:
1367
   case S_REDUCE_XNOR:
1368
   case S_MATCH_EQ:
1369
   case S_MATCH_NEQ:
1370
   case S_MATCH_LT:
1371
   case S_MATCH_LE:
1372
   case S_MATCH_GT:
1373
   case S_MATCH_GE:
1374
   case S_MINIMUM:
1375
   case S_MAXIMUM:
1376
      return false;
1377
   default:
220,406✔
1378
      return true;
220,406✔
1379
   }
1380
}
1381

1382
tree_t std_func(ident_t mangled)
×
1383
{
1384
   tree_t std = cached_std(NULL);
×
1385

1386
   const int ndecls = tree_decls(std);
×
1387
   for (int i = 0; i < ndecls; i++) {
×
1388
      tree_t d = tree_decl(std, i);
×
1389
      if (is_subprogram(d) && tree_has_ident2(d) && tree_ident2(d) == mangled)
×
1390
         return d;
×
1391
   }
1392

1393
   return NULL;
1394
}
1395

1396
tree_t name_to_ref(tree_t name)
79,000✔
1397
{
1398
   tree_kind_t kind;
79,000✔
1399
   while ((kind = tree_kind(name)) != T_REF) {
89,297✔
1400
      switch (kind) {
11,642✔
1401
      case T_ARRAY_REF:
10,297✔
1402
      case T_ARRAY_SLICE:
1403
      case T_RECORD_REF:
1404
      case T_ALL:
1405
         name = tree_value(name);
10,297✔
1406
         break;
10,297✔
1407
      default:
1408
         return NULL;
1409
      }
1410
   }
1411

1412
   return name;
1413
}
1414

1415
const char *port_mode_str(port_mode_t mode)
22✔
1416
{
1417
   const char *mode_str[] = {
22✔
1418
      "INVALID", "IN", "OUT", "INOUT", "BUFFER", "LINKAGE", "VIEW", "VIEW"
1419
   };
1420
   assert(mode < ARRAY_LEN(mode_str));
22✔
1421
   return mode_str[mode];
22✔
1422
}
1423

1424
void mangle_one_type(text_buf_t *buf, type_t type)
156,888✔
1425
{
1426
   ident_t ident = type_ident(type);
156,888✔
1427

1428
   char code = 0;
156,888✔
1429
   switch (is_well_known(ident)) {
156,888✔
1430
   case W_STD_INTEGER:        code = 'I'; break;
1431
   case W_STD_STRING:         code = 'S'; break;
3,040✔
1432
   case W_STD_REAL:           code = 'R'; break;
3,278✔
1433
   case W_STD_BOOL:           code = 'B'; break;
21,181✔
1434
   case W_STD_CHAR:           code = 'C'; break;
651✔
1435
   case W_STD_TIME:           code = 'T'; break;
891✔
1436
   case W_STD_NATURAL:        code = 'N'; break;
3,945✔
1437
   case W_STD_POSITIVE:       code = 'P'; break;
324✔
1438
   case W_STD_BIT:            code = 'J'; break;
2,353✔
1439
   case W_STD_BIT_VECTOR:     code = 'Q'; break;
2,278✔
1440
   case W_IEEE_LOGIC:         code = 'L'; break;
244✔
1441
   case W_IEEE_ULOGIC:        code = 'U'; break;
4,734✔
1442
   case W_IEEE_LOGIC_VECTOR:  code = 'V'; break;
1,539✔
1443
   case W_IEEE_ULOGIC_VECTOR: code = 'Y'; break;
1,397✔
1444
   default: break;
1445
   }
1446

1447
   if (code)
45,855✔
1448
      tb_append(buf, code);
57,657✔
1449
   else {
1450
      tb_printf(buf, "%zu", ident_len(ident));
99,231✔
1451
      tb_istr(buf, ident);
99,231✔
1452
   }
1453
}
156,888✔
1454

1455
tree_t primary_unit_of(tree_t unit)
16,970✔
1456
{
1457
   switch (tree_kind(unit)) {
16,970✔
1458
   case T_ENTITY:
1459
   case T_COMPONENT:
1460
   case T_PACKAGE:
1461
   case T_BLOCK:
1462
   case T_ELAB:
1463
      return unit;
1464
   case T_ARCH:
7,013✔
1465
   case T_CONFIGURATION:
1466
   case T_PACK_BODY:
1467
      return tree_primary(unit);
7,013✔
1468
   default:
×
1469
      fatal_trace("invalid kind %s in primary_unit_of",
×
1470
                  tree_kind_str(tree_kind(unit)));
1471
   }
1472
}
1473

1474
unsigned get_case_choice_char(tree_t value, int depth)
7,573✔
1475
{
1476
   switch (tree_kind(value)) {
7,573✔
1477
   case T_STRING:
6,823✔
1478
      if (depth < tree_chars(value)) {
6,823✔
1479
         tree_t ch = tree_char(value, depth);
6,822✔
1480
         return tree_pos(tree_ref(ch));
6,822✔
1481
      }
1482
      else
1483
         return ~0;   // Out of bounds
1484

1485
   case T_AGGREGATE:
14✔
1486
      {
1487
         const int nassocs = tree_assocs(value);
14✔
1488
         type_t type = tree_type(value);
14✔
1489

1490
         for (int i = 0; i < nassocs; i++) {
24✔
1491
            tree_t a = tree_assoc(value, i);
23✔
1492
            switch (tree_subkind(a)) {
23✔
1493
            case A_NAMED:
×
1494
               if (rebase_index(type, 0, assume_int(tree_name(a))) == depth)
×
1495
                  return assume_int(tree_value(a));
×
1496
               break;
1497

1498
            case A_POS:
23✔
1499
               if (tree_pos(a) == (unsigned)depth)
23✔
1500
                  return assume_int(tree_value(a));
13✔
1501
               break;
1502

1503
            case A_OTHERS:
×
1504
               return assume_int(tree_value(a));
×
1505
            }
1506
         }
10✔
1507

1508
         // This will produce an error during bounds checking
1509
         return ~0;
1510
      }
1511

1512
   case T_REF:
392✔
1513
      {
1514
         tree_t decl = tree_ref(value);
392✔
1515
         assert(tree_kind(decl) == T_CONST_DECL || tree_kind(decl) == T_ALIAS);
392✔
1516
         assert(tree_has_value(decl));
392✔
1517
         return get_case_choice_char(tree_value(decl), depth);
392✔
1518
      }
1519

1520
   case T_ARRAY_SLICE:
240✔
1521
      {
1522
         tree_t base = tree_value(value);
240✔
1523
         tree_t r = tree_range(value, 0);
240✔
1524
         const int64_t rleft = assume_int(tree_left(r));
240✔
1525
         const int64_t offset = rebase_index(tree_type(base), 0, rleft);
240✔
1526
         return get_case_choice_char(base, depth + offset);
240✔
1527
      }
1528

1529
   case T_FCALL:
104✔
1530
      if (tree_subkind(tree_ref(value)) == S_CONCAT) {
104✔
1531
         const int nparams = tree_params(value);
104✔
1532
         for (int i = 0; i < nparams; i++) {
156✔
1533
            tree_t left = tree_value(tree_param(value, i));
156✔
1534

1535
            type_t left_type = tree_type(left);
156✔
1536
            if (type_is_unconstrained(left_type))
156✔
1537
               fatal_at(tree_loc(left), "sorry, this expression is not "
×
1538
                        "currently supported in a case choice");
1539

1540
            tree_t lr = range_of(tree_type(left), 0);
156✔
1541
            int64_t left_len;
156✔
1542
            if (!folded_length(lr, &left_len))
156✔
1543
               fatal_at(tree_loc(left), "cannot determine length of left hand "
×
1544
                        "side of concatenation");
1545

1546
            if (depth < left_len || i + 1 == nparams)
156✔
1547
               return get_case_choice_char(left, depth);
104✔
1548

1549
            depth -= left_len;
52✔
1550
         }
1551
      }
1552
      // Fall-through
1553

1554
   default:
1555
      fatal_at(tree_loc(value), "unsupported tree type %s in case choice",
×
1556
               tree_kind_str(tree_kind(value)));
1557
   }
1558
}
1559

1560
int64_t encode_case_choice(tree_t value, int length, int bits)
981✔
1561
{
1562
   uint64_t enc = 0;
981✔
1563
   for (int i = 0; i < length; i++) {
7,812✔
1564
      if (bits > 0) {
6,831✔
1565
         enc <<= bits;
1,631✔
1566
         enc |= get_case_choice_char(value, i);
1,631✔
1567
      }
1568
      else {
1569
         enc *= 0x27d4eb2d;
5,200✔
1570
         enc += get_case_choice_char(value, i);
5,200✔
1571
      }
1572
   }
1573

1574
   return enc;
981✔
1575
}
1576

1577
void to_string(text_buf_t *tb, type_t type, int64_t value)
553✔
1578
{
1579
   if (type_is_integer(type))
553✔
1580
      tb_printf(tb, "%"PRIi64, value);
419✔
1581
   else if (type_is_enum(type)) {
134✔
1582
      type_t base = type_base_recur(type);
62✔
1583
      if (value < 0 || value >= type_enum_literals(base))
62✔
1584
         tb_printf(tb, "%"PRIi64, value);
3✔
1585
      else
1586
         tb_cat(tb, istr(tree_ident(type_enum_literal(base, value))));
59✔
1587
   }
1588
   else if (type_is_physical(type)) {
72✔
1589
      type_t base = type_base_recur(type);
24✔
1590
      const unsigned nunits = type_units(base);
24✔
1591
      tree_t max_unit = NULL;
24✔
1592
      int64_t max_unit_value = 0;
24✔
1593

1594
      // Find the largest unit that evenly divides the given value
1595
      for (unsigned u = 0; u < nunits; u++) {
216✔
1596
         tree_t unit = type_unit(base, u);
192✔
1597
         const int64_t unit_value = assume_int(tree_value(unit));
192✔
1598
         if ((unit_value > max_unit_value) && (value % unit_value == 0)) {
192✔
1599
            max_unit = unit;
90✔
1600
            max_unit_value = unit_value;
90✔
1601
         }
1602
      }
1603
      assert(max_unit);
24✔
1604

1605
      tb_printf(tb, "%"PRIi64" %s", value / max_unit_value,
24✔
1606
                istr(tree_ident(max_unit)));
1607
   }
1608
   else if (type_is_real(type)) {
48✔
1609
      union { int64_t i; double r; } u = { .i = value };
42✔
1610
      tb_printf(tb, "%.17g", u.r);
42✔
1611
   }
1612
   else if (type_is_access(type)) {
6✔
1613
      if (value == 0)
6✔
1614
         tb_cat(tb, "NULL");
3✔
1615
      else
1616
         tb_printf(tb, "%p", (void *)value);
3✔
1617
   }
1618
}
553✔
1619

1620
static bool is_static(tree_t expr)
4,873✔
1621
{
1622
   switch (tree_kind(expr)) {
4,974✔
1623
   case T_REF:
432✔
1624
      {
1625
         tree_t decl = tree_ref(expr);
432✔
1626
         switch (tree_kind(decl)) {
432✔
1627
         case T_CONST_DECL:
119✔
1628
            return !(tree_flags(decl) & TREE_F_SEQ_BLOCK);
119✔
1629
         case T_UNIT_DECL:
1630
         case T_ENUM_LIT:
1631
         case T_GENERIC_DECL:
1632
            return true;
1633
         case T_ALIAS:
×
1634
            return is_static(tree_value(decl));
×
1635
         default:
113✔
1636
            return false;
113✔
1637
         }
1638
      }
1639

1640
   case T_LITERAL:
1641
   case T_STRING:
1642
      return true;
1643

1644
   case T_FCALL:
315✔
1645
      return !!(tree_flags(expr) & (TREE_F_LOCALLY_STATIC
315✔
1646
                                    | TREE_F_GLOBALLY_STATIC));
1647

1648
   case T_RECORD_REF:
101✔
1649
      return is_static(tree_value(expr));
101✔
1650

1651
   default:
×
1652
      return false;
×
1653
   }
1654
}
1655

1656
tree_t longest_static_prefix(tree_t expr)
17,313✔
1657
{
1658
   switch (tree_kind(expr)) {
17,313✔
1659
   case T_ARRAY_REF:
3,382✔
1660
      {
1661
         tree_t value = tree_value(expr);
3,382✔
1662
         tree_t prefix = longest_static_prefix(value);
3,382✔
1663

1664
         if (prefix != value)
3,382✔
1665
            return prefix;
1666

1667
         const int nparams = tree_params(expr);
3,369✔
1668
         for (int i = 0; i < nparams; i++) {
7,018✔
1669
            if (!is_static(tree_value(tree_param(expr, i))))
3,795✔
1670
               return prefix;
1671
         }
1672

1673
         return expr;
1674
      }
1675

1676
   case T_ARRAY_SLICE:
555✔
1677
      {
1678
         tree_t value = tree_value(expr);
555✔
1679
         tree_t prefix = longest_static_prefix(value);
555✔
1680

1681
         if (prefix != value)
555✔
1682
            return prefix;
1683

1684
         const int nranges = tree_ranges(expr);
548✔
1685
         for (int i = 0; i < nranges; i++) {
1,080✔
1686
            tree_t r = tree_range(expr, i);
548✔
1687
            if (tree_subkind(r) == RANGE_EXPR)
548✔
1688
               return prefix;
1689
            else if (!is_static(tree_left(r)) || !is_static(tree_right(r)))
545✔
1690
               return prefix;
13✔
1691
         }
1692

1693
         return expr;
1694
      }
1695

1696
   case T_RECORD_REF:
938✔
1697
      {
1698
         tree_t value = tree_value(expr);
938✔
1699
         tree_t prefix = longest_static_prefix(value);
938✔
1700

1701
         if (prefix != value)
938✔
1702
            return prefix;
×
1703

1704
         return expr;
1705
      }
1706

1707
   default:
1708
      return expr;
1709
   }
1710
}
1711

1712
tree_t body_of(tree_t pack)
690✔
1713
{
1714
   const tree_kind_t kind = tree_kind(pack);
690✔
1715
   if (kind == T_PACK_INST)
690✔
1716
      return NULL;
1717

1718
   assert(tree_kind(pack) == T_PACKAGE);
690✔
1719

1720
   ident_t body_i = well_known(W_BODY);
690✔
1721
   ident_t body_name = ident_prefix(tree_ident(pack), body_i, '-');
690✔
1722
   return lib_get_qualified(body_name);
690✔
1723
}
1724

1725
tree_t find_generic_map(tree_t unit, int pos, tree_t g)
1,183✔
1726
{
1727
   const int ngenmaps = tree_genmaps(unit);
1,183✔
1728

1729
   if (pos < ngenmaps) {
1,183✔
1730
      tree_t m = tree_genmap(unit, pos);
1,180✔
1731
      if (tree_subkind(m) == P_POS && tree_pos(m) == pos)
1,180✔
1732
         return tree_value(m);
650✔
1733
   }
1734

1735
   for (int j = 0; j < ngenmaps; j++) {
1,402✔
1736
      tree_t m = tree_genmap(unit, j);
1,399✔
1737
      switch (tree_subkind(m)) {
1,399✔
1738
      case P_NAMED:
1,000✔
1739
         {
1740
            tree_t name = tree_name(m);
1,000✔
1741
            assert(tree_kind(name) == T_REF);
1,000✔
1742

1743
            if (tree_ref(name) == g)
1,000✔
1744
               return tree_value(m);
322✔
1745
         }
1746
         break;
1747

1748
      case P_POS:
399✔
1749
         if (tree_pos(m) == pos)
399✔
1750
            return tree_value(m);
208✔
1751
         break;
1752

1753
      default:
1754
         break;
1755
      }
1756
   }
1757

1758
   return NULL;
1759
}
1760

1761
bool relaxed_rules(void)
827,269✔
1762
{
1763
   return opt_get_int(OPT_RELAXED);
827,269✔
1764
}
1765

1766
bool is_type_attribute(attr_kind_t kind)
61,391✔
1767
{
1768
   switch (kind) {
61,391✔
1769
   case ATTR_SUBTYPE:
1770
   case ATTR_BASE:
1771
   case ATTR_ELEMENT:
1772
   case ATTR_DESIGNATED_SUBTYPE:
1773
   case ATTR_INDEX:
1774
      return true;
1775
   default:
61,064✔
1776
      return false;
61,064✔
1777
   }
1778
}
1779

1780
bool attribute_has_param(attr_kind_t attr)
20,441✔
1781
{
1782
   switch (attr) {
20,441✔
1783
   case ATTR_IMAGE:
1784
   case ATTR_SUCC:
1785
   case ATTR_PRED:
1786
   case ATTR_DELAYED:
1787
   case ATTR_LEFTOF:
1788
   case ATTR_RIGHTOF:
1789
   case ATTR_VALUE:
1790
   case ATTR_POS:
1791
   case ATTR_LOW:
1792
   case ATTR_HIGH:
1793
   case ATTR_LEFT:
1794
   case ATTR_RIGHT:
1795
   case ATTR_LENGTH:
1796
   case ATTR_RANGE:
1797
   case ATTR_REVERSE_RANGE:
1798
   case ATTR_VAL:
1799
   case ATTR_QUIET:
1800
   case ATTR_STABLE:
1801
   case ATTR_INDEX:
1802
   case ATTR_ASCENDING:
1803
      return true;
1804
   default:
1,814✔
1805
      return false;
1,814✔
1806
   }
1807
}
1808

1809
type_t get_type_or_null(tree_t t)
1,782,810✔
1810
{
1811
   switch (tree_kind(t)) {
1,782,810✔
1812
   case T_LIBRARY:
1813
   case T_ATTR_SPEC:
1814
   case T_PACKAGE:
1815
   case T_PACK_INST:
1816
   case T_PACK_BODY:
1817
   case T_ENTITY:
1818
   case T_ARCH:
1819
   case T_PROCESS:
1820
   case T_COMPONENT:
1821
   case T_INSTANCE:
1822
   case T_CONCURRENT:
1823
   case T_BLOCK:
1824
   case T_WHILE:
1825
   case T_FOR:
1826
   case T_GROUP_TEMPLATE:
1827
   case T_CONFIGURATION:
1828
   case T_GROUP:
1829
   case T_FOR_GENERATE:
1830
   case T_IF_GENERATE:
1831
   case T_USE:
1832
   case T_CONTEXT:
1833
   case T_PSL:
1834
      return NULL;
1835
   default:
1,713,540✔
1836
      if (tree_has_type(t))
1,713,540✔
1837
         return tree_type(t);
1,712,540✔
1838
      else
1839
         return NULL;
1840
   }
1841
}
1842

1843
type_t subtype_for_string(tree_t str, type_t base)
24,061✔
1844
{
1845
   if (!type_is_unconstrained(base))
24,061✔
1846
      return base;
1847

1848
   // Construct a new constrained array subtype: the direction and
1849
   // bounds are the same as those for a positional array aggregate
1850
   type_t sub = type_new(T_SUBTYPE);
21,322✔
1851
   type_set_base(sub, base);
21,322✔
1852

1853
   type_t index_type = index_type_of(base, 0);
21,322✔
1854
   const bool is_enum = type_is_enum(index_type);
21,322✔
1855

1856
   // The direction is determined by the index type
1857
   range_kind_t dir = direction_of(index_type, 0);
21,322✔
1858

1859
   // The left bound is the left of the index type and the right bound
1860
   // is determined by the number of elements
1861

1862
   tree_t left = NULL, right = NULL;
21,322✔
1863

1864
   if (is_enum)
21,322✔
1865
      left = make_ref(type_enum_literal(type_base_recur(index_type), 0));
1✔
1866
   else
1867
      left = tree_left(range_of(index_type, 0));
21,321✔
1868

1869
   const int nchars = tree_chars(str);
21,322✔
1870
   int64_t iright;
21,322✔
1871
   if (dir == RANGE_DOWNTO)
21,322✔
1872
      iright = assume_int(left) - nchars + 1;
×
1873
   else
1874
      iright = assume_int(left) + nchars - 1;
21,322✔
1875

1876
   if (is_enum)
21,322✔
1877
      right = get_enum_lit(str, index_type, iright);
1✔
1878
   else
1879
      right = get_int_lit(str, index_type, iright);
21,321✔
1880

1881
   tree_t r = tree_new(T_RANGE);
21,322✔
1882
   tree_set_subkind(r, dir);
21,322✔
1883
   tree_set_left(r, left);
21,322✔
1884
   tree_set_right(r, right);
21,322✔
1885
   tree_set_loc(r, tree_loc(str));
21,322✔
1886
   tree_set_type(r, index_type);
21,322✔
1887

1888
   tree_t c = tree_new(T_CONSTRAINT);
21,322✔
1889
   tree_set_subkind(c, C_INDEX);
21,322✔
1890
   tree_add_range(c, r);
21,322✔
1891
   tree_set_loc(c, tree_loc(str));
21,322✔
1892

1893
   type_add_constraint(sub, c);
21,322✔
1894

1895
   return sub;
21,322✔
1896
}
1897

1898
tree_t change_ref(tree_t name, tree_t new)
1,678✔
1899
{
1900
   switch (tree_kind(name)) {
1,678✔
1901
   case T_REF:
1,138✔
1902
      return make_ref(new);
1,138✔
1903

1904
   case T_ARRAY_REF:
89✔
1905
      {
1906
         tree_t t = tree_new(T_ARRAY_REF);
89✔
1907
         tree_set_loc(t, tree_loc(name));
89✔
1908
         tree_set_value(t, change_ref(tree_value(name), new));
89✔
1909
         tree_set_type(t, tree_type(name));
89✔
1910

1911
         const int nparams = tree_params(name);
89✔
1912
         for (int i = 0; i < nparams; i++)
178✔
1913
            tree_add_param(t, tree_param(name, i));
89✔
1914

1915
         return t;
1916
      }
1917

1918
   case T_ARRAY_SLICE:
43✔
1919
      {
1920
         tree_t t = tree_new(T_ARRAY_SLICE);
43✔
1921
         tree_set_loc(t, tree_loc(name));
43✔
1922
         tree_set_value(t, change_ref(tree_value(name), new));
43✔
1923
         tree_set_type(t, tree_type(name));
43✔
1924
         tree_add_range(t, tree_range(name, 0));
43✔
1925

1926
         return t;
43✔
1927
      }
1928

1929
   case T_RECORD_REF:
351✔
1930
      {
1931
         tree_t t = tree_new(T_RECORD_REF);
351✔
1932
         tree_set_loc(t, tree_loc(name));
351✔
1933
         tree_set_value(t, change_ref(tree_value(name), new));
351✔
1934
         tree_set_type(t, tree_type(name));
351✔
1935
         tree_set_ident(t, tree_ident(name));
351✔
1936
         tree_set_ref(t, tree_ref(name));
351✔
1937

1938
         return t;
351✔
1939
      }
1940

1941
   case T_CONV_FUNC:
54✔
1942
      {
1943
         tree_t t = tree_new(T_CONV_FUNC);
54✔
1944
         tree_set_loc(t, tree_loc(name));
54✔
1945
         tree_set_value(t, change_ref(tree_value(name), new));
54✔
1946
         tree_set_ident(t, tree_ident(name));
54✔
1947
         tree_set_type(t, tree_type(name));
54✔
1948
         tree_set_ref(t, tree_ref(name));
54✔
1949

1950
         return t;
54✔
1951
      }
1952

1953
   case T_TYPE_CONV:
3✔
1954
      {
1955
         tree_t t = tree_new(T_TYPE_CONV);
3✔
1956
         tree_set_loc(t, tree_loc(name));
3✔
1957
         tree_set_type(t, tree_type(name));
3✔
1958
         tree_set_value(t, change_ref(tree_value(name), new));
3✔
1959

1960
         return t;
3✔
1961
      }
1962

1963
   default:
×
1964
      fatal_trace("cannot handle tree kind %s in elab_change_ref",
×
1965
                  tree_kind_str(tree_kind(name)));
1966
   }
1967
}
1968

1969
static void build_wait_for_target(tree_t expr, build_wait_fn_t fn, void *ctx)
2,122✔
1970
{
1971
   switch (tree_kind(expr)) {
2,122✔
1972
   case T_ARRAY_SLICE:
60✔
1973
      build_wait(tree_range(expr, 0), fn, ctx);
60✔
1974
      break;
60✔
1975

1976
   case T_ARRAY_REF:
325✔
1977
      {
1978
         const int nparams = tree_params(expr);
325✔
1979
         for (int i = 0; i < nparams; i++)
650✔
1980
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
325✔
1981
      }
1982
      break;
1983

1984
   default:
1985
      break;
1986
   }
1987
}
2,122✔
1988

1989
void build_wait(tree_t expr, build_wait_fn_t fn, void *ctx)
9,691✔
1990
{
1991
   // LRM 08 section 10.2 has rules for building a wait statement from a
1992
   // sensitivity list. LRM 08 section 11.3 extends these rules to
1993
   // all-sensitised processes.
1994

1995
   switch (tree_kind(expr)) {
12,250✔
1996
   case T_REF:
3,096✔
1997
      if (class_of(tree_ref(expr)) == C_SIGNAL)
3,096✔
1998
         (*fn)(expr, ctx);
1,723✔
1999
      break;
2000

2001
   case T_EXTERNAL_NAME:
3✔
2002
      if (tree_class(expr) == C_SIGNAL)
3✔
2003
         (*fn)(expr, ctx);
3✔
2004
      break;
2005

2006
   case T_WAVEFORM:
2,488✔
2007
   case T_QUALIFIED:
2008
   case T_TYPE_CONV:
2009
   case T_ASSERT:
2010
      if (tree_has_value(expr))
2,488✔
2011
         build_wait(tree_value(expr), fn, ctx);
2,485✔
2012
      break;
2013

2014
   case T_ARRAY_REF:
586✔
2015
   case T_ARRAY_SLICE:
2016
   case T_RECORD_REF:
2017
      {
2018
         tree_t ref = name_to_ref(expr);
586✔
2019
         if (ref != NULL && class_of(ref) == C_SIGNAL
586✔
2020
             && longest_static_prefix(expr) == expr)
422✔
2021
            (*fn)(expr, ctx);
388✔
2022
         else {
2023
            build_wait(tree_value(expr), fn, ctx);
198✔
2024
            build_wait_for_target(expr, fn, ctx);
198✔
2025
         }
2026
      }
2027
      break;
2028

2029
   case T_FCALL:
1,748✔
2030
   case T_PCALL:
2031
   case T_PROT_FCALL:
2032
   case T_PROT_PCALL:
2033
      {
2034
         tree_t decl = tree_ref(expr);
1,748✔
2035
         const int nparams = tree_params(expr);
1,748✔
2036
         for (int i = 0; i < nparams; i++) {
4,851✔
2037
            tree_t p = tree_param(expr, i);
3,103✔
2038
            assert(tree_subkind(p) == P_POS);
3,103✔
2039
            const port_mode_t mode = tree_subkind(tree_port(decl, tree_pos(p)));
3,103✔
2040
            if (mode == PORT_IN || mode == PORT_INOUT)
3,103✔
2041
               build_wait(tree_value(p), fn, ctx);
3,096✔
2042
         }
2043
      }
2044
      break;
2045

2046
   case T_AGGREGATE:
173✔
2047
      {
2048
         const int nassocs = tree_assocs(expr);
173✔
2049
         for (int i = 0; i < nassocs; i++)
629✔
2050
            build_wait(tree_value(tree_assoc(expr, i)), fn, ctx);
456✔
2051
      }
2052
      break;
2053

2054
   case T_ATTR_REF:
111✔
2055
      {
2056
         const attr_kind_t predef = tree_subkind(expr);
111✔
2057
         if (predef == ATTR_EVENT || predef == ATTR_ACTIVE)
111✔
2058
            build_wait(tree_name(expr), fn, ctx);
60✔
2059

2060
         const int nparams = tree_params(expr);
111✔
2061
         for (int i = 0; i < nparams; i++)
112✔
2062
            build_wait(tree_value(tree_param(expr, i)), fn, ctx);
1✔
2063
      }
2064
      break;
2065

2066
   case T_LITERAL:
2067
   case T_STRING:
2068
      break;
2069

2070
   case T_IF:
156✔
2071
      {
2072
         const int nconds = tree_conds(expr);
156✔
2073
         for (int i = 0; i < nconds; i++)
450✔
2074
            build_wait(tree_cond(expr, i), fn, ctx);
294✔
2075
      }
2076
      break;
2077

2078
   case T_COND_STMT:
294✔
2079
      {
2080
         if (tree_has_value(expr))
294✔
2081
            build_wait(tree_value(expr), fn, ctx);
178✔
2082

2083
         const int nstmts = tree_stmts(expr);
294✔
2084
         for (int i = 0; i < nstmts; i++)
594✔
2085
            build_wait(tree_stmt(expr, i), fn, ctx);
300✔
2086
      }
2087
      break;
2088

2089
   case T_PROCESS:
21✔
2090
   case T_SEQUENCE:
2091
   case T_PROC_BODY:
2092
      {
2093
         const int ndecls = tree_decls(expr);
21✔
2094
         for (int i = 0; i < ndecls; i++) {
29✔
2095
            tree_t d = tree_decl(expr, i);
8✔
2096
            if (tree_kind(d) == T_PROC_BODY)
8✔
2097
               build_wait(d, fn, ctx);
1✔
2098
         }
2099

2100
         const int nstmts = tree_stmts(expr);
21✔
2101
         for (int i = 0; i < nstmts; i++)
46✔
2102
            build_wait(tree_stmt(expr, i), fn, ctx);
25✔
2103
      }
2104
      break;
2105

2106
   case T_SIGNAL_ASSIGN:
1,917✔
2107
      {
2108
         build_wait_for_target(tree_target(expr), fn, ctx);
1,917✔
2109

2110
         const int nwaves = tree_waveforms(expr);
1,917✔
2111
         for (int i = 0; i < nwaves; i++)
3,905✔
2112
            build_wait(tree_waveform(expr, i), fn, ctx);
1,988✔
2113
      }
2114
      break;
2115

2116
   case T_VAR_ASSIGN:
7✔
2117
      build_wait_for_target(tree_target(expr), fn, ctx);
7✔
2118
      build_wait(tree_value(expr), fn, ctx);
7✔
2119
      break;
7✔
2120

2121
   case T_CASE:
33✔
2122
   case T_MATCH_CASE:
2123
      {
2124
         build_wait(tree_value(expr), fn, ctx);
33✔
2125

2126
         const int nstmts = tree_stmts(expr);
33✔
2127
         for (int i = 0; i < nstmts; i++) {
237✔
2128
            tree_t alt = tree_stmt(expr, i);
204✔
2129

2130
            const int nstmts = tree_stmts(alt);
204✔
2131
            for (int j = 0; j < nstmts; j++)
408✔
2132
               build_wait(tree_stmt(alt, j), fn, ctx);
204✔
2133
         }
2134
      }
2135
      break;
2136

2137
   case T_FOR:
1✔
2138
      {
2139
         build_wait(tree_range(expr, 0), fn, ctx);
1✔
2140

2141
         const int nstmts = tree_stmts(expr);
1✔
2142
         for (int i = 0; i < nstmts; i++)
2✔
2143
            build_wait(tree_stmt(expr, i), fn, ctx);
1✔
2144
      }
2145
      break;
2146

2147
   case T_WHILE:
4✔
2148
      {
2149
         build_wait(tree_value(expr), fn, ctx);
4✔
2150

2151
         const int nstmts = tree_stmts(expr);
4✔
2152
         for (int i = 0; i < nstmts; i++)
20✔
2153
            build_wait(tree_stmt(expr, i), fn, ctx);
16✔
2154
      }
2155
      break;
2156

2157
   case T_NEXT:
9✔
2158
   case T_EXIT:
2159
      if (tree_has_value(expr))
9✔
2160
         build_wait(tree_value(expr), fn, ctx);
6✔
2161
      break;
2162

2163
   case T_RANGE:
61✔
2164
      if (tree_subkind(expr) == RANGE_EXPR)
61✔
2165
         build_wait(tree_value(expr), fn, ctx);
×
2166
      else {
2167
         build_wait(tree_left(expr), fn, ctx);
61✔
2168
         build_wait(tree_right(expr), fn, ctx);
61✔
2169
      }
2170
      break;
2171

2172
   default:
×
2173
      fatal_trace("Cannot handle tree kind %s in wait expression",
×
2174
                  tree_kind_str(tree_kind(expr)));
2175
   }
2176
}
9,691✔
2177

2178
void print_syntax(const char *fmt, ...)
1,381✔
2179
{
2180
   LOCAL_TEXT_BUF tb = tb_new();
1,381✔
2181
   bool highlighting = false;
1,381✔
2182
   static bool comment = false, last_was_newline = false;
1,381✔
2183
   for (const char *p = fmt; *p != '\0'; p++) {
7,793✔
2184
      if (comment) {
6,412✔
2185
         if (*p == '\n' || *p == '\r') {
2,954✔
2186
            comment = false;
90✔
2187
            last_was_newline = true;
90✔
2188
            tb_printf(tb, "$$\n");
90✔
2189
         }
2190
         else if (*p != '~' && *p != '#') {
2,864✔
2191
            tb_append(tb, *p);
2,704✔
2192
            last_was_newline = false;
2,704✔
2193
         }
2194
         if (p > fmt && *p == '/' && *(p - 1) == '*') {
2,954✔
2195
            tb_printf(tb, "$$");
1✔
2196
            comment = false;
1✔
2197
            last_was_newline = false;
1✔
2198
         }
2199
      }
2200
      else if (*p == '\r') {
3,458✔
2201
         if (!last_was_newline) {
18✔
2202
            tb_append(tb, '\n');
×
2203
            last_was_newline = true;
×
2204
         }
2205
      }
2206
      else if (*p == '#') {
3,440✔
2207
         tb_printf(tb, "$bold$$cyan$");
239✔
2208
         last_was_newline = false;
239✔
2209
         highlighting = true;
239✔
2210
      }
2211
      else if (*p == '~') {
3,201✔
2212
         tb_printf(tb, "$yellow$");
×
2213
         last_was_newline = false;
×
2214
         highlighting = true;
×
2215
      }
2216
      else if ((*p == '-' && *(p + 1) == '-')
3,201✔
2217
               || (*p == '/' && *(p + 1) == '/')
3,113✔
2218
               || (*p == '/' && *(p + 1) == '*')) {
3,111✔
2219
         tb_printf(tb, "$red$%c", *p);
91✔
2220
         last_was_newline = false;
91✔
2221
         comment = true;
91✔
2222
      }
2223
      else if (!isalnum_iso88591(*p) && *p != '_'
3,110✔
2224
               && *p != '%' && highlighting) {
1,551✔
2225
         tb_printf(tb, "$$%c", *p);
219✔
2226
         last_was_newline = false;
219✔
2227
         highlighting = false;
219✔
2228
      }
2229
      else {
2230
         tb_append(tb, *p);
2,891✔
2231
         last_was_newline = (*p == '\n');
2,891✔
2232
      }
2233
   }
2234

2235
   if (highlighting)
1,381✔
2236
      tb_cat(tb, "$$");
20✔
2237

2238
   va_list ap;
1,381✔
2239
   va_start(ap, fmt);
1,381✔
2240

2241
   if (syntax_buf != NULL) {
1,381✔
2242
      char *stripped LOCAL = strip_color(tb_get(tb), ap);
2,762✔
2243
      tb_cat(syntax_buf, stripped);
1,381✔
2244
   }
2245
   else
2246
      color_vprintf(tb_get(tb), ap);
×
2247

2248
   va_end(ap);
1,381✔
2249
}
1,381✔
2250

2251
void capture_syntax(text_buf_t *tb)
7✔
2252
{
2253
   assert(tb == NULL || syntax_buf == NULL);
7✔
2254
   syntax_buf = tb;
7✔
2255
}
7✔
2256

2257
void analyse_file(const char *file, jit_t *jit, unit_registry_t *ur)
2,898✔
2258
{
2259
   input_from_file(file);
2,898✔
2260

2261
   switch (source_kind()) {
2,898✔
2262
   case SOURCE_VHDL:
2,879✔
2263
      {
2264
         lib_t work = lib_work();
2,879✔
2265
         int base_errors = 0;
2,879✔
2266
         tree_t unit;
2,879✔
2267
         while (base_errors = error_count(), (unit = parse())) {
11,049✔
2268
            if (error_count() == base_errors) {
8,170✔
2269
               lib_put(work, unit);
8,169✔
2270
               unit_registry_purge(ur, tree_ident(unit));
8,169✔
2271

2272
               simplify_local(unit, jit, ur);
8,169✔
2273
               bounds_check(unit);
8,169✔
2274
            }
2275
            else
2276
               lib_put_error(work, unit);
1✔
2277
         }
2278
      }
2279
      break;
2280

2281
   case SOURCE_VERILOG:
19✔
2282
#ifdef ENABLE_VERILOG
2283
      {
2284
         LOCAL_TEXT_BUF tb = tb_new();
38✔
2285
         vlog_preprocess(tb);
19✔
2286

2287
         input_from_buffer(tb_get(tb), tb_len(tb), SOURCE_VERILOG);
19✔
2288

2289
         lib_t work = lib_work();
19✔
2290
         vlog_node_t module;
19✔
2291
         while ((module = vlog_parse())) {
57✔
2292
            if (error_count() == 0) {
19✔
2293
               vlog_check(module);
19✔
2294

2295
               if (error_count() == 0)
19✔
2296
                  lib_put_vlog(work, module);
19✔
2297
            }
2298
         }
2299
      }
2300
#else
2301
      fatal("Verilog is not currently supported");
2302
#endif
2303
      break;
19✔
2304
   }
2305
}
2,895✔
2306

2307
static void tree_copy_cb(tree_t t, void *__ctx)
277,488✔
2308
{
2309
   copy_ctx_t *ctx = __ctx;
277,488✔
2310

2311
   if (is_subprogram(t))
277,488✔
2312
      list_add(&ctx->copied_subs, t);
11,796✔
2313
}
277,488✔
2314

2315
static void type_copy_cb(type_t type, void *__ctx)
16,599✔
2316
{
2317
   copy_ctx_t *ctx = __ctx;
16,599✔
2318

2319
   if (type_has_ident(type))
16,599✔
2320
      list_add(&ctx->copied_types, type);
10,599✔
2321
}
16,599✔
2322

2323
void copy_with_renaming(tree_t *roots, int nroots, tree_copy_pred_t tree_pred,
6,608✔
2324
                        type_copy_pred_t type_pred, void *context,
2325
                        ident_t dotted, const ident_t *prefixes, int nprefix)
2326
{
2327
   copy_ctx_t copy_ctx = {};
6,608✔
2328

2329
   tree_copy(roots, nroots, tree_pred, type_pred, context,
6,608✔
2330
             tree_copy_cb, type_copy_cb, &copy_ctx);
2331

2332
   // Change the name of any copied types to reflect the new hiearchy
2333
   for (list_iter(type_t, type, copy_ctx.copied_types)) {
17,207✔
2334
      ident_t orig = type_ident(type);
10,599✔
2335
      for (int j = 0; j < nprefix; j++) {
31,999✔
2336
         if (ident_starts_with(orig, prefixes[j])) {
11,461✔
2337
            LOCAL_TEXT_BUF tb = tb_new();
660✔
2338
            tb_cat(tb, istr(dotted));
660✔
2339
            tb_cat(tb, istr(orig) + ident_len(prefixes[j]));
660✔
2340

2341
            type_set_ident(type, ident_new(tb_get(tb)));
660✔
2342
            break;
660✔
2343
         }
2344
      }
2345
   }
2346
   list_free(&copy_ctx.copied_types);
6,608✔
2347

2348
   // Change the mangled name of copied subprograms so that copies in
2349
   // different instances do not collide
2350
   for (list_iter(tree_t, decl, copy_ctx.copied_subs)) {
18,404✔
2351
      if (tree_kind(decl) == T_GENERIC_DECL)
11,796✔
2352
         continue;   // Does not yet have mangled name
398✔
2353

2354
      ident_t orig = tree_ident2(decl);
11,398✔
2355
      for (int j = 0; j < nprefix; j++) {
12,717✔
2356
         if (ident_starts_with(orig, prefixes[j])) {
11,472✔
2357
            ident_t prefix = ident_runtil(orig, '(');
10,153✔
2358

2359
            LOCAL_TEXT_BUF tb = tb_new();
10,153✔
2360
            tb_cat(tb, istr(dotted));
10,153✔
2361
            tb_cat(tb, istr(prefix) + ident_len(prefixes[j]));
10,153✔
2362

2363
            const tree_kind_t kind = tree_kind(decl);
10,153✔
2364
            const bool is_func = kind == T_FUNC_BODY || kind == T_FUNC_DECL;
10,153✔
2365
            const int nports = tree_ports(decl);
10,153✔
2366
            if (nports > 0 || is_func)
10,153✔
2367
               tb_append(tb, '(');
9,975✔
2368

2369
            for (int k = 0; k < nports; k++) {
29,931✔
2370
               tree_t p = tree_port(decl, k);
19,778✔
2371
               if (tree_class(p) == C_SIGNAL)
19,778✔
2372
                  tb_printf(tb, "s");
190✔
2373
               mangle_one_type(tb, tree_type(p));
19,778✔
2374
            }
2375

2376
            if (nports > 0 || is_func)
10,153✔
2377
               tb_printf(tb, ")");
9,975✔
2378

2379
            if (is_func)
10,153✔
2380
               mangle_one_type(tb, type_result(tree_type(decl)));
8,759✔
2381

2382
            if (tree_flags(decl) & TREE_F_PREDEFINED)
10,153✔
2383
               tb_cat(tb, "$predef");
1,832✔
2384

2385
            ident_t mangled = ident_new(tb_get(tb));
10,153✔
2386
            tree_set_ident2(decl, mangled);
10,153✔
2387

2388
            break;
10,153✔
2389
         }
2390
      }
2391
   }
2392
   list_free(&copy_ctx.copied_subs);
6,608✔
2393
}
6,608✔
2394

2395
bool all_character_literals(type_t type)
1,704✔
2396
{
2397
   assert(type_is_enum(type));
1,704✔
2398

2399
   type_t base = type_base_recur(type);
1,704✔
2400
   const int nlits = type_enum_literals(base);
1,704✔
2401
   for (int i = 0; i < nlits; i++) {
6,748✔
2402
      if (ident_char(tree_ident(type_enum_literal(base, i)), 0) != '\'')
5,811✔
2403
         return false;
2404
   }
2405

2406
   return true;
2407
}
2408

2409
bool is_operator_symbol(ident_t ident)
11,017✔
2410
{
2411
   const int len = ident_len(ident);
11,017✔
2412
   if (len < 3)
11,017✔
2413
      return false;
2414
   else if (ident_char(ident, 0) != '"')
11,017✔
2415
      return false;
2416
   else if (ident_char(ident, len - 1) != '"')
10,728✔
2417
      return false;
2418
   else if (ident_char(ident, 1) == '?' && standard() < STD_08)
10,728✔
2419
      return false;
2420

2421
   static const char *const strings[] = {
10,728✔
2422
      "\"??\"", "\"and\"", "\"or\"", "\"nand\"", "\"nor\"",
2423
      "\"xor\"", "\"xnor\"", "\"=\"", "\"/=\"", "\"<\"", "\"<=\"",
2424
      "\">\"", "\">=\"", "\"?=\"", "\"?/=\"", "\"?<\"", "\"?<=\"",
2425
      "\"?>\"", "\"?>=\"", "\"sll\"", "\"srl\"", "\"sla\"", "\"sra\"",
2426
      "\"rol\"", "\"ror\"", "\"+\"", "\"-\"", "\"&\"", "\"*\"",
2427
      "\"/\"", "\"mod\"", "\"rem\"", "\"**\"", "\"abs\"", "\"not\""
2428
   };
2429

2430
   static ident_t operators[ARRAY_LEN(strings)];
10,728✔
2431
   INIT_ONCE({
18,148✔
2432
         for (int i = 0; i < ARRAY_LEN(strings); i++)
2433
            operators[i] = ident_new(strings[i]);
2434
      });
2435

2436
   for (int i = 0; i < ARRAY_LEN(operators); i++) {
166,702✔
2437
      if (ident == operators[i])
166,701✔
2438
         return true;
2439
   }
2440

2441
   return false;
2442
}
2443

2444
bool same_tree(tree_t a, tree_t b)
2,689✔
2445
{
2446
   const tree_kind_t akind = tree_kind(a);
2,689✔
2447
   if (akind != tree_kind(b))
2,689✔
2448
      return false;
2449

2450
   switch (akind) {
2,635✔
2451
   case T_REF:
1,389✔
2452
      return tree_ref(a) == tree_ref(b);
1,389✔
2453
   case T_ARRAY_REF:
228✔
2454
      {
2455
         if (!same_tree(tree_value(a), tree_value(b)))
228✔
2456
            return false;
2457

2458
         const int nparams = tree_params(a);
216✔
2459
         assert(nparams == tree_params(b));
216✔
2460

2461
         for (int i = 0; i < nparams; i++) {
383✔
2462
            tree_t pa = tree_value(tree_param(a, i));
219✔
2463
            tree_t pb = tree_value(tree_param(b, i));
219✔
2464
            if (!same_tree(pa, pb))
219✔
2465
               return false;
2466
         }
2467

2468
         return true;
2469
      }
2470
   case T_ARRAY_SLICE:
32✔
2471
      {
2472
         if (!same_tree(tree_value(a), tree_value(b)))
32✔
2473
            return false;
2474

2475
         tree_t ra = tree_range(a, 0);
32✔
2476
         tree_t rb = tree_range(b, 0);
32✔
2477

2478
         const range_kind_t rakind = tree_subkind(ra);
32✔
2479
         if (rakind != tree_subkind(rb) || rakind == RANGE_EXPR)
32✔
2480
            return false;
2481

2482
         return same_tree(tree_left(ra), tree_left(rb))
32✔
2483
            && same_tree(tree_right(ra), tree_right(rb));
32✔
2484
      }
2485

2486
   case T_RECORD_REF:
729✔
2487
      return tree_ident(a) == tree_ident(b)
729✔
2488
         && same_tree(tree_value(a), tree_value(b));
729✔
2489

2490
   case T_LITERAL:
257✔
2491
      {
2492
         const literal_kind_t alkind = tree_subkind(a);
257✔
2493
         if (alkind != tree_subkind(b) || alkind != L_INT)
257✔
2494
            return false;
2495
         else
2496
            return tree_ival(a) == tree_ival(b);
257✔
2497
      }
2498
   default:
2499
      return false;
2500
   }
2501
}
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