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

nickg / nvc / 28300252271

27 Jun 2026 08:01PM UTC coverage: 92.287% (+0.04%) from 92.252%
28300252271

push

github

nickg
Resolve hierarchical references to global modules

17 of 18 new or added lines in 2 files covered. (94.44%)

690 existing lines in 13 files now uncovered.

79685 of 86345 relevant lines covered (92.29%)

638988.06 hits per line

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

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

18
#include "util.h"
19
#include "vlog/vlog-node.h"
20
#include "vlog/vlog-number.h"
21
#include "object.h"
22

23
#include <string.h>
24
#include <inttypes.h>
25
#include <stdlib.h>
26

27
STATIC_ASSERT(V_LAST_NODE_KIND < 256);
28

29
static const imask_t has_map[V_LAST_NODE_KIND] = {
30
   // V_MODULE
31
   (I_IDENT | I_PORTS | I_STMTS | I_DECLS | I_IDENT2),
32

33
   // V_PORT_DECL
34
   (I_IDENT | I_SUBKIND | I_IDENT2 | I_REF | I_RANGES | I_TYPE | I_VALUE),
35

36
   // V_REF
37
   (I_IDENT | I_REF),
38

39
   // V_ALWAYS
40
   (I_IDENT | I_SUBKIND | I_STMTS),
41

42
   // V_TIMING
43
   (I_VALUE | I_STMTS),
44

45
   // V_NBASSIGN
46
   (I_TARGET | I_VALUE | I_DELAY),
47

48
   // V_EVENT
49
   (I_SUBKIND | I_VALUE),
50

51
   // V_INITIAL
52
   (I_IDENT | I_STMTS),
53

54
   // V_SEQ_BLOCK
55
   (I_IDENT | I_DECLS | I_STMTS),
56

57
   // V_SYS_TCALL
58
   (I_IDENT | I_PARAMS | I_SUBKIND),
59

60
   // V_STRING
61
   (I_NUMBER),
62

63
   // V_NUMBER
64
   (I_NUMBER),
65

66
   // V_NET_DECL
67
   (I_IDENT | I_SUBKIND | I_TYPE | I_RANGES | I_VALUE),
68

69
   // V_ASSIGN
70
   (I_TARGET | I_VALUE | I_IDENT | I_DELAY | I_PARAMS),
71

72
   // V_DIMENSION
73
   (I_SUBKIND | I_LEFT | I_RIGHT),
74

75
   // V_IF
76
   (I_CONDS),
77

78
   // V_COND
79
   (I_VALUE | I_STMTS),
80

81
   // V_VAR_DECL
82
   (I_IDENT | I_TYPE | I_RANGES | I_VALUE),
83

84
   // V_DELAY_CONTROL
85
   (I_VALUE),
86

87
   // V_BINARY
88
   (I_LEFT | I_RIGHT | I_SUBKIND),
89

90
   // V_BASSIGN
91
   (I_TARGET | I_VALUE | I_DELAY),
92

93
   // V_UNARY
94
   (I_VALUE | I_SUBKIND),
95

96
   // V_GATE_INST
97
   (I_SUBKIND | I_PARAMS | I_IDENT | I_REF | I_TARGET),
98

99
   // V_STRENGTH
100
   (I_SUBKIND),
101

102
   // V_MOD_INST
103
   (I_IDENT | I_PARAMS),
104

105
   // V_BIT_SELECT
106
   (I_VALUE | I_PARAMS),
107

108
   // V_SYS_FCALL
109
   (I_IDENT | I_PARAMS | I_SUBKIND),
110

111
   // V_FOREVER
112
   (I_STMTS),
113

114
   // V_SPECIFY
115
   (I_DECLS),
116

117
   // V_PRIMITIVE
118
   (I_IDENT | I_IDENT2 | I_PORTS | I_DECLS | I_STMTS),
119

120
   // V_UDP_TABLE
121
   (I_IDENT | I_PARAMS | I_SUBKIND | I_STMTS),
122

123
   // V_UDP_ENTRY
124
   (I_PARAMS),
125

126
   // V_DATA_TYPE
127
   (I_SUBKIND | I_RANGES | I_FLAGS),
128

129
   // V_TYPE_DECL
130
   (I_IDENT | I_TYPE),
131

132
   // V_ENUM_DECL
133
   (I_IDENT | I_TYPE | I_RANGES | I_DECLS),
134

135
   // V_ENUM_NAME
136
   (I_IDENT | I_TYPE | I_VALUE),
137

138
   // V_UNION_DECL
139
   (I_IDENT | I_DECLS | I_FLAGS),
140

141
   // V_STRUCT_DECL
142
   (I_IDENT | I_DECLS | I_FLAGS),
143

144
   // V_EVENT_CONTROL
145
   (I_PARAMS),
146

147
   // V_EMPTY
148
   (0),
149

150
   // V_REPEAT
151
   (I_VALUE | I_STMTS),
152

153
   // V_WHILE
154
   (I_VALUE | I_STMTS),
155

156
   // V_DO_WHILE
157
   (I_VALUE | I_STMTS),
158

159
   // V_TASK_DECL
160
   (I_IDENT | I_IDENT2 | I_STMTS | I_DECLS | I_PORTS),
161

162
   // V_FUNC_DECL
163
   (I_IDENT | I_IDENT2 | I_STMTS | I_DECLS | I_TYPE | I_PORTS | I_FLAGS),
164

165
   // V_WAIT
166
   (I_VALUE | I_STMTS),
167

168
   // V_PARAM_DECL
169
   (I_IDENT | I_VALUE | I_TYPE),
170

171
   // V_COND_EXPR
172
   (I_VALUE | I_LEFT | I_RIGHT),
173

174
   // V_REAL
175
   (I_DVAL),
176

177
   // V_CONCAT
178
   (I_PARAMS | I_VALUE),
179

180
   // V_FOR_LOOP
181
   (I_LEFT | I_VALUE | I_RIGHT | I_STMTS),
182

183
   // V_FOR_INIT
184
   (I_DECLS | I_STMTS),
185

186
   // V_FOR_STEP
187
   (I_STMTS),
188

189
   // V_PREFIX
190
   (I_TARGET | I_SUBKIND),
191

192
   // V_POSTFIX
193
   (I_TARGET | I_SUBKIND),
194

195
   // V_LOCALPARAM
196
   (I_IDENT | I_VALUE | I_TYPE),
197

198
   // V_CASE
199
   (I_SUBKIND | I_VALUE | I_STMTS),
200

201
   // V_CASE_ITEM
202
   (I_PARAMS | I_STMTS),
203

204
   // V_INST_LIST
205
   (I_PARAMS | I_STMTS | I_IDENT),
206

207
   // V_PARAM_ASSIGN
208
   (I_IDENT | I_VALUE),
209

210
   // V_INST_BODY
211
   (I_IDENT | I_IDENT2 | I_PORTS | I_STMTS | I_DECLS),
212

213
   // V_PORT_CONN
214
   (I_IDENT | I_VALUE),
215

216
   // V_PART_SELECT
217
   (I_SUBKIND | I_VALUE | I_LEFT | I_RIGHT),
218

219
   // V_IF_GENERATE
220
   (I_CONDS),
221

222
   // V_EVENT_TRIGGER
223
   (I_IDENT),
224

225
   // V_USER_FCALL
226
   (I_IDENT | I_REF | I_PARAMS),
227

228
   // V_UDP_LEVEL
229
   (I_SUBKIND | I_IVAL),
230

231
   // V_UDP_EDGE
232
   (I_SUBKIND | I_LEFT | I_RIGHT),
233

234
   // V_SPECPARAM
235
   (I_IDENT | I_VALUE),
236

237
   // V_FORK
238
   (I_IDENT | I_DECLS | I_STMTS),
239

240
   // V_ATTR_INST
241
   (0),
242

243
   // V_USER_TCALL
244
   (I_IDENT | I_REF | I_PARAMS),
245

246
   // V_VOID_CALL
247
   (I_VALUE),
248

249
   // V_GENVAR_DECL
250
   (I_IDENT | I_TYPE),
251

252
   // V_FOR_GENERATE
253
   (I_LEFT | I_VALUE | I_RIGHT | I_STMTS),
254

255
   // V_DEASSIGN
256
   (I_TARGET),
257

258
   // V_FORCE
259
   (I_TARGET | I_VALUE),
260

261
   // V_RELEASE
262
   (I_TARGET | I_VALUE),
263

264
   // V_DISABLE
265
   (I_IDENT),
266

267
   // V_HIER_REF
268
   (I_IDENT | I_VALUE | I_REF),
269

270
   // V_TF_PORT_DECL
271
   (I_IDENT | I_SUBKIND | I_RANGES | I_TYPE | I_VALUE | I_REF),
272

273
   // V_RETURN
274
   (I_REF | I_VALUE),
275

276
   // V_OP_ASSIGN
277
   (I_TARGET | I_SUBKIND | I_VALUE),
278

279
   // V_MEMBER_REF
280
   (I_VALUE | I_IDENT | I_REF),
281

282
   // V_PACKAGE
283
   (I_DECLS | I_IDENT | I_IDENT2),
284

285
   // V_MIN_TYP_MAX
286
   (I_LEFT | I_VALUE | I_RIGHT),
287

288
   // V_PROGRAM
289
   (I_IDENT | I_STMTS | I_DECLS | I_IDENT2),
290

291
   // V_CLASS_DECL
292
   (I_IDENT | I_IDENT2 | I_DECLS),
293

294
   // V_NULL
295
   (I_TYPE),
296

297
   // V_CLASS_NEW
298
   (I_TYPE | I_PARAMS),
299

300
   // V_DYNAMIC_NEW
301
   (I_TYPE | I_VALUE),
302

303
   // V_CONSTRUCTOR
304
   (I_IDENT | I_PARAMS | I_STMTS | I_DECLS),
305

306
   // V_SUPER_CALL
307
   (I_PARAMS),
308

309
   // V_IMPORT_DECL
310
   (I_REF | I_IDENT),
311

312
   // V_NAMESPACE
313
   (I_DECLS | I_IDENT),
314

315
   // V_DEFPARAM
316
   (I_TARGET | I_VALUE),
317

318
   // V_PORT_MAP
319
   (I_REF | I_VALUE),
320

321
   // V_FINAL
322
   (I_IDENT | I_STMTS),
323

324
   // V_LOCAL_DECL
325
   (I_IDENT | I_TYPE | I_RANGES | I_VALUE),
326

327
   // V_GEN_BLOCK
328
   (I_IDENT | I_DECLS | I_STMTS),
329

330
   // V_METHOD_CALL
331
   (I_IDENT | I_VALUE | I_REF | I_SUBKIND | I_PARAMS),
332

333
   // V_MOD_REF
334
   (I_IDENT | I_PARAMS | I_VALUE | I_REF),
335
};
336

