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

nickg / nvc / 19798036146

30 Nov 2025 10:13AM UTC coverage: 92.564% (+0.009%) from 92.555%
19798036146

push

github

nickg
Avoid code generation for processes in cloned blocks

38 of 49 new or added lines in 4 files covered. (77.55%)

1016 existing lines in 13 files now uncovered.

75314 of 81364 relevant lines covered (92.56%)

413525.48 hits per line

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

99.23
/src/tree.c
1
//
2
//  Copyright (C) 2011-2025  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 "tree.h"
19
#include "util.h"
20
#include "object.h"
21
#include "common.h"
22

23
#include <assert.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <ctype.h>
27

28
static const imask_t has_map[T_LAST_TREE_KIND] = {
29
   // T_ENTITY
30
   (I_IDENT | I_PORTS | I_GENERICS | I_CONTEXT | I_DECLS | I_STMTS | I_PRAGMAS),
31

32
   // T_ARCH
33
   (I_IDENT | I_IDENT2 | I_DECLS | I_STMTS | I_CONTEXT | I_PRIMARY | I_PRAGMAS),
34

35
   // T_PORT_DECL
36
   (I_IDENT | I_VALUE | I_TYPE | I_SUBKIND | I_CLASS | I_FLAGS),
37

38
   // T_FCALL
39
   (I_IDENT | I_PARAMS | I_TYPE | I_REF | I_FLAGS),
40

41
   // T_LITERAL
42
   (I_SUBKIND | I_TYPE | I_IVAL | I_DVAL | I_IDENT | I_REF),
43

44
   // T_SIGNAL_DECL
45
   (I_IDENT | I_VALUE | I_TYPE | I_FLAGS),
46

47
   // T_VAR_DECL
48
   (I_IDENT | I_VALUE | I_TYPE | I_FLAGS),
49

50
   // T_PROCESS
51
   (I_IDENT | I_DECLS | I_STMTS | I_TRIGGERS | I_FLAGS),
52

53
   // T_REF
54
   (I_IDENT | I_TYPE | I_REF | I_FLAGS),
55

56
   // T_WAIT
57
   (I_IDENT | I_VALUE | I_DELAY | I_TRIGGERS | I_FLAGS),
58

59
   // T_TYPE_DECL
60
   (I_IDENT | I_TYPE),
61

62
   // T_VAR_ASSIGN
63
   (I_IDENT | I_VALUE | I_TARGET),
64

65
   // T_PACKAGE
66
   (I_IDENT | I_DECLS | I_CONTEXT | I_GENERICS | I_GENMAPS | I_PRAGMAS),
67

68
   // T_SIGNAL_ASSIGN
69
   (I_IDENT | I_TARGET | I_WAVES | I_REJECT),
70

71
   // T_QUALIFIED
72
   (I_IDENT | I_VALUE | I_TYPE),
73

74
   // T_ENUM_LIT
75
   (I_IDENT | I_TYPE | I_POS),
76

77
   // T_CONST_DECL
78
   (I_IDENT | I_VALUE | I_TYPE | I_FLAGS),
79

80
   // T_FUNC_DECL
81
   (I_IDENT | I_PORTS | I_TYPE | I_FLAGS | I_IDENT2 | I_SUBKIND | I_GENERICS),
82

83
   // T_ELAB
84
   (I_IDENT | I_DECLS | I_STMTS | I_CONTEXT),
85

86
   // T_AGGREGATE
87
   (I_TYPE | I_ASSOCS | I_FLAGS),
88

89
   // T_ASSERT
90
   (I_IDENT | I_VALUE | I_SEVERITY | I_MESSAGE),
91

92
   // T_ATTR_REF
93
   (I_NAME | I_VALUE | I_IDENT | I_PARAMS | I_TYPE | I_SUBKIND),
94

95
   // T_ARRAY_REF
96
   (I_VALUE | I_PARAMS | I_TYPE | I_FLAGS),
97

98
   // T_ARRAY_SLICE
99
   (I_VALUE | I_TYPE | I_RANGES),
100

101
   // T_INSTANCE
102
   (I_IDENT | I_IDENT2 | I_PARAMS | I_GENMAPS | I_REF | I_CLASS | I_SPEC),
103

104
   // T_IF
105
   (I_IDENT | I_CONDS),
106

107
   // T_NULL
108
   (I_IDENT),
109

110
   // T_PACK_BODY
111
   (I_IDENT | I_DECLS | I_CONTEXT | I_PRIMARY | I_PRAGMAS),
112

113
   // T_FUNC_BODY
114
   (I_IDENT | I_DECLS | I_STMTS | I_PORTS | I_TYPE | I_FLAGS | I_GENERICS
115
    | I_IDENT2 | I_SUBKIND),
116

117
   // T_RETURN
118
   (I_IDENT | I_TYPE | I_VALUE),
119

120
   // T_COND_ASSIGN
121
   (I_IDENT | I_TARGET | I_CONDS | I_GUARD),
122

123
   // T_WHILE
124
   (I_IDENT | I_VALUE | I_STMTS),
125

126
   // T_WAVEFORM
127
   (I_VALUE | I_DELAY),
128

129
   // T_ALIAS
130
   (I_IDENT | I_VALUE | I_TYPE | I_FLAGS),
131

132
   // T_FOR
133
   (I_IDENT | I_STMTS | I_RANGES | I_DECLS),
134

135
   // T_ATTR_DECL
136
   (I_IDENT | I_TYPE),
137

138
   // T_ATTR_SPEC
139
   (I_IDENT | I_VALUE | I_IDENT2 | I_CLASS | I_REF | I_TYPE | I_SUBKIND),
140

141
   // T_PROC_DECL
142
   (I_IDENT | I_PORTS | I_TYPE | I_FLAGS | I_IDENT2 | I_SUBKIND | I_GENERICS),
143

144
   // T_PROC_BODY
145
   (I_IDENT | I_DECLS | I_STMTS | I_PORTS | I_TYPE | I_FLAGS | I_GENERICS
146
    | I_IDENT2 | I_SUBKIND),
147

148
   // T_EXIT
149
   (I_IDENT | I_VALUE | I_IDENT2),
150

151
   // T_PCALL
152
   (I_IDENT | I_IDENT2 | I_PARAMS | I_REF),
153

154
   // T_CASE
155
   (I_IDENT | I_VALUE | I_STMTS),
156

157
   // T_BLOCK
158
   (I_IDENT | I_DECLS | I_STMTS | I_PORTS | I_GENERICS | I_PARAMS | I_GENMAPS),
159

160
   // T_COND_STMT
161
   (I_IDENT | I_VALUE | I_DECLS | I_STMTS),
162

163
   // T_TYPE_CONV
164
   (I_VALUE | I_TYPE | I_FLAGS),
165

166
   // T_SELECT
167
   (I_IDENT | I_VALUE | I_STMTS | I_GUARD),
168

169
   // T_COMPONENT
170
   (I_IDENT | I_PORTS | I_GENERICS),
171

172
   // T_IF_GENERATE
173
   (I_IDENT | I_CONDS),
174

175
   // T_FOR_GENERATE
176
   (I_IDENT | I_DECLS | I_STMTS | I_RANGES),
177

178
   // T_FILE_DECL
179
   (I_IDENT | I_VALUE | I_TYPE | I_FILE_MODE),
180

181
   // T_OPEN
182
   (I_TYPE),
183

184
   // T_FIELD_DECL
185
   (I_IDENT | I_TYPE | I_POS),
186

187
   // T_RECORD_REF
188
   (I_IDENT | I_VALUE | I_TYPE | I_REF),
189

190
   // T_ALL
191
   (I_VALUE | I_TYPE),
192

193
   // T_NEW
194
   (I_VALUE | I_TYPE),
195

196
   // T_UNIT_DECL
197
   (I_IDENT | I_VALUE | I_TYPE),
198

199
   // T_NEXT
200
   (I_IDENT | I_VALUE | I_IDENT2),
201

202
   // T_PARAM
203
   (I_VALUE | I_POS | I_SUBKIND | I_NAME),
204

205
   // T_ASSOC
206
   (I_VALUE | I_POS | I_NAME | I_RANGES | I_SUBKIND),
207

208
   // T_USE
209
   (I_IDENT | I_IDENT2 | I_REF),
210

211
   // T_HIER
212
   (I_IDENT | I_SUBKIND | I_IDENT2 | I_REF),
213

214
   // T_SPEC
215
   (I_IDENT | I_IDENT2 | I_VALUE | I_REF | I_DECLS),
216

217
   // T_BINDING
218
   (I_PARAMS | I_GENMAPS | I_IDENT | I_IDENT2 | I_CLASS | I_REF),
219

220
   // T_LIBRARY
221
   (I_IDENT | I_IDENT2),
222

223
   // T_DESIGN_UNIT
224
   (I_CONTEXT),
225

226
   // T_CONFIGURATION
227
   (I_IDENT | I_IDENT2 | I_DECLS | I_PRIMARY | I_PRAGMAS),
228

229
   // T_PROT_BODY
230
   (I_IDENT | I_TYPE | I_DECLS | I_PRIMARY),
231

232
   // T_CONTEXT
233
   (I_CONTEXT | I_IDENT | I_PRAGMAS),
234

235
   // T_CONTEXT_REF
236
   (I_IDENT | I_REF),
237

238
   // T_CONSTRAINT
239
   (I_SUBKIND | I_RANGES | I_REF),
240

241
   // T_BLOCK_CONFIG
242
   (I_DECLS | I_IDENT | I_VALUE | I_RANGES | I_REF),
243

244
   // T_PROT_FCALL
245
   (I_IDENT | I_PARAMS | I_TYPE | I_REF | I_FLAGS | I_NAME),
246

247
   // T_PROT_PCALL
248
   (I_IDENT | I_IDENT2 | I_PARAMS | I_REF | I_NAME),
249

250
   // T_RANGE
251
   (I_SUBKIND | I_VALUE | I_LEFT | I_RIGHT | I_TYPE),
252

253
   // T_IMPLICIT_SIGNAL
254
   (I_IDENT | I_TYPE | I_SUBKIND | I_VALUE | I_FLAGS),
255

256
   // T_DISCONNECT
257
   (I_IDENT | I_REF | I_TYPE | I_DELAY),
258

259
   // T_GROUP_TEMPLATE
260
   (I_IDENT),
261

262
   // T_GROUP
263
   (I_IDENT | I_REF),
264

265
   // T_SUBTYPE_DECL
266
   (I_IDENT | I_TYPE),
267

268
   // T_CONV_FUNC
269
   (I_IDENT | I_REF | I_VALUE | I_TYPE),
270

271
   // T_CONCURRENT
272
   (I_IDENT | I_STMTS | I_FLAGS),
273

274
   // T_SEQUENCE
275
   (I_IDENT | I_STMTS | I_DECLS),
276

277
   // T_PACK_INST
278
   (I_IDENT | I_REF | I_DECLS | I_CONTEXT | I_GENERICS | I_GENMAPS | I_PRAGMAS),
279

280
   // T_GENERIC_DECL
281
   (I_IDENT | I_VALUE | I_TYPE | I_CLASS | I_SUBKIND | I_FLAGS | I_PORTS),
282

283
   // T_TYPE_REF
284
   (I_IDENT | I_TYPE),
285

286
   // T_BOX
287
   (I_IDENT | I_TYPE | I_REF),
288

289
   // T_PARAM_DECL
290
   (I_IDENT | I_VALUE | I_TYPE | I_SUBKIND | I_CLASS | I_FLAGS),
291

292
   // T_EXTERNAL_NAME
293
   (I_PARTS | I_CLASS | I_TYPE | I_REF),
294

295
   // T_FORCE
296
   (I_IDENT | I_TARGET | I_VALUE | I_SUBKIND),
297

298
   // T_RELEASE
299
   (I_IDENT | I_TARGET | I_SUBKIND),
300

301
   // T_PROT_REF
302
   (I_IDENT | I_VALUE | I_TYPE | I_REF),
303

304
   // T_MATCH_CASE
305
   (I_IDENT | I_VALUE | I_STMTS),
306

307
   // T_FUNC_INST
308
   (I_IDENT | I_DECLS | I_STMTS | I_PORTS | I_TYPE | I_FLAGS | I_GENERICS
309
    | I_IDENT2 | I_SUBKIND | I_GENMAPS | I_REF),
310

311
   // T_PROC_INST
312
   (I_IDENT | I_DECLS | I_STMTS | I_PORTS | I_TYPE | I_FLAGS | I_GENERICS
313
    | I_IDENT2 | I_SUBKIND | I_GENMAPS | I_REF),
314

315
   // T_ELEM_CONSTRAINT
316
   (I_IDENT | I_REF | I_TYPE),
317

318
   // T_STRING
319
   (I_CHARS | I_TYPE),
320

321
   // T_PATH_ELT
322
   (I_SUBKIND | I_IDENT | I_VALUE),
323

324
   // T_PRAGMA
325
   (I_SUBKIND),
326

327
   // T_CASE_GENERATE
328
   (I_IDENT | I_VALUE | I_STMTS),
329

330
   // T_ALTERNATIVE
331
   (I_IDENT | I_ASSOCS | I_STMTS | I_DECLS),
332

333
   // T_PSL_DECL
334
   (I_IDENT | I_FOREIGN),
335

336
   // T_VERILOG
337
   (I_IDENT | I_FOREIGN),
338

339
   // T_VIEW_DECL
340
   (I_IDENT | I_TYPE),
341

342
   // T_PACKAGE_MAP
343
   (I_IDENT | I_SUBKIND | I_GENMAPS | I_REF),
344

345
   // T_COND_EXPR
346
   (I_VALUE | I_RESULT),
347

348
   // T_COND_VALUE
349
   (I_CONDS | I_TYPE),
350

351
   // T_COND_RETURN
352
   (I_IDENT | I_VALUE),
353

354
   // T_VIEW_ELEMENT
355
   (I_IDENT | I_REF | I_SUBKIND | I_TYPE | I_VALUE),
356

357
   // T_MATCH_SELECT
358
   (I_IDENT | I_VALUE | I_STMTS | I_GUARD),
359

360
   // T_PROT_DECL
361
   (I_IDENT | I_DECLS | I_TYPE),
362

363
   // T_DUMMY_DRIVER
364
   (I_TARGET | I_IDENT),
365

366
   // T_GUARD
367
   (I_REF | I_SPEC | I_TYPE),
368

369
   // T_INERTIAL
370
   (I_VALUE | I_TYPE | I_TARGET),
371

372
   // T_ELEM_RESOLUTION
373
   (I_ASSOCS),
374

375
   // T_LOOP
376
   (I_IDENT | I_STMTS),
377

378
   // T_REPORT
379
   (I_IDENT | I_SEVERITY | I_MESSAGE),
380

381
   // T_PSL_DIRECT
382
   (I_IDENT | I_FOREIGN),
383

384
   // T_PSL_FCALL
385
   (I_FOREIGN | I_TYPE),
386

387
   // T_PSL_UNION
388
   (I_FOREIGN | I_TYPE)
389
};
390

