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

nickg / nvc / 19789834065

29 Nov 2025 09:53PM UTC coverage: 92.566% (-0.009%) from 92.575%
19789834065

push

github

nickg
Avoid code generation for processes in cloned blocks

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

595 existing lines in 10 files now uncovered.

75316 of 81365 relevant lines covered (92.57%)

421911.4 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,311✔
512
                             const char *what)
513
{
514
   for (size_t i = 0; i < len; i++) {
4,744,530✔
515
      if (t->object.kind == list[i])
4,744,530✔
516
         return;
395,311✔
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,157✔
526
{
527
   tree_assert_kind(t, expr_kinds, ARRAY_LEN(expr_kinds), "an expression");
149,157✔
528
}
149,157✔
529

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

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

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

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

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

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

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

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

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

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

579
ident_t tree_ident(tree_t t)
29,714,721✔
580
{
581
   item_t *item = lookup_item(&tree_object, t, I_IDENT);
29,714,721✔
582
   assert(item->ident != NULL);
29,714,721✔
583
   return item->ident;
29,714,721✔
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,147✔
592
{
593
   lookup_item(&tree_object, t, I_IDENT)->ident = i;
1,210,147✔
594
}
1,210,147✔
595

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

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

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

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

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

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

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

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

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

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

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

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

665
tree_t tree_generic(tree_t t, unsigned n)
56,384✔
666
{
667
   item_t *item = lookup_item(&tree_object, t, I_GENERICS);
56,384✔
668
   return tree_array_nth(item, n);
56,384✔
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,860,516✔
684
{
685
   item_t *item = lookup_item(&tree_object, t, I_TYPE);
33,860,516✔
686
   assert(item->object != NULL);
33,860,516✔
687
   return container_of(item->object, struct _type, object);
33,860,516✔
688
}
689

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

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

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

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

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

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

727
tree_t tree_genmap(tree_t t, unsigned n)
44,932✔
728
{
729
   item_t *item = lookup_item(&tree_object, t, I_GENMAPS);
44,932✔
730
   return tree_array_nth(item, n);
44,932✔
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,103,328✔
747
{
748
   return lookup_item(&tree_object, t, I_IVAL)->ival;
3,103,328✔
749
}
750

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

756
double tree_dval(tree_t t)
282,706✔
757
{
758
   return lookup_item(&tree_object, t, I_DVAL)->dval;
282,706✔
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,072,884✔
767
{
768
   return lookup_item(&tree_object, t, I_FLAGS)->ival;
18,072,884✔
769
}
770

771
void tree_set_flag(tree_t t, tree_flags_t mask)
160,287✔
772
{
773
   lookup_item(&tree_object, t, I_FLAGS)->ival |= mask;
160,287✔
774
}
160,287✔
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,169✔
782
{
783
   item_t *item = lookup_item(&tree_object, t, I_PRIMARY);
65,169✔
784
   assert(item->object != NULL);
65,169✔
785
   return container_of(item->object, struct _tree, object);
65,169✔
786
}
787

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

793
void tree_set_primary(tree_t t, tree_t unit)
6,318✔
794
{
795
   lookup_item(&tree_object, t, I_PRIMARY)->object = &(unit->object);
6,318✔
796
   object_write_barrier(&(t->object), &(unit->object));
6,318✔
797
}
6,318✔
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,240,350✔
869
{
870
   return lookup_item(&tree_object, t, I_VALUE)->object != NULL;
3,240,350✔
871
}
872

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

880
void tree_set_value(tree_t t, tree_t v)
392,344✔
881
{
882
   object_t *obj = v ? &(v->object) : NULL;
392,344✔
883
   lookup_item(&tree_object, t, I_VALUE)->object = obj;
392,344✔
884
   object_write_barrier(&(t->object), obj);
392,344✔
885
}
392,344✔
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,335✔
907
{
908
   item_t *item = lookup_item(&tree_object, t, I_DECLS);
139,335✔
909
   return obj_array_count(item->obj_array);
139,335✔
910
}
911

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1055
void tree_set_ref(tree_t t, tree_t decl)
1,095,201✔
1056
{
1057
   object_t *obj = decl ? &(decl->object) : NULL;
1,095,201✔
1058
   lookup_item(&tree_object, t, I_REF)->object = obj;
1,095,201✔
1059
   object_write_barrier(&(t->object), obj);
1,095,201✔
1060
}
1,095,201✔
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,493✔
1070
{
1071
   return lookup_item(&tree_object, t, I_SPEC)->object != NULL;
16,493✔
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,194✔
1082
{
1083
   item_t *item = lookup_item(&tree_object, t, I_CONTEXT);
29,194✔
1084
   return obj_array_count(item->obj_array);
29,194✔
1085
}
1086

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

1093
void tree_add_context(tree_t t, tree_t ctx)
42,861✔
1094
{
1095
   assert(ctx->object.kind == T_USE || ctx->object.kind == T_LIBRARY
42,861✔
1096
          || ctx->object.kind == T_CONTEXT_REF);
1097
   tree_array_add(lookup_item(&tree_object, t, I_CONTEXT), ctx);
42,861✔
1098
   object_write_barrier(&(t->object), &(ctx->object));
42,861✔
1099
}
42,861✔
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)
208,986✔
1121
{
1122
   item_t *item = lookup_item(&tree_object, t, I_ASSOCS);
208,986✔
1123
   return obj_array_count(item->obj_array);
208,986✔
1124
}
1125

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

1132
void tree_add_assoc(tree_t t, tree_t a)
48,879✔
1133
{
1134
   assert(a->object.kind == T_ASSOC);
48,879✔
1135
   tree_array_add(lookup_item(&tree_object, t, I_ASSOCS), a);
48,879✔
1136
   object_write_barrier(&(t->object), &(a->object));
48,879✔
1137
}
48,879✔
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,951✔
1154
{
1155
   return lookup_item(&tree_object, t, I_SEVERITY)->object != NULL;
35,951✔
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,654✔
1166
{
1167
   return lookup_item(&tree_object, t, I_MESSAGE)->object != NULL;
48,654✔
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,907✔
1178
{
1179
   tree_array_add(lookup_item(&tree_object, t, I_RANGES), r);
49,907✔
1180
   object_write_barrier(&(t->object), &(r->object));
49,907✔
1181
}
49,907✔
1182

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

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

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

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

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

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

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

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

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

1238
void tree_set_class(tree_t t, class_t c)
50,243✔
1239
{
1240
   lookup_item(&tree_object, t, I_CLASS)->ival = c;
50,243✔
1241
}
50,243✔
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,284✔
1258
{
1259
   return lookup_item(&tree_object, t, I_REJECT)->object != NULL;
25,284✔
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,479✔
1277
{
1278
   return lookup_item(&tree_object, t, I_GUARD)->object != NULL;
4,479✔
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,611✔
1313
{
1314
   return tree_visit_only(t, fn, context, T_LAST_TREE_KIND);
9,611✔
1315
}
1316

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

1322
   object_visit_ctx_t ctx = {
10,806✔
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,806✔
1330
      .deep       = false
1331
   };
1332

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

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

1338
tree_t tree_rewrite(tree_t t, tree_rewrite_pre_fn_t pre_fn,
29,374✔
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,374✔
1344
   if (arena_frozen(arena))
29,374✔
1345
      return t;
1346

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

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

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

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

1363
void tree_copy(tree_t *roots, unsigned nroots,
5,770✔
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,540✔
1372
                                               nroots, sizeof(object_t *));
1373

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

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

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

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

1388
   object_copy(ctx);
5,770✔
1389

1390
   for (unsigned i = 0; i < nroots; i++)
17,397✔
1391
      roots[i] = container_of(ctx->roots[i], struct _tree, object);
11,627✔
1392
}
5,770✔
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)
100,682✔
1417
{
1418
   tree_deps_args_t *args = ctx;
100,682✔
1419
   tree_t t = tree_from_object(obj);
100,682✔
1420
   if (t != NULL)
100,682✔
1421
      (*args->fn)(t, args->context);
100,623✔
1422
}
100,682✔
1423

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

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

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

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

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