337
static const char *kind_text_map[V_LAST_NODE_KIND] = {
338
   "V_MODULE",        "V_PORT_DECL",   "V_REF",           "V_ALWAYS",
339
   "V_TIMING",        "V_NBASSIGN",    "V_EVENT",         "V_INITIAL",
340
   "V_SEQ_BLOCK",     "V_SYS_TCALL",   "V_STRING",        "V_NUMBER",
341
   "V_NET_DECL",      "V_ASSIGN",      "V_DIMENSION",     "V_IF",
342
   "V_COND",          "V_VAR_DECL",    "V_DELAY_CONTROL", "V_BINARY",
343
   "V_BASSIGN",       "V_UNARY",       "V_GATE_INST",     "V_STRENGTH",
344
   "V_MOD_INST",      "V_BIT_SELECT",  "V_SYS_FCALL",     "V_FOREVER",
345
   "V_SPECIFY",       "V_PRIMITIVE",   "V_UDP_TABLE",     "V_UDP_ENTRY",
346
   "V_DATA_TYPE",     "V_TYPE_DECL",   "V_ENUM_DECL",     "V_ENUM_NAME",
347
   "V_UNION_DECL",    "V_STRUCT_DECL", "V_EVENT_CONTROL", "V_EMPTY",
348
   "V_REPEAT",        "V_WHILE",       "V_DO_WHILE",      "V_TASK_DECL",
349
   "V_FUNC_DECL",     "V_WAIT",        "V_PARAM_DECL",    "V_COND_EXPR",
350
   "V_REAL",          "V_CONCAT",      "V_FOR_LOOP",      "V_FOR_INIT",
351
   "V_FOR_STEP",      "V_PREFIX",      "V_POSTFIX",       "V_LOCALPARAM",
352
   "V_CASE",          "V_CASE_ITEM",   "V_INST_LIST",     "V_PARAM_ASSIGN",
353
   "V_INST_BODY",     "V_PORT_CONN",   "V_PART_SELECT",   "V_IF_GENERATE",
354
   "V_EVENT_TRIGGER", "V_USER_FCALL",  "V_UDP_LEVEL",     "V_UDP_EDGE",
355
   "V_SPECPARAM",     "V_FORK",        "V_ATTR_INST",     "V_USER_TCALL",
356
   "V_VOID_CALL",     "V_GENVAR_DECL", "V_FOR_GENERATE",  "V_DEASSIGN",
357
   "V_FORCE",         "V_RELEASE",     "V_DISABLE",       "V_HIER_REF",
358
   "V_TF_PORT_DECL",  "V_RETURN",      "V_OP_ASSIGN",     "V_MEMBER_REF",
359
   "V_PACKAGE",       "V_MIN_TYP_MAX", "V_PROGRAM",       "V_CLASS_DECL",
360
   "V_NULL",          "V_CLASS_NEW",   "V_DYNAMIC_NEW",   "V_CONSTRUCTOR",
361
   "V_SUPER_CALL",    "V_IMPORT_DECL", "V_NAMESPACE",     "V_DEFPARAM",
362
   "V_PORT_MAP",      "V_FINAL",       "V_LOCAL_DECL",    "V_GEN_BLOCK",
363
   "V_METHOD_CALL",   "V_MOD_REF",
364
};
365