391
static const char *kind_text_map[T_LAST_TREE_KIND] = {
392
   "T_ENTITY",          "T_ARCH",            "T_PORT_DECL",
393
   "T_FCALL",           "T_LITERAL",         "T_SIGNAL_DECL",
394
   "T_VAR_DECL",        "T_PROCESS",         "T_REF",
395
   "T_WAIT",            "T_TYPE_DECL",       "T_VAR_ASSIGN",
396
   "T_PACKAGE",         "T_SIGNAL_ASSIGN",   "T_QUALIFIED",
397
   "T_ENUM_LIT",        "T_CONST_DECL",      "T_FUNC_DECL",
398
   "T_ELAB",            "T_AGGREGATE",       "T_ASSERT",
399
   "T_ATTR_REF",        "T_ARRAY_REF",       "T_ARRAY_SLICE",
400
   "T_INSTANCE",        "T_IF",              "T_NULL",
401
   "T_PACK_BODY",       "T_FUNC_BODY",       "T_RETURN",
402
   "T_COND_ASSIGN",     "T_WHILE",           "T_WAVEFORM",
403
   "T_ALIAS",           "T_FOR",             "T_ATTR_DECL",
404
   "T_ATTR_SPEC",       "T_PROC_DECL",       "T_PROC_BODY",
405
   "T_EXIT",            "T_PCALL",           "T_CASE",
406
   "T_BLOCK",           "T_COND_STMT",       "T_TYPE_CONV",
407
   "T_SELECT",          "T_COMPONENT",       "T_IF_GENERATE",
408
   "T_FOR_GENERATE",    "T_FILE_DECL",       "T_OPEN",
409
   "T_FIELD_DECL",      "T_RECORD_REF",      "T_ALL",
410
   "T_NEW",             "T_UNIT_DECL",       "T_NEXT",
411
   "T_PARAM",           "T_ASSOC",           "T_USE",
412
   "T_HIER",            "T_SPEC",            "T_BINDING",
413
   "T_LIBRARY",         "T_DESIGN_UNIT",     "T_CONFIGURATION",
414
   "T_PROT_BODY",       "T_CONTEXT",         "T_CONTEXT_REF",
415
   "T_CONSTRAINT",      "T_BLOCK_CONFIG",    "T_PROT_FCALL",
416
   "T_PROT_PCALL",      "T_RANGE",           "T_IMPLICIT_SIGNAL",
417
   "T_DISCONNECT",      "T_GROUP_TEMPLATE",  "T_GROUP",
418
   "T_SUBTYPE_DECL",    "T_CONV_FUNC",       "T_CONCURRENT",
419
   "T_SEQUENCE",        "T_PACK_INST",       "T_GENERIC_DECL",
420
   "T_TYPE_REF",        "T_BOX",             "T_PARAM_DECL",
421
   "T_EXTERNAL_NAME",   "T_FORCE",           "T_RELEASE",
422
   "T_PROT_REF",        "T_MATCH_CASE",      "T_FUNC_INST",
423
   "T_PROC_INST",       "T_ELEM_CONSTRAINT", "T_STRING",
424
   "T_PATH_ELT",        "T_PRAGMA",          "T_CASE_GENERATE",
425
   "T_ALTERNATIVE",     "T_PSL_DECL",        "T_VERILOG",
426
   "T_VIEW_DECL",       "T_PACKAGE_MAP",     "T_COND_EXPR",
427
   "T_COND_VALUE",      "T_COND_RETURN",     "T_VIEW_ELEMENT",
428
   "T_MATCH_SELECT",    "T_PROT_DECL",       "T_DUMMY_DRIVER",
429
   "T_GUARD",           "T_INERTIAL",        "T_ELEM_RESOLUTION",
430
   "T_LOOP",            "T_REPORT",          "T_PSL_DIRECT",
431
   "T_PSL_FCALL",       "T_PSL_UNION",
432
};
433

434
static const change_allowed_t change_allowed[] = {
435
   { T_REF,         T_FCALL         },
436
   { T_REF,         T_PCALL         },
437
   { T_ARRAY_REF,   T_FCALL         },
438
   { T_FCALL,       T_ARRAY_REF     },
439
   { T_PROT_FCALL,  T_ARRAY_REF     },
440
   { T_DESIGN_UNIT, T_ENTITY        },
441
   { T_DESIGN_UNIT, T_PACKAGE       },
442
   { T_DESIGN_UNIT, T_PACK_BODY     },
443
   { T_DESIGN_UNIT, T_ARCH          },
444
   { T_DESIGN_UNIT, T_CONFIGURATION },
445
   { T_DESIGN_UNIT, T_CONTEXT       },
446
   { T_DESIGN_UNIT, T_PACK_INST     },
447
   { T_FUNC_DECL,   T_FUNC_BODY     },
448
   { T_PROC_DECL,   T_PROC_BODY     },
449
   { T_FCALL,       T_PROT_FCALL    },
450
   { T_PCALL,       T_PROT_PCALL    },
451
   { -1,            -1              }
452
};
453

454
struct _tree {
455
   object_t object;
456
};
457

458
struct _type {
459
   object_t object;
460
};
461

462
struct _psl_node {
463
   object_t object;
464
};
465

466
struct _vlog_node {
467
   object_t object;
468
};
469

470
object_class_t tree_object = {
471
   .name           = "tree",
472
   .change_allowed = change_allowed,
473
   .has_map        = has_map,
474
   .kind_text_map  = kind_text_map,
475
   .tag            = OBJECT_TAG_TREE,
476
   .last_kind      = T_LAST_TREE_KIND,
477
   .has_loc        = true,
478
   .gc_roots       = { T_ARCH, T_ENTITY, T_PACKAGE, T_ELAB, T_PACK_BODY,
479
                       T_CONTEXT, T_CONFIGURATION, T_DESIGN_UNIT,
480
                       T_PACK_INST },
481
   .gc_num_roots   = 9
482
};
483

484
typedef struct {
485
   tree_deps_fn_t fn;
486
   void          *context;
487
} tree_deps_args_t;
488

489
#ifdef DEBUG
490
static tree_kind_t expr_kinds[] = {
491
   T_FCALL,     T_LITERAL,       T_REF,        T_QUALIFIED,
492
   T_AGGREGATE, T_ATTR_REF,      T_ARRAY_REF,  T_ARRAY_SLICE,
493
   T_TYPE_CONV, T_OPEN,          T_RECORD_REF, T_ALL,
494
   T_NEW,       T_PROT_FCALL,    T_CONV_FUNC,  T_TYPE_REF,
495
   T_BOX,       T_EXTERNAL_NAME, T_PROT_REF,   T_STRING,
496
};
497

498
static tree_kind_t decl_kinds[] = {
499
   T_PORT_DECL,      T_SIGNAL_DECL,    T_VAR_DECL,        T_TYPE_DECL,
500
   T_CONST_DECL,     T_FUNC_DECL,      T_FUNC_BODY,       T_ALIAS,
501
   T_ATTR_DECL,      T_ATTR_SPEC,      T_PROC_DECL,       T_PROC_BODY,
502
   T_COMPONENT,      T_FILE_DECL,      T_FIELD_DECL,      T_UNIT_DECL,
503
   T_HIER,           T_SPEC,           T_BINDING,         T_USE,
504
   T_PROT_BODY,      T_BLOCK_CONFIG,   T_IMPLICIT_SIGNAL, T_DISCONNECT,
505
   T_GROUP_TEMPLATE, T_GROUP,          T_SUBTYPE_DECL,    T_PACKAGE,
506
   T_PACK_BODY,      T_PACK_INST,      T_GENERIC_DECL,    T_PARAM_DECL,
507
   T_PROC_INST,      T_FUNC_INST,      T_PSL_DECL,        T_VIEW_DECL,
508
   T_PROT_DECL,      T_VERILOG,
509
};
510

511
static void tree_assert_kind(tree_t t, const tree_kind_t *list, size_t len,
395,386✔
512
                             const char *what)
513
{
514
   for (size_t i = 0; i < len; i++) {
4,744,827✔
515
      if (t->object.kind == list[i])
4,744,827✔
516
         return;
395,386✔
517
   }
518

519
   fatal_trace("tree kind %s is not %s", tree_kind_str(t->object.kind), what);
520
}
521
#else
522
#define tree_assert_kind(t, list, len, what)
523
#endif
524

525
static inline void tree_assert_expr(tree_t t)
149,178✔
526
{
527
   tree_assert_kind(t, expr_kinds, ARRAY_LEN(expr_kinds), "an expression");
149,178✔
528
}
149,178✔
529

530
static inline void tree_assert_decl(tree_t t)
246,208✔
531
{
532
   tree_assert_kind(t, decl_kinds, ARRAY_LEN(decl_kinds), "a declaration");
246,208✔
533
}
246,208✔
534

535
static inline tree_t tree_array_nth(item_t *item, unsigned n)
32,959,718✔
536
{
537
   object_t *o = obj_array_nth(item->obj_array, n);
32,959,718✔
538
   return container_of(o, struct _tree, object);
32,959,718✔
539
}
540

541
static inline void tree_array_add(item_t *item, tree_t t)
1,149,072✔
542
{
543
   obj_array_add(&(item->obj_array), &(t->object));
1,149,072✔
544
}
1,149,072✔
545