366
static const change_allowed_t change_allowed[] = {
367
   { -1, -1 }
368
};
369

370
object_class_t vlog_object = {
371
   .name           = "vlog",
372
   .change_allowed = change_allowed,
373
   .has_map        = has_map,
374
   .kind_text_map  = kind_text_map,
375
   .tag            = OBJECT_TAG_VLOG,
376
   .last_kind      = V_LAST_NODE_KIND,
377
   .has_loc        = true,
378
   .gc_roots       = { V_MODULE, V_PRIMITIVE, V_PROGRAM, V_PACKAGE,
379
                       V_NAMESPACE },
380
   .gc_num_roots   = 5,
381
};
382

383
struct _vlog_node {
384
   object_t object;
385
};
386

387
static inline vlog_node_t vlog_array_nth(item_t *item, unsigned n)
298,624✔
388
{
389
   object_t *o = obj_array_nth(item->obj_array, n);
298,624✔
390
   return container_of(o, struct _vlog_node, object);
298,624✔
391
}
392

393
static inline void vlog_array_add(item_t *item, vlog_node_t v)
93,312✔
394
{
395
   obj_array_add(&(item->obj_array), &(v->object));
93,312✔
396
}
93,312✔
397

398
vlog_node_t vlog_new(vlog_kind_t kind)
245,471✔
399
{
400
   object_t *o = object_new(NULL, &vlog_object, kind);
245,471✔
401
   return container_of(o, struct _vlog_node, object);
245,471✔
402
}
403