546
static inline void tree_copy_array(tree_t t, tree_t from, imask_t mask)
28,436✔
547
{
548
   item_t *dst = lookup_item(&tree_object, t, mask);
28,436✔
549
   const item_t *src = lookup_item(&tree_object, from, mask);
28,436✔
550
   if (src->obj_array == NULL)
28,436✔
551
      return;
552

553
   obj_array_copy(&(dst->obj_array), src->obj_array);
11,276✔
554

555
   for (int i = 0; i < src->obj_array->count; i++)
53,238✔
556
      object_write_barrier(&(t->object), src->obj_array->items[i]);
41,962✔
557
}
558

559
tree_t tree_new(tree_kind_t kind)
1,778,633✔
560
{
561
   object_t *o = object_new(NULL, &tree_object, kind);
1,778,633✔
562
   return container_of(o, struct _tree, object);
1,778,633✔
563
}
564

565
const loc_t *tree_loc(tree_t t)
2,279,403✔
566
{
567
   assert(t != NULL);
2,279,403✔
568
   return &t->object.loc;
2,279,403✔
569
}
570

571
void tree_set_loc(tree_t t, const loc_t *loc)
1,814,806✔
572
{
573
   assert(t != NULL);
1,814,806✔
574
   assert(loc != NULL);
1,814,806✔
575

576
   t->object.loc = *loc;
1,814,806✔
577
}
1,814,806✔
578

579
ident_t tree_ident(tree_t t)
29,660,121✔
580
{
581
   item_t *item = lookup_item(&tree_object, t, I_IDENT);
29,660,121✔
582
   assert(item->ident != NULL);
29,660,121✔
583
   return item->ident;
29,660,121✔
584
}
585

586
bool tree_has_ident(tree_t t)
12,517✔
587
{
588
   return lookup_item(&tree_object, t, I_IDENT)->ident != NULL;
12,517✔
589
}
590

591
void tree_set_ident(tree_t t, ident_t i)
1,210,432✔
592
{
593
   lookup_item(&tree_object, t, I_IDENT)->ident = i;
1,210,432✔
594
}
1,210,432✔
595

596
ident_t tree_ident2(tree_t t)
716,298✔
597
{
598
   item_t *item = lookup_item(&tree_object, t, I_IDENT2);
716,298✔
599
   assert(item->ident != NULL);
716,298✔
600
   return item->ident;
716,298✔
601
}
602

603
void tree_set_ident2(tree_t t, ident_t i)
131,448✔
604
{
605
   lookup_item(&tree_object, t, I_IDENT2)->ident = i;
131,448✔
606
}
131,448✔
607

608
bool tree_has_ident2(tree_t t)
76,094✔
609
{
610
   return lookup_item(&tree_object, t, I_IDENT2)->ident != NULL;
76,094✔
611
}
612

613
tree_kind_t tree_kind(tree_t t)
123,106,796✔
614
{
615
   assert(t != NULL);
123,106,796✔
616
   return t->object.kind;
123,106,796✔
617
}
618

619
void tree_change_kind(tree_t t, tree_kind_t kind)
24,288✔
620
{
621
   object_change_kind(&tree_object, &(t->object), kind);
24,288✔
622
}
24,288✔
623

624
unsigned tree_ports(tree_t t)
3,961,362✔
625
{
626
   item_t *item = lookup_item(&tree_object, t, I_PORTS);
3,961,362✔
627
   return obj_array_count(item->obj_array);
3,961,362✔
628
}
629

630
tree_t tree_port(tree_t t, unsigned n)
5,595,475✔
631
{
632
   item_t *item = lookup_item(&tree_object, t, I_PORTS);
5,595,475✔
633
   return tree_array_nth(item, n);
5,595,475✔
634
}
635

636
void tree_add_port(tree_t t, tree_t d)
113,496✔
637
{
638
   tree_assert_decl(d);
113,496✔
639
   tree_array_add(lookup_item(&tree_object, t, I_PORTS), d);
113,496✔
640
   object_write_barrier(&(t->object), &(d->object));
113,496✔
641
}
113,496✔
642

643
void tree_copy_ports(tree_t t, tree_t from)
5,495✔
644
{
645
   tree_copy_array(t, from, I_PORTS);
5,495✔
646
}
5,495✔
647

648
unsigned tree_subkind(tree_t t)
31,395,987✔
649
{
650
   item_t *item = lookup_item(&tree_object, t, I_SUBKIND);
31,395,987✔
651
   return item->ival;
31,395,987✔
652
}
653

654
void tree_set_subkind(tree_t t, unsigned sub)
714,520✔
655
{
656
   lookup_item(&tree_object, t, I_SUBKIND)->ival = sub;
714,520✔
657
}
714,520✔
658

659
unsigned tree_generics(tree_t t)
219,779✔
660
{
661
   item_t *item = lookup_item(&tree_object, t, I_GENERICS);
219,779✔
662
   return obj_array_count(item->obj_array);
219,779✔
663
}
664

665
tree_t tree_generic(tree_t t, unsigned n)
56,387✔
666
{
667
   item_t *item = lookup_item(&tree_object, t, I_GENERICS);
56,387✔
668
   return tree_array_nth(item, n);
56,387✔
669
}
670

671
void tree_add_generic(tree_t t, tree_t d)
10,920✔
672
{
673
   assert(d->object.kind == T_GENERIC_DECL);
10,920✔
674
   tree_array_add(lookup_item(&tree_object, t, I_GENERICS), d);
10,920✔
675
   object_write_barrier(&(t->object), &(d->object));
10,920✔
676
}
10,920✔
677

678
void tree_copy_generics(tree_t t, tree_t from)
410✔
679
{
680
   tree_copy_array(t, from, I_GENERICS);
410✔
681
}
410✔
682

683
type_t tree_type(tree_t t)
33,865,183✔
684
{
685
   item_t *item = lookup_item(&tree_object, t, I_TYPE);
33,865,183✔
686
   assert(item->object != NULL);
33,865,183✔
687
   return container_of(item->object, struct _type, object);
33,865,183✔
688
}
689

690
void tree_set_type(tree_t t, type_t ty)
1,233,273✔
691
{
692
   object_t *obj = ty ? &(ty->object) : NULL;
1,233,273✔
693
   lookup_item(&tree_object, t, I_TYPE)->object = obj;
1,233,273✔
694
   object_write_barrier(&(t->object), obj);
1,233,273✔
695
}
1,233,273✔
696

697
bool tree_has_type(tree_t t)
4,914,327✔
698
{
699
   return lookup_item(&tree_object, t, I_TYPE)->object != NULL;
4,914,327✔
700
}
701

702
unsigned tree_params(tree_t t)
14,698,797✔
703
{
704
   item_t *item = lookup_item(&tree_object, t, I_PARAMS);
14,698,797✔
705
   return obj_array_count(item->obj_array);
14,698,797✔
706
}
707

708
tree_t tree_param(tree_t t, unsigned n)
14,974,066✔
709
{
710
   item_t *item = lookup_item(&tree_object, t, I_PARAMS);
14,974,066✔
711
   return tree_array_nth(item, n);
14,974,066✔
712
}
713

714
void tree_add_param(tree_t t, tree_t e)
218,543✔
715
{
716
   assert(e->object.kind == T_PARAM);
218,543✔
717
   tree_array_add(lookup_item(&tree_object, t, I_PARAMS), e);
218,543✔
718
   object_write_barrier(&(t->object), &(e->object));
218,543✔
719
}
218,543✔
720

721
unsigned tree_genmaps(tree_t t)
58,283✔
722
{
723
   item_t *item = lookup_item(&tree_object, t, I_GENMAPS);
58,283✔
724
   return obj_array_count(item->obj_array);
58,283✔
725
}
726

727
tree_t tree_genmap(tree_t t, unsigned n)
44,935✔
728
{
729
   item_t *item = lookup_item(&tree_object, t, I_GENMAPS);
44,935✔
730
   return tree_array_nth(item, n);
44,935✔
731
}
732

733
void tree_add_genmap(tree_t t, tree_t e)
12,333✔
734
{
735
   tree_array_add(lookup_item(&tree_object, t, I_GENMAPS), e);
12,333✔
736
}
12,333✔
737

738
void tree_trim_genmaps(tree_t t, unsigned n)
5✔
739
{
740
   item_t *item = lookup_item(&tree_object, t, I_GENMAPS);
5✔
741
   assert(n < obj_array_count(item->obj_array));
5✔
742
   assert(n > 0);
5✔
743
   item->obj_array->count = n;
5✔
744
}
5✔
745

746
int64_t tree_ival(tree_t t)
3,104,981✔
747
{
748
   return lookup_item(&tree_object, t, I_IVAL)->ival;
3,104,981✔
749
}
750

751
void tree_set_ival(tree_t t, int64_t i)
121,813✔
752
{
753
   lookup_item(&tree_object, t, I_IVAL)->ival = i;
121,813✔
754
}
121,813✔
755

756
double tree_dval(tree_t t)
282,718✔
757
{
758
   return lookup_item(&tree_object, t, I_DVAL)->dval;
282,718✔
759
}
760

761
void tree_set_dval(tree_t t, double d)
23,688✔
762
{
763
   lookup_item(&tree_object, t, I_DVAL)->dval = d;
23,688✔
764
}
23,688✔
765

766
tree_flags_t tree_flags(tree_t t)
18,075,011✔
767
{
768
   return lookup_item(&tree_object, t, I_FLAGS)->ival;
18,075,011✔
769
}
770

771
void tree_set_flag(tree_t t, tree_flags_t mask)
160,332✔
772
{
773
   lookup_item(&tree_object, t, I_FLAGS)->ival |= mask;
160,332✔
774
}
160,332✔
775

776
void tree_clear_flag(tree_t t, tree_flags_t mask)
593✔
777
{
778
   lookup_item(&tree_object, t, I_FLAGS)->ival &= ~mask;
593✔
779
}
593✔
780

781
tree_t tree_primary(tree_t t)
65,225✔
782
{
783
   item_t *item = lookup_item(&tree_object, t, I_PRIMARY);
65,225✔
784
   assert(item->object != NULL);
65,225✔
785
   return container_of(item->object, struct _tree, object);
65,225✔
786
}
787

788
bool tree_has_primary(tree_t t)
6,128✔
789
{
790
   return lookup_item(&tree_object, t, I_PRIMARY)->object != NULL;
6,128✔
791
}
792

793
void tree_set_primary(tree_t t, tree_t unit)
6,324✔
794
{
795
   lookup_item(&tree_object, t, I_PRIMARY)->object = &(unit->object);
6,324✔
796
   object_write_barrier(&(t->object), &(unit->object));
6,324✔
797
}
6,324✔
798

799
psl_node_t tree_psl(tree_t t)
1,399✔
800
{
801
   item_t *item = lookup_item(&tree_object, t, I_FOREIGN);
1,399✔
802
   assert(item->object != NULL);
1,399✔
803
   return container_of(item->object, struct _psl_node, object);
1,399✔
804
}
805

806
void tree_set_psl(tree_t t, psl_node_t p)
577✔
807
{
808
   assert(p != NULL);
577✔
809
   lookup_item(&tree_object, t, I_FOREIGN)->object = &(p->object);
577✔
810
   object_write_barrier(&(t->object), &(p->object));
577✔
811
}
577✔
812

UNCOV
813
bool tree_has_psl(tree_t t)
×
814
{
UNCOV
815
   return lookup_item(&tree_object, t, I_FOREIGN)->object != NULL;
×
816
}
817

818
vlog_node_t tree_vlog(tree_t t)
1,661✔
819
{
820
   item_t *item = lookup_item(&tree_object, t, I_FOREIGN);
1,661✔
821
   assert(item->object != NULL);
1,661✔
822
   return container_of(item->object, struct _vlog_node, object);
1,661✔
823
}
824

825
void tree_set_vlog(tree_t t, vlog_node_t v)
1,416✔
826
{
827
   assert(v != NULL);
1,416✔
828
   lookup_item(&tree_object, t, I_FOREIGN)->object = &(v->object);
1,416✔
829
   object_write_barrier(&(t->object), &(v->object));
1,416✔
830
}
1,416✔
831

832
unsigned tree_chars(tree_t t)
132,493✔
833
{
834
   item_t *item = lookup_item(&tree_object, t, I_CHARS);
132,493✔
835
   return obj_array_count(item->obj_array);
132,493✔
836
}
837

838
tree_t tree_char(tree_t t, unsigned n)
1,012,665✔
839
{
840
   item_t *item = lookup_item(&tree_object, t, I_CHARS);
1,012,665✔
841
   return tree_array_nth(item, n);
1,012,665✔
842
}
843

844
void tree_add_char(tree_t t, tree_t ref)
359,224✔
845
{
846
   tree_array_add(lookup_item(&tree_object, t, I_CHARS), ref);
359,224✔
847
   object_write_barrier(&(t->object), &(ref->object));
359,224✔
848
}
359,224✔
849

850
unsigned tree_parts(tree_t t)
696✔
851
{
852
   item_t *item = lookup_item(&tree_object, t, I_PARTS);
696✔
853
   return obj_array_count(item->obj_array);
696✔
854
}
855

856
tree_t tree_part(tree_t t, unsigned n)
2,109✔
857
{
858
   item_t *item = lookup_item(&tree_object, t, I_PARTS);
2,109✔
859
   return tree_array_nth(item, n);
2,109✔
860
}
861

862
void tree_add_part(tree_t t, tree_t ref)
653✔
863
{
864
   tree_array_add(lookup_item(&tree_object, t, I_PARTS), ref);
653✔
865
   object_write_barrier(&(t->object), &(ref->object));
653✔
866
}
653✔
867

868
bool tree_has_value(tree_t t)
3,241,358✔
869
{
870
   return lookup_item(&tree_object, t, I_VALUE)->object != NULL;
3,241,358✔
871
}
872

873
tree_t tree_value(tree_t t)
17,105,516✔
874
{
875
   item_t *item = lookup_item(&tree_object, t, I_VALUE);
17,105,516✔
876
   assert(item->object != NULL);
17,105,516✔
877
   return container_of(item->object, struct _tree, object);
17,105,516✔
878
}
879

880
void tree_set_value(tree_t t, tree_t v)
392,467✔
881
{
882
   object_t *obj = v ? &(v->object) : NULL;
392,467✔
883
   lookup_item(&tree_object, t, I_VALUE)->object = obj;
392,467✔
884
   object_write_barrier(&(t->object), obj);
392,467✔
885
}
392,467✔
886

887
bool tree_has_result(tree_t t)
330✔
888
{
889
   return lookup_item(&tree_object, t, I_RESULT)->object != NULL;
330✔
890
}
891

892
tree_t tree_result(tree_t t)
324✔
893
{
894
   item_t *item = lookup_item(&tree_object, t, I_RESULT);
324✔
895
   assert(item->object != NULL);
324✔
896
   return container_of(item->object, struct _tree, object);
324✔
897
}
898

899
void tree_set_result(tree_t t, tree_t v)
117✔
900
{
901
   object_t *obj = v ? &(v->object) : NULL;
117✔
902
   lookup_item(&tree_object, t, I_RESULT)->object = obj;
117✔
903
   object_write_barrier(&(t->object), obj);
117✔
904
}
117✔
905

906
unsigned tree_decls(tree_t t)
139,389✔
907
{
908
   item_t *item = lookup_item(&tree_object, t, I_DECLS);
139,389✔
909
   return obj_array_count(item->obj_array);
139,389✔
910
}
911

912
tree_t tree_decl(tree_t t, unsigned n)
8,099,347✔
913
{
914
   item_t *item = lookup_item(&tree_object, t, I_DECLS);
8,099,347✔
915
   return tree_array_nth(item, n);
8,099,347✔
916
}
917

918
void tree_add_decl(tree_t t, tree_t d)
132,712✔
919
{
920
   tree_assert_decl(d);
132,712✔
921
   tree_array_add(lookup_item(&tree_object, t, I_DECLS), d);
132,712✔
922
   object_write_barrier(&(t->object), &(d->object));
132,712✔
923
}
132,712✔
924