404
vlog_kind_t vlog_kind(vlog_node_t v)
2,104,144✔
405
{
406
   return v->object.kind;
2,104,144✔
407
}
408

UNCOV
409
const char *vlog_kind_str(vlog_kind_t kind)
×
410
{
UNCOV
411
   return kind_text_map[kind];
×
412
}
413

414
ident_t vlog_ident(vlog_node_t v)
157,750✔
415
{
416
   item_t *item = lookup_item(&vlog_object, v, I_IDENT);
157,750✔
417
   assert(item->ident != NULL);
157,750✔
418
   return item->ident;
157,750✔
419
}
420

421
void vlog_set_ident(vlog_node_t v, ident_t i)
80,963✔
422
{
423
   lookup_item(&vlog_object, v, I_IDENT)->ident = i;
80,963✔
424
}
80,963✔
425

426
bool vlog_has_ident(vlog_node_t v)
1,559✔
427
{
428
   return lookup_item(&vlog_object, v, I_IDENT)->ident != NULL;
1,559✔
429
}
430

431
ident_t vlog_ident2(vlog_node_t v)
4,286✔
432
{
433
   item_t *item = lookup_item(&vlog_object, v, I_IDENT2);
4,286✔
434
   assert(item->ident != NULL);
4,286✔
435
   return item->ident;
4,286✔
436
}
437

438
bool vlog_has_ident2(vlog_node_t v)
1✔
439
{
440
   return lookup_item(&vlog_object, v, I_IDENT2)->ident != NULL;
1✔
441
}
442

443
void vlog_set_ident2(vlog_node_t v, ident_t i)
3,354✔
444
{
445
   lookup_item(&vlog_object, v, I_IDENT2)->ident = i;
3,354✔
446
}
3,354✔
447

448
const loc_t *vlog_loc(vlog_node_t v)
285,263✔
449
{
450
   assert(v != NULL);
285,263✔
451
   return &(v->object.loc);
285,263✔
452
}
453

454
void vlog_set_loc(vlog_node_t v, const loc_t *loc)
263,018✔
455
{
456
   assert(v != NULL);
263,018✔
457
   assert(loc != NULL);
263,018✔
458
   v->object.loc = *loc;
263,018✔
459
}
263,018✔
460

461
vlog_node_t vlog_ref(vlog_node_t v)
260,337✔
462
{
463
   item_t *item = lookup_item(&vlog_object, v, I_REF);
260,337✔
464
   assert(item->object != NULL);
260,337✔
465
   return container_of(item->object, struct _vlog_node, object);
260,337✔
466
}
467

468
bool vlog_has_ref(vlog_node_t v)
66,432✔
469
{
470
   return lookup_item(&vlog_object, v, I_REF)->object != NULL;
66,432✔
471
}
472

473
void vlog_set_ref(vlog_node_t v, vlog_node_t d)
52,471✔
474
{
475
   object_t *d_obj = vlog_to_object(d);
52,471✔
476
   lookup_item(&vlog_object, v, I_REF)->object = d_obj;
52,471✔
477
   object_write_barrier(&(v->object), d_obj);
52,471✔
478
}
52,471✔
479

480
unsigned vlog_stmts(vlog_node_t v)
40,875✔
481
{
482
   item_t *item = lookup_item(&vlog_object, v, I_STMTS);
40,875✔
483
   return obj_array_count(item->obj_array);
40,875✔
484
}
485

486
vlog_node_t vlog_stmt(vlog_node_t v, unsigned n)
89,854✔
487
{
488
   item_t *item = lookup_item(&vlog_object, v, I_STMTS);
89,854✔
489
   return vlog_array_nth(item, n);
89,854✔
490
}
491

492
void vlog_add_stmt(vlog_node_t v, vlog_node_t s)
43,495✔
493
{
494
   assert(s != NULL);
43,495✔
495
   vlog_array_add(lookup_item(&vlog_object, v, I_STMTS), s);
43,495✔
496
   object_write_barrier(&(v->object), &(s->object));
43,495✔
497
}
43,495✔
498

499
unsigned vlog_ports(vlog_node_t v)
11,949✔
500
{
501
   item_t *item = lookup_item(&vlog_object, v, I_PORTS);
11,949✔
502
   return obj_array_count(item->obj_array);
11,949✔
503
}
504

505
vlog_node_t vlog_port(vlog_node_t v, unsigned n)
16,961✔
506
{
507
   item_t *item = lookup_item(&vlog_object, v, I_PORTS);
16,961✔
508
   return vlog_array_nth(item, n);
16,961✔
509
}
510

511
void vlog_add_port(vlog_node_t v, vlog_node_t p)
1,749✔
512
{
513
   assert(p != NULL);
1,749✔
514
   assert(p->object.kind == V_REF || p->object.kind == V_PORT_DECL
1,749✔
515
          || p->object.kind == V_TF_PORT_DECL);
516
   vlog_array_add(lookup_item(&vlog_object, v, I_PORTS), p);
1,749✔
517
   object_write_barrier(&(v->object), &(p->object));
1,749✔
518
}
1,749✔
519

520
unsigned vlog_params(vlog_node_t v)
51,321✔
521
{
522
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
51,321✔
523
   return obj_array_count(item->obj_array);
51,321✔
524
}
525

526
vlog_node_t vlog_param(vlog_node_t v, unsigned n)
60,423✔
527
{
528
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
60,423✔
529
   return vlog_array_nth(item, n);
60,423✔
530
}
531

532
void vlog_add_param(vlog_node_t v, vlog_node_t p)
22,225✔
533
{
534
   assert(p != NULL);
22,225✔
535
   vlog_array_add(lookup_item(&vlog_object, v, I_PARAMS), p);
22,225✔
536
   object_write_barrier(&(v->object), &(p->object));
22,225✔
537
}
22,225✔
538

539
void vlog_set_param(vlog_node_t v, unsigned n, vlog_node_t p)
×
540
{
541
   assert(p != NULL);
×
UNCOV
542
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
×
UNCOV
543
   assert(n < obj_array_count(item->obj_array));
×
UNCOV
544
   item->obj_array->items[n] = vlog_to_object(p);
×
UNCOV
545
   object_write_barrier(&(v->object), &(p->object));
×
UNCOV
546
}
×
547