925
void tree_copy_decls(tree_t t, tree_t from)
11,218✔
926
{
927
   tree_copy_array(t, from, I_DECLS);
11,218✔
928
}
11,218✔
929

930
unsigned tree_stmts(tree_t t)
122,203✔
931
{
932
   item_t *item = lookup_item(&tree_object, t, I_STMTS);
122,203✔
933
   return obj_array_count(item->obj_array);
122,203✔
934
}
935

936
tree_t tree_stmt(tree_t t, unsigned n)
190,852✔
937
{
938
   item_t *item = lookup_item(&tree_object, t, I_STMTS);
190,852✔
939
   return tree_array_nth(item, n);
190,852✔
940
}
941

942
void tree_add_stmt(tree_t t, tree_t s)
132,023✔
943
{
944
   assert(s != NULL);
132,023✔
945
   tree_array_add(lookup_item(&tree_object, t, I_STMTS), s);
132,023✔
946
   object_write_barrier(&(t->object), &(s->object));
132,023✔
947
}
132,023✔
948

949
void tree_copy_stmts(tree_t t, tree_t from)
11,313✔
950
{
951
   tree_copy_array(t, from, I_STMTS);
11,313✔
952
}
11,313✔
953

954
unsigned tree_waveforms(tree_t t)
35,629✔
955
{
956
   item_t *item = lookup_item(&tree_object, t, I_WAVES);
35,629✔
957
   return obj_array_count(item->obj_array);
35,629✔
958
}
959

960
tree_t tree_waveform(tree_t t, unsigned n)
36,418✔
961
{
962
   item_t *item = lookup_item(&tree_object, t, I_WAVES);
36,418✔
963
   return tree_array_nth(item, n);
36,418✔
964
}
965

966
void tree_add_waveform(tree_t t, tree_t w)
8,122✔
967
{
968
   assert(w->object.kind == T_WAVEFORM);
8,122✔
969
   tree_array_add(lookup_item(&tree_object, t, I_WAVES), w);
8,122✔
970
   object_write_barrier(&(t->object), &(w->object));
8,122✔
971
}
8,122✔
972

973
unsigned tree_conds(tree_t t)
36,305✔
974
{
975
   item_t *item = lookup_item(&tree_object, t, I_CONDS);
36,305✔
976
   return obj_array_count(item->obj_array);
36,305✔
977
}
978

979
tree_t tree_cond(tree_t t, unsigned n)
50,323✔
980
{
981
   item_t *item = lookup_item(&tree_object, t, I_CONDS);
50,323✔
982
   return tree_array_nth(item, n);
50,323✔
983
}
984

985
void tree_add_cond(tree_t t, tree_t c)
15,055✔
986
{
987
   assert(c->object.kind == T_COND_STMT || c->object.kind == T_COND_EXPR);
15,055✔
988
   tree_array_add(lookup_item(&tree_object, t, I_CONDS), c);
15,055✔
989
   object_write_barrier(&(t->object), &(c->object));
15,055✔
990
}
15,055✔
991

992
bool tree_has_delay(tree_t t)
71,939✔
993
{
994
   return lookup_item(&tree_object, t, I_DELAY)->object != NULL;
71,939✔
995
}
996

997
tree_t tree_delay(tree_t t)
19,413✔
998
{
999
   item_t *item = lookup_item(&tree_object, t, I_DELAY);
19,413✔
1000
   assert(item->object != NULL);
19,413✔
1001
   return container_of(item->object, struct _tree, object);
19,413✔
1002
}
1003

1004
void tree_set_delay(tree_t t, tree_t d)
6,326✔
1005
{
1006
   tree_assert_expr(d);
6,326✔
1007
   lookup_item(&tree_object, t, I_DELAY)->object = &(d->object);
6,326✔
1008
   object_write_barrier(&(t->object), &(d->object));
6,326✔
1009
}
6,326✔
1010

1011
unsigned tree_triggers(tree_t t)
58,057✔
1012
{
1013
   item_t *item = lookup_item(&tree_object, t, I_TRIGGERS);
58,057✔
1014
   return obj_array_count(item->obj_array);
58,057✔
1015
}
1016

1017
tree_t tree_trigger(tree_t t, unsigned n)
8,342✔
1018
{
1019
   item_t *item = lookup_item(&tree_object, t, I_TRIGGERS);
8,342✔
1020
   return tree_array_nth(item, n);
8,342✔
1021
}
1022

1023
void tree_add_trigger(tree_t t, tree_t s)
4,228✔
1024
{
1025
   tree_assert_expr(s);
4,228✔
1026
   tree_array_add(lookup_item(&tree_object, t, I_TRIGGERS), s);
4,228✔
1027
   object_write_barrier(&(t->object), &(s->object));
4,228✔
1028
}
4,228✔
1029

1030
tree_t tree_target(tree_t t)
103,308✔
1031
{
1032
   item_t *item = lookup_item(&tree_object, t, I_TARGET);
103,308✔
1033
   assert(item->object != NULL);
103,308✔
1034
   return container_of(item->object, struct _tree, object);
103,308✔
1035
}
1036

1037
void tree_set_target(tree_t t, tree_t lhs)
27,096✔
1038
{
1039
   lookup_item(&tree_object, t, I_TARGET)->object = &(lhs->object);
27,096✔
1040
   object_write_barrier(&(t->object), &(lhs->object));
27,096✔
1041
}
27,096✔
1042

1043
tree_t tree_ref(tree_t t)
20,064,515✔
1044
{
1045
   item_t *item = lookup_item(&tree_object, t, I_REF);
20,064,515✔
1046
   assert(item->object != NULL);
20,064,515✔
1047
   return container_of(item->object, struct _tree, object);
20,064,515✔
1048
}
1049

1050
bool tree_has_ref(tree_t t)
16,185,967✔
1051
{
1052
   return lookup_item(&tree_object, t, I_REF)->object != NULL;
16,185,967✔
1053
}
1054

1055
void tree_set_ref(tree_t t, tree_t decl)
1,095,414✔
1056
{
1057
   object_t *obj = decl ? &(decl->object) : NULL;
1,095,414✔
1058
   lookup_item(&tree_object, t, I_REF)->object = obj;
1,095,414✔
1059
   object_write_barrier(&(t->object), obj);
1,095,414✔
1060
}
1,095,414✔
1061

1062
tree_t tree_spec(tree_t t)
2,691✔
1063
{
1064
   item_t *item = lookup_item(&tree_object, t, I_SPEC);
2,691✔
1065
   assert(item->object != NULL);
2,691✔
1066
   return container_of(item->object, struct _tree, object);
2,691✔
1067
}
1068

1069
bool tree_has_spec(tree_t t)
16,520✔
1070
{
1071
   return lookup_item(&tree_object, t, I_SPEC)->object != NULL;
16,520✔
1072
}
1073

1074
void tree_set_spec(tree_t t, tree_t s)
321✔
1075
{
1076
   assert(s != NULL);
321✔
1077
   lookup_item(&tree_object, t, I_SPEC)->object = &(s->object);
321✔
1078
   object_write_barrier(&(t->object), &(s->object));
321✔
1079
}
321✔
1080

1081
unsigned tree_contexts(tree_t t)
29,224✔
1082
{
1083
   item_t *item = lookup_item(&tree_object, t, I_CONTEXT);
29,224✔
1084
   return obj_array_count(item->obj_array);
29,224✔
1085
}
1086

1087
tree_t tree_context(tree_t t, unsigned n)
97,668✔
1088
{
1089
   item_t *item = lookup_item(&tree_object, t, I_CONTEXT);
97,668✔
1090
   return tree_array_nth(item, n);
97,668✔
1091
}
1092

1093
void tree_add_context(tree_t t, tree_t ctx)
42,897✔
1094
{
1095
   assert(ctx->object.kind == T_USE || ctx->object.kind == T_LIBRARY
42,897✔
1096
          || ctx->object.kind == T_CONTEXT_REF);
1097
   tree_array_add(lookup_item(&tree_object, t, I_CONTEXT), ctx);
42,897✔
1098
   object_write_barrier(&(t->object), &(ctx->object));
42,897✔
1099
}
42,897✔
1100