548
unsigned vlog_ranges(vlog_node_t v)
85,956✔
549
{
550
   item_t *item = lookup_item(&vlog_object, v, I_RANGES);
85,956✔
551
   return obj_array_count(item->obj_array);
85,956✔
552
}
553

554
vlog_node_t vlog_range(vlog_node_t v, unsigned n)
50,258✔
555
{
556
   item_t *item = lookup_item(&vlog_object, v, I_RANGES);
50,258✔
557
   return vlog_array_nth(item, n);
50,258✔
558
}
559

560
void vlog_add_range(vlog_node_t v, vlog_node_t r)
5,454✔
561
{
562
   assert(r != NULL);
5,454✔
563
   assert(r->object.kind == V_DIMENSION);
5,454✔
564
   vlog_array_add(lookup_item(&vlog_object, v, I_RANGES), r);
5,454✔
565
   object_write_barrier(&(v->object), &(r->object));
5,454✔
566
}
5,454✔
567

568
unsigned vlog_decls(vlog_node_t v)
18,663✔
569
{
570
   item_t *item = lookup_item(&vlog_object, v, I_DECLS);
18,663✔
571
   return obj_array_count(item->obj_array);
18,663✔
572
}
573

574
vlog_node_t vlog_decl(vlog_node_t v, unsigned n)
73,016✔
575
{
576
   item_t *item = lookup_item(&vlog_object, v, I_DECLS);
73,016✔
577
   return vlog_array_nth(item, n);
73,016✔
578
}
579

580
void vlog_add_decl(vlog_node_t v, vlog_node_t d)
16,340✔
581
{
582
   assert(d != NULL);
16,340✔
583
   vlog_array_add(lookup_item(&vlog_object, v, I_DECLS), d);
16,340✔
584
   object_write_barrier(&(v->object), &(d->object));
16,340✔
585
}
16,340✔
586

587
unsigned vlog_conds(vlog_node_t v)
7,049✔
588
{
589
   item_t *item = lookup_item(&vlog_object, v, I_CONDS);
7,049✔
590
   return obj_array_count(item->obj_array);
7,049✔
591
}
592

593
vlog_node_t vlog_cond(vlog_node_t v, unsigned n)
8,112✔
594
{
595
   item_t *item = lookup_item(&vlog_object, v, I_CONDS);
8,112✔
596
   return vlog_array_nth(item, n);
8,112✔
597
}
598

599
void vlog_add_cond(vlog_node_t v, vlog_node_t c)
4,049✔
600
{
601
   assert(c != NULL && c->object.kind == V_COND);
4,049✔
602
   vlog_array_add(lookup_item(&vlog_object, v, I_CONDS), c);
4,049✔
603
   object_write_barrier(&(v->object), &(c->object));
4,049✔
604
}
4,049✔
605

606
unsigned vlog_subkind(vlog_node_t v)
294,575✔
607
{
608
   return lookup_item(&vlog_object, v, I_SUBKIND)->ival;
294,575✔
609
}
610

611
void vlog_set_subkind(vlog_node_t v, unsigned sub)
74,109✔
612
{
613
   lookup_item(&vlog_object, v, I_SUBKIND)->ival = sub;
74,109✔
614
}
74,109✔
615

616
vlog_node_t vlog_value(vlog_node_t v)
133,794✔
617
{
618
   item_t *item = lookup_item(&vlog_object, v, I_VALUE);
133,794✔
619
   assert(item->object != NULL);
133,794✔
620
   return container_of(item->object, struct _vlog_node, object);
133,794✔
621
}
622

623
bool vlog_has_value(vlog_node_t v)
29,036✔
624
{
625
   return lookup_item(&vlog_object, v, I_VALUE)->object != NULL;
29,036✔
626
}
627

628
void vlog_set_value(vlog_node_t v, vlog_node_t e)
48,578✔
629
{
630
   lookup_item(&vlog_object, v, I_VALUE)->object = &(e->object);
48,578✔
631
   object_write_barrier(&(v->object), &(e->object));
48,578✔
632
}
48,578✔
633

634
vlog_node_t vlog_target(vlog_node_t v)
28,786✔
635
{
636
   item_t *item = lookup_item(&vlog_object, v, I_TARGET);
28,786✔
637
   assert(item->object != NULL);
28,786✔
638
   return container_of(item->object, struct _vlog_node, object);
28,786✔
639
}
640

641
void vlog_set_target(vlog_node_t v, vlog_node_t e)
14,205✔
642
{
643
   lookup_item(&vlog_object, v, I_TARGET)->object = &(e->object);
14,205✔
644
   object_write_barrier(&(v->object), &(e->object));
14,205✔
645
}
14,205✔
646

647
vlog_node_t vlog_delay(vlog_node_t v)
114✔
648
{
649
   item_t *item = lookup_item(&vlog_object, v, I_DELAY);
114✔
650
   assert(item->object != NULL);
114✔
651
   return container_of(item->object, struct _vlog_node, object);
114✔
652
}
653

654
bool vlog_has_delay(vlog_node_t v)
13,727✔
655
{
656
   return lookup_item(&vlog_object, v, I_DELAY)->object != NULL;
13,727✔
657
}
658

659
void vlog_set_delay(vlog_node_t v, vlog_node_t d)
805✔
660
{
661
   object_t *d_obj = vlog_to_object(d);
805✔
662
   lookup_item(&vlog_object, v, I_DELAY)->object = d_obj;
805✔
663
   object_write_barrier(&(v->object), d_obj);
805✔
664
}
805✔
665

666
vlog_node_t vlog_type(vlog_node_t v)
158,259✔
667
{
668
   item_t *item = lookup_item(&vlog_object, v, I_TYPE);
158,259✔
669
   assert(item->object != NULL);
158,259✔
670
   return container_of(item->object, struct _vlog_node, object);
158,259✔
671
}
672

673
bool vlog_has_type(vlog_node_t v)
1✔
674
{
675
   return lookup_item(&vlog_object, v, I_TYPE)->object != NULL;
1✔
676
}
677

678
void vlog_set_type(vlog_node_t v, vlog_node_t t)
9,608✔
679
{
680
   object_t *t_obj = vlog_to_object(t);
9,608✔
681
   lookup_item(&vlog_object, v, I_TYPE)->object = t_obj;
9,608✔
682
   object_write_barrier(&(v->object), t_obj);
9,608✔
683
}
9,608✔
684

685
number_t vlog_number(vlog_node_t v)
191,227✔
686
{
687
   return lookup_item(&vlog_object, v, I_NUMBER)->number;
191,227✔
688
}
689

690
void vlog_set_number(vlog_node_t v, number_t n)
65,834✔
691
{
692
   lookup_item(&vlog_object, v, I_NUMBER)->number = n;
65,834✔
693
}
65,834✔
694

695
vlog_node_t vlog_left(vlog_node_t v)
178,247✔
696
{
697
   item_t *item = lookup_item(&vlog_object, v, I_LEFT);
178,247✔
698
   assert(item->object != NULL);
178,247✔
699
   return container_of(item->object, struct _vlog_node, object);
178,247✔
700
}
701

702
void vlog_set_left(vlog_node_t v, vlog_node_t e)
41,707✔
703
{
704
   lookup_item(&vlog_object, v, I_LEFT)->object = &(e->object);
41,707✔
705
   object_write_barrier(&(v->object), &(e->object));
41,707✔
706
}
41,707✔
707

708
vlog_node_t vlog_right(vlog_node_t v)
178,051✔
709
{
710
   item_t *item = lookup_item(&vlog_object, v, I_RIGHT);
178,051✔
711
   assert(item->object != NULL);
178,051✔
712
   return container_of(item->object, struct _vlog_node, object);
178,051✔
713
}
714

715
void vlog_set_right(vlog_node_t v, vlog_node_t e)
41,699✔
716
{
717
   lookup_item(&vlog_object, v, I_RIGHT)->object = &(e->object);
41,699✔
718
   object_write_barrier(&(v->object), &(e->object));
41,699✔
719
}
41,699✔
720

721
double vlog_dval(vlog_node_t v)
825✔
722
{
723
   return lookup_item(&vlog_object, v, I_DVAL)->dval;
825✔
724
}
725

726
void vlog_set_dval(vlog_node_t v, double d)
571✔
727
{
728
   lookup_item(&vlog_object, v, I_DVAL)->dval = d;
571✔
729
}
571✔
730

731
int64_t vlog_ival(vlog_node_t v)
780✔
732
{
733
   return lookup_item(&vlog_object, v, I_IVAL)->ival;
780✔
734
}
735

736
void vlog_set_ival(vlog_node_t v, int64_t i)
729✔
737
{
738
   lookup_item(&vlog_object, v, I_IVAL)->ival = i;
729✔
739
}
729✔
740