1101
unsigned tree_pragmas(tree_t t)
388✔
1102
{
1103
   item_t *item = lookup_item(&tree_object, t, I_PRAGMAS);
388✔
1104
   return obj_array_count(item->obj_array);
388✔
1105
}
1106

1107
tree_t tree_pragma(tree_t t, unsigned n)
51✔
1108
{
1109
   item_t *item = lookup_item(&tree_object, t, I_PRAGMAS);
51✔
1110
   return tree_array_nth(item, n);
51✔
1111
}
1112

1113
void tree_add_pragma(tree_t t, tree_t p)
59✔
1114
{
1115
   assert(p->object.kind == T_PRAGMA);
59✔
1116
   tree_array_add(lookup_item(&tree_object, t, I_PRAGMAS), p);
59✔
1117
   object_write_barrier(&(t->object), &(p->object));
59✔
1118
}
59✔
1119

1120
unsigned tree_assocs(tree_t t)
209,037✔
1121
{
1122
   item_t *item = lookup_item(&tree_object, t, I_ASSOCS);
209,037✔
1123
   return obj_array_count(item->obj_array);
209,037✔
1124
}
1125

1126
tree_t tree_assoc(tree_t t, unsigned n)
1,081,888✔
1127
{
1128
   item_t *item = lookup_item(&tree_object, t, I_ASSOCS);
1,081,888✔
1129
   return tree_array_nth(item, n);
1,081,888✔
1130
}
1131

1132
void tree_add_assoc(tree_t t, tree_t a)
48,897✔
1133
{
1134
   assert(a->object.kind == T_ASSOC);
48,897✔
1135
   tree_array_add(lookup_item(&tree_object, t, I_ASSOCS), a);
48,897✔
1136
   object_write_barrier(&(t->object), &(a->object));
48,897✔
1137
}
48,897✔
1138

1139
tree_t tree_severity(tree_t t)
9,423✔
1140
{
1141
   item_t *item = lookup_item(&tree_object, t, I_SEVERITY);
9,423✔
1142
   assert(item->object != NULL);
9,423✔
1143
   return container_of(item->object, struct _tree, object);
9,423✔
1144
}
1145

1146
void tree_set_severity(tree_t t, tree_t s)
6,117✔
1147
{
1148
   tree_assert_expr(s);
6,117✔
1149
   lookup_item(&tree_object, t, I_SEVERITY)->object = &(s->object);
6,117✔
1150
   object_write_barrier(&(t->object), &(s->object));
6,117✔
1151
}
6,117✔
1152

1153
bool tree_has_severity(tree_t t)
35,999✔
1154
{
1155
   return lookup_item(&tree_object, t, I_SEVERITY)->object != NULL;
35,999✔
1156
}
1157

1158
tree_t tree_message(tree_t t)
13,856✔
1159
{
1160
   item_t *item = lookup_item(&tree_object, t, I_MESSAGE);
13,856✔
1161
   assert(item->object != NULL);
13,856✔
1162
   return container_of(item->object, struct _tree, object);
13,856✔
1163
}
1164

1165
bool tree_has_message(tree_t t)
48,726✔
1166
{
1167
   return lookup_item(&tree_object, t, I_MESSAGE)->object != NULL;
48,726✔
1168
}
1169

1170
void tree_set_message(tree_t t, tree_t m)
8,240✔
1171
{
1172
   tree_assert_expr(m);
8,240✔
1173
   lookup_item(&tree_object, t, I_MESSAGE)->object = &(m->object);
8,240✔
1174
   object_write_barrier(&(t->object), &(m->object));
8,240✔
1175
}
8,240✔
1176

1177
void tree_add_range(tree_t t, tree_t r)
49,910✔
1178
{
1179
   tree_array_add(lookup_item(&tree_object, t, I_RANGES), r);
49,910✔
1180
   object_write_barrier(&(t->object), &(r->object));
49,910✔
1181
}
49,910✔
1182

1183
tree_t tree_range(tree_t t, unsigned n)
1,709,192✔
1184
{
1185
   item_t *item = lookup_item(&tree_object, t, I_RANGES);
1,709,192✔
1186
   return tree_array_nth(item, n);
1,709,192✔
1187
}
1188

1189
unsigned tree_ranges(tree_t t)
1,653,349✔
1190
{
1191
   item_t *item = lookup_item(&tree_object, t, I_RANGES);
1,653,349✔
1192
   return obj_array_count(item->obj_array);
1,653,349✔
1193
}
1194

1195
unsigned tree_pos(tree_t t)
3,708,424✔
1196
{
1197
   return lookup_item(&tree_object, t, I_POS)->ival;
3,708,424✔
1198
}
1199

1200
void tree_set_pos(tree_t t, unsigned pos)
254,035✔
1201
{
1202
   lookup_item(&tree_object, t, I_POS)->ival = pos;
254,035✔
1203
}
254,035✔
1204

1205
tree_t tree_left(tree_t t)
2,653,800✔
1206
{
1207
   item_t *item = lookup_item(&tree_object, t, I_LEFT);
2,653,800✔
1208
   assert(item->object != NULL);
2,653,800✔
1209
   return container_of(item->object, struct _tree, object);
2,653,800✔
1210
}
1211

1212
void tree_set_left(tree_t t, tree_t left)
41,889✔
1213
{
1214
   tree_assert_expr(left);
41,889✔
1215
   lookup_item(&tree_object, t, I_LEFT)->object = &(left->object);
41,889✔
1216
   object_write_barrier(&(t->object), &(left->object));
41,889✔
1217
}
41,889✔
1218

1219
tree_t tree_right(tree_t t)
2,184,442✔
1220
{
1221
   item_t *item = lookup_item(&tree_object, t, I_RIGHT);
2,184,442✔
1222
   assert(item->object != NULL);
2,184,442✔
1223
   return container_of(item->object, struct _tree, object);
2,184,442✔
1224
}
1225

1226
void tree_set_right(tree_t t, tree_t right)
41,888✔
1227
{
1228
   tree_assert_expr(right);
41,888✔
1229
   lookup_item(&tree_object, t, I_RIGHT)->object = &(right->object);
41,888✔
1230
   object_write_barrier(&(t->object), &(right->object));
41,888✔
1231
}
41,888✔
1232

1233
class_t tree_class(tree_t t)
905,184✔
1234
{
1235
   return lookup_item(&tree_object, t, I_CLASS)->ival;
905,184✔
1236
}
1237

1238
void tree_set_class(tree_t t, class_t c)
50,258✔
1239
{
1240
   lookup_item(&tree_object, t, I_CLASS)->ival = c;
50,258✔
1241
}
50,258✔
1242

1243
tree_t tree_reject(tree_t t)
2,127✔
1244
{
1245
   item_t *item = lookup_item(&tree_object, t, I_REJECT);
2,127✔
1246
   assert(item->object != NULL);
2,127✔
1247
   return container_of(item->object, struct _tree, object);
2,127✔
1248
}
1249

1250
void tree_set_reject(tree_t t, tree_t r)
673✔
1251
{
1252
   tree_assert_expr(r);
673✔
1253
   lookup_item(&tree_object, t, I_REJECT)->object = &(r->object);
673✔
1254
   object_write_barrier(&(t->object), &(r->object));
673✔
1255
}
673✔
1256

1257
bool tree_has_reject(tree_t t)
25,314✔
1258
{
1259
   return lookup_item(&tree_object, t, I_REJECT)->object != NULL;
25,314✔
1260
}
1261

1262
tree_t tree_guard(tree_t t)
29✔
1263
{
1264
   item_t *item = lookup_item(&tree_object, t, I_GUARD);
29✔
1265
   assert(item->object != NULL);
29✔
1266
   return container_of(item->object, struct _tree, object);
29✔
1267
}
1268

1269
void tree_set_guard(tree_t t, tree_t g)
22✔
1270
{
1271
   assert(g->object.kind == T_GUARD);
22✔
1272
   lookup_item(&tree_object, t, I_GUARD)->object = &(g->object);
22✔
1273
   object_write_barrier(&(t->object), &(g->object));
22✔
1274
}
22✔
1275