741
vlog_flags_t vlog_flags(vlog_node_t t)
33,222✔
742
{
743
   return lookup_item(&vlog_object, t, I_FLAGS)->ival;
33,222✔
744
}
745

746
void vlog_set_flags(vlog_node_t v, vlog_flags_t mask)
1,247✔
747
{
748
   lookup_item(&vlog_object, v, I_FLAGS)->ival |= mask;
1,247✔
749
}
1,247✔
750

751
void vlog_clear_flags(vlog_node_t v, vlog_flags_t mask)
34✔
752
{
753
   lookup_item(&vlog_object, v, I_FLAGS)->ival &= ~mask;
34✔
754
}
34✔
755

756
void vlog_visit(vlog_node_t v, vlog_visit_fn_t fn, void *context)
227✔
757
{
758
   vlog_visit_only(v, fn, context, V_LAST_NODE_KIND);
227✔
759
}
227✔
760

761
void vlog_visit_only(vlog_node_t v, vlog_visit_fn_t fn, void *context,
227✔
762
                     vlog_kind_t kind)
763
{
764
   assert(v != NULL);
227✔
765

766
   object_visit_ctx_t ctx = {
227✔
767
      .count      = 0,
768
      .postorder  = (object_visit_fn_t)fn,
769
      .preorder   = NULL,
770
      .context    = context,
771
      .kind       = kind,
772
      .tag        = OBJECT_TAG_VLOG,
773
      .generation = object_next_generation(),
227✔
774
      .deep       = false
775
   };
776

777
   object_visit(&(v->object), &ctx);
227✔
778
}
227✔
779

780
vlog_node_t vlog_rewrite(vlog_node_t v, vlog_rewrite_pre_fn_t pre_fn,
4,728✔
781
                         vlog_rewrite_post_fn_t post_fn, void *context)
782
{
783
   object_arena_t *arena = object_arena(&(v->object));
4,728✔
784
   if (arena_frozen(arena))
4,728✔
785
      return v;
786

787
   object_rewrite_ctx_t ctx = {
4,728✔
788
      .generation = object_next_generation(),
4,728✔
789
      .context    = context,
790
      .arena      = arena,
791
   };
792

793
   ctx.pre_fn[OBJECT_TAG_VLOG] = (object_rewrite_pre_fn_t)pre_fn;
4,728✔
794
   ctx.post_fn[OBJECT_TAG_VLOG] = (object_rewrite_post_fn_t)post_fn;
4,728✔
795

796
   object_t *result = object_rewrite(&(v->object), &ctx);
4,728✔
797
   free(ctx.cache);
4,728✔
798
   return container_of(result, struct _vlog_node, object);
4,728✔
799
}
800

801
vlog_node_t vlog_copy(vlog_node_t v, vlog_copy_pred_t pred, void *ctx)
1,275✔
802
{
803
   object_copy_ctx_t *copy LOCAL = xcalloc_flex(sizeof(object_copy_ctx_t),
1,275✔
804
                                                1, sizeof(object_t *));
805
   copy->generation   = object_next_generation();
1,275✔
806
   copy->pred_context = ctx;
1,275✔
807
   copy->nroots       = 1;
1,275✔
808
   copy->roots[0]     = &(v->object);
1,275✔
809

810
   copy->should_copy[OBJECT_TAG_VLOG] = (object_copy_pred_t)pred;
1,275✔
811

812
   object_copy_begin(copy);
1,275✔
813
   object_copy_finish(copy);
1,275✔
814

815
   return container_of(copy->roots[0], struct _vlog_node, object);
1,275✔
816
}
817

818
object_t *vlog_to_object(vlog_node_t v)
82,741✔
819
{
820
   return v != NULL ? &(v->object) : NULL;
82,741✔
821
}
822

823
vlog_node_t vlog_from_object(object_t *obj)
38,253✔
824
{
825
   if (obj != NULL && obj->tag == OBJECT_TAG_VLOG)
38,253✔
826
      return container_of(obj, struct _vlog_node, object);
827
   else
828
      return NULL;
28,148✔
829
}
830

831
vlog_global_flags_t vlog_global_flags(vlog_node_t v)
1,059✔
832
{
833
   return arena_flags(object_arena(&(v->object)));
1,059✔
834
}
835

836
void vlog_set_global_flags(vlog_node_t v, vlog_global_flags_t flags)
31✔
837
{
838
   arena_set_flags(object_arena(&(v->object)), flags);
31✔
839
}
31✔
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