1276
bool tree_has_guard(tree_t t)
4,485✔
1277
{
1278
   return lookup_item(&tree_object, t, I_GUARD)->object != NULL;
4,485✔
1279
}
1280

1281
tree_t tree_name(tree_t t)
511,513✔
1282
{
1283
   item_t *item = lookup_item(&tree_object, t, I_NAME);
511,513✔
1284
   assert(item->object != NULL);
511,513✔
1285
   return container_of(item->object, struct _tree, object);
511,513✔
1286
}
1287

1288
void tree_set_name(tree_t t, tree_t n)
39,817✔
1289
{
1290
   tree_assert_expr(n);
39,817✔
1291
   lookup_item(&tree_object, t, I_NAME)->object = &(n->object);
39,817✔
1292
   object_write_barrier(&(t->object), &(n->object));
39,817✔
1293
}
39,817✔
1294

1295
bool tree_has_name(tree_t t)
2,251✔
1296
{
1297
   return lookup_item(&tree_object, t, I_NAME)->object != NULL;
2,251✔
1298
}
1299

1300
tree_t tree_file_mode(tree_t t)
1,108✔
1301
{
1302
   item_t *item = lookup_item(&tree_object, t, I_FILE_MODE);
1,108✔
1303
   return container_of(item->object, struct _tree, object);
1,108✔
1304
}
1305

1306
void tree_set_file_mode(tree_t t, tree_t m)
50✔
1307
{
1308
   lookup_item(&tree_object, t, I_FILE_MODE)->object = &(m->object);
50✔
1309
   object_write_barrier(&(t->object), &(m->object));
50✔
1310
}
50✔
1311

1312
unsigned tree_visit(tree_t t, tree_visit_fn_t fn, void *context)
9,620✔
1313
{
1314
   return tree_visit_only(t, fn, context, T_LAST_TREE_KIND);
9,620✔
1315
}
1316

1317
unsigned tree_visit_only(tree_t t, tree_visit_fn_t fn,
10,815✔
1318
                         void *context, tree_kind_t kind)
1319
{
1320
   assert(t != NULL);
10,815✔
1321

1322
   object_visit_ctx_t ctx = {
10,815✔
1323
      .count      = 0,
1324
      .postorder  = (object_visit_fn_t)fn,
1325
      .preorder   = NULL,
1326
      .context    = context,
1327
      .kind       = kind,
1328
      .tag        = OBJECT_TAG_TREE,
1329
      .generation = object_next_generation(),
10,815✔
1330
      .deep       = false
1331
   };
1332

1333
   object_visit(&(t->object), &ctx);
10,815✔
1334

1335
   return ctx.count;
10,815✔
1336
}
1337

1338
tree_t tree_rewrite(tree_t t, tree_rewrite_pre_fn_t pre_fn,
29,404✔
1339
                    tree_rewrite_post_fn_t tree_post_fn,
1340
                    type_rewrite_post_fn_t type_post_fn,
1341
                    void *context)
1342
{
1343
   object_arena_t *arena = object_arena(&(t->object));
29,404✔
1344
   if (arena_frozen(arena))
29,404✔
1345
      return t;
1346

1347
   object_rewrite_ctx_t ctx = {
29,404✔
1348
      .generation = object_next_generation(),
29,404✔
1349
      .context    = context,
1350
      .arena      = arena,
1351
   };
1352

1353
   ctx.pre_fn[OBJECT_TAG_TREE] = (object_rewrite_pre_fn_t)pre_fn;
29,404✔
1354

1355
   ctx.post_fn[OBJECT_TAG_TREE] = (object_rewrite_post_fn_t)tree_post_fn;
29,404✔
1356
   ctx.post_fn[OBJECT_TAG_TYPE] = (object_rewrite_post_fn_t)type_post_fn;
29,404✔
1357

1358
   object_t *result = object_rewrite(&(t->object), &ctx);
29,404✔
1359
   free(ctx.cache);
29,400✔
1360
   return container_of(result, struct _tree, object);
29,400✔
1361
}
1362

1363
void tree_copy(tree_t *roots, unsigned nroots,
5,776✔
1364
               tree_copy_pred_t tree_pred,
1365
               type_copy_pred_t type_pred,
1366
               void *pred_context,
1367
               tree_copy_fn_t tree_callback,
1368
               type_copy_fn_t type_callback,
1369
               void *callback_context)
1370
{
1371
   object_copy_ctx_t *ctx LOCAL = xcalloc_flex(sizeof(object_copy_ctx_t),
11,552✔
1372
                                               nroots, sizeof(object_t *));
1373

1374
   ctx->generation       = object_next_generation();
5,776✔
1375
   ctx->pred_context     = pred_context;
5,776✔
1376
   ctx->callback_context = callback_context;
5,776✔
1377
   ctx->nroots           = nroots;
5,776✔
1378

1379
   for (unsigned i = 0; i < nroots; i++)
17,415✔
1380
      ctx->roots[i] = &(roots[i]->object);
11,639✔
1381

1382
   ctx->should_copy[OBJECT_TAG_TREE] = (object_copy_pred_t)tree_pred;
5,776✔
1383
   ctx->should_copy[OBJECT_TAG_TYPE] = (object_copy_pred_t)type_pred;
5,776✔
1384

1385
   ctx->callback[OBJECT_TAG_TREE] = (object_copy_fn_t)tree_callback;
5,776✔
1386
   ctx->callback[OBJECT_TAG_TYPE] = (object_copy_fn_t)type_callback;
5,776✔
1387

1388
   object_copy(ctx);
5,776✔
1389

1390
   for (unsigned i = 0; i < nroots; i++)
17,415✔
1391
      roots[i] = container_of(ctx->roots[i], struct _tree, object);
11,639✔
1392
}
5,776✔
1393

1394
const char *tree_kind_str(tree_kind_t t)
187✔
1395
{
1396
   return kind_text_map[t];
187✔
1397
}
1398

UNCOV
1399
object_arena_t *tree_arena(tree_t t)
×
1400
{
UNCOV
1401
   return object_arena(&(t->object));
×
1402
}
1403

1404
bool tree_frozen(tree_t t)
188✔
1405
{
1406
   return arena_frozen(object_arena(&(t->object)));
188✔
1407
}
1408

1409
tree_t tree_container(tree_t t)
54,950✔
1410
{
1411
   object_t *o = arena_root(object_arena(&(t->object)));
54,950✔
1412
   assert(o->tag == OBJECT_TAG_TREE);
54,950✔
1413
   return container_of(o, struct _tree, object);
54,950✔
1414
}
1415

1416
static void tree_deps_cb(object_t *obj, void *ctx)
56,535✔
1417
{
1418
   tree_deps_args_t *args = ctx;
56,535✔
1419
   tree_t t = tree_from_object(obj);
56,535✔
1420
   if (t != NULL)
56,535✔
1421
      (*args->fn)(t, args->context);
56,535✔
1422
}
56,535✔
1423

1424
void tree_walk_deps(tree_t t, tree_deps_fn_t fn, void *ctx)
32,286✔
1425
{
1426
   tree_deps_args_t args = { fn, ctx };
32,286✔
1427
   arena_walk_deps(object_arena(&(t->object)), tree_deps_cb, &args);
32,286✔
1428
}
32,286✔
1429

1430
object_t *tree_to_object(tree_t t)
877,983✔
1431
{
1432
   return t ? &(t->object) : NULL;
877,983✔
1433
}
1434

1435
tree_t tree_from_object(object_t *obj)
323,590✔
1436
{
1437
   if (obj != NULL && obj->tag == OBJECT_TAG_TREE)
323,590✔
1438
      return container_of(obj, struct _tree, object);
1439
   else
1440
      return NULL;
3,715✔
1441
}
1442

1443
tree_global_flags_t tree_global_flags(tree_t t)
53,048✔
1444
{
1445
   return arena_flags(object_arena(&(t->object)));
53,048✔
1446
}
1447

1448
void tree_set_global_flags(tree_t t, tree_global_flags_t flags)
6,809✔
1449
{
1450
   arena_set_flags(object_arena(&(t->object)), flags);
6,809✔
1451
}
6,809✔
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