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

nickg / nvc / 24238351848

10 Apr 2026 10:22AM UTC coverage: 92.348% (+0.01%) from 92.338%
24238351848

Pull #1488

github

web-flow
Merge 198926fb5 into e00449bb3
Pull Request #1488: Verilog: implement $info, $warning, $error and fix $fatal format strings

1156 of 1216 new or added lines in 23 files covered. (95.07%)

1443 existing lines in 24 files now uncovered.

76369 of 82697 relevant lines covered (92.35%)

609386.16 hits per line

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

97.84
/src/vlog/vlog-node.c
1
//
2
//  Copyright (C) 2022-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 "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 const imask_t has_map[V_LAST_NODE_KIND] = {
28
   // V_MODULE
29
   (I_IDENT | I_PORTS | I_STMTS | I_DECLS | I_IDENT2),
30

31
   // V_PORT_DECL
32
   (I_IDENT | I_SUBKIND | I_IDENT2 | I_REF | I_RANGES | I_TYPE | I_VALUE),
33

34
   // V_REF
35
   (I_IDENT | I_REF),
36

37
   // V_ALWAYS
38
   (I_IDENT | I_SUBKIND | I_STMTS),
39

40
   // V_TIMING
41
   (I_VALUE | I_STMTS),
42

43
   // V_NBASSIGN
44
   (I_TARGET | I_VALUE | I_DELAY),
45

46
   // V_EVENT
47
   (I_SUBKIND | I_VALUE),
48

49
   // V_INITIAL
50
   (I_IDENT | I_STMTS),
51

52
   // V_BLOCK
53
   (I_IDENT | I_DECLS | I_STMTS),
54

55
   // V_SYS_TCALL
56
   (I_IDENT | I_PARAMS),
57

58
   // V_STRING
59
   (I_NUMBER),
60

61
   // V_NUMBER
62
   (I_NUMBER),
63

64
   // V_NET_DECL
65
   (I_IDENT | I_SUBKIND | I_TYPE | I_RANGES | I_VALUE),
66

67
   // V_ASSIGN
68
   (I_TARGET | I_VALUE | I_IDENT | I_DELAY),
69

70
   // V_DIMENSION
71
   (I_SUBKIND | I_LEFT | I_RIGHT),
72

73
   // V_IF
74
   (I_CONDS),
75

76
   // V_COND
77
   (I_VALUE | I_STMTS),
78

79
   // V_VAR_DECL
80
   (I_IDENT | I_TYPE | I_RANGES | I_VALUE),
81

82
   // V_DELAY_CONTROL
83
   (I_VALUE),
84

85
   // V_BINARY
86
   (I_LEFT | I_RIGHT | I_SUBKIND),
87

88
   // V_BASSIGN
89
   (I_TARGET | I_VALUE | I_DELAY),
90

91
   // V_UNARY
92
   (I_VALUE | I_SUBKIND),
93

94
   // V_GATE_INST
95
   (I_SUBKIND | I_PARAMS | I_IDENT | I_REF | I_TARGET),
96

97
   // V_STRENGTH
98
   (I_SUBKIND),
99

100
   // V_MOD_INST
101
   (I_IDENT | I_PARAMS),
102

103
   // V_BIT_SELECT
104
   (I_VALUE | I_PARAMS),
105

106
   // V_SYS_FCALL
107
   (I_IDENT | I_PARAMS),
108

109
   // V_FOREVER
110
   (I_STMTS),
111

112
   // V_SPECIFY
113
   (I_DECLS),
114

115
   // V_PRIMITIVE
116
   (I_IDENT | I_IDENT2 | I_PORTS | I_DECLS | I_STMTS),
117

118
   // V_UDP_TABLE
119
   (I_IDENT | I_PARAMS | I_SUBKIND | I_STMTS),
120

121
   // V_UDP_ENTRY
122
   (I_PARAMS),
123

124
   // V_DATA_TYPE
125
   (I_SUBKIND | I_RANGES | I_FLAGS),
126

127
   // V_TYPE_DECL
128
   (I_IDENT | I_TYPE),
129

130
   // V_ENUM_DECL
131
   (I_IDENT | I_TYPE | I_RANGES | I_DECLS),
132

133
   // V_ENUM_NAME
134
   (I_IDENT | I_TYPE | I_VALUE),
135

136
   // V_UNION_DECL
137
   (I_IDENT | I_DECLS),
138

139
   // V_STRUCT_DECL
140
   (I_IDENT | I_DECLS),
141

142
   // V_EVENT_CONTROL
143
   (I_PARAMS),
144

145
   // V_EMPTY
146
   (0),
147

148
   // V_REPEAT
149
   (I_VALUE | I_STMTS),
150

151
   // V_WHILE
152
   (I_VALUE | I_STMTS),
153

154
   // V_DO_WHILE
155
   (I_VALUE | I_STMTS),
156

157
   // V_TASK_DECL
158
   (I_IDENT | I_IDENT2 | I_STMTS | I_DECLS | I_PORTS),
159

160
   // V_FUNC_DECL
161
   (I_IDENT | I_IDENT2 | I_STMTS | I_DECLS | I_TYPE | I_PORTS),
162

163
   // V_WAIT
164
   (I_VALUE | I_STMTS),
165

166
   // V_PARAM_DECL
167
   (I_IDENT | I_VALUE | I_TYPE),
168

169
   // V_COND_EXPR
170
   (I_VALUE | I_LEFT | I_RIGHT),
171

172
   // V_REAL
173
   (I_DVAL),
174

175
   // V_CONCAT
176
   (I_PARAMS | I_VALUE),
177

178
   // V_FOR_LOOP
179
   (I_LEFT | I_VALUE | I_RIGHT | I_STMTS),
180

181
   // V_FOR_INIT
182
   (I_DECLS | I_STMTS),
183

184
   // V_FOR_STEP
185
   (I_STMTS),
186

187
   // V_PREFIX
188
   (I_TARGET | I_SUBKIND),
189

190
   // V_POSTFIX
191
   (I_TARGET | I_SUBKIND),
192

193
   // V_LOCALPARAM
194
   (I_IDENT | I_VALUE | I_TYPE),
195

196
   // V_CASE
197
   (I_SUBKIND | I_VALUE | I_STMTS),
198

199
   // V_CASE_ITEM
200
   (I_PARAMS | I_STMTS),
201

202
   // V_INST_LIST
203
   (I_PARAMS | I_STMTS | I_IDENT),
204

205
   // V_PARAM_ASSIGN
206
   (I_IDENT | I_VALUE),
207

208
   // V_INST_BODY
209
   (I_IDENT | I_IDENT2 | I_PORTS | I_STMTS | I_DECLS),
210

211
   // V_PORT_CONN
212
   (I_IDENT | I_VALUE),
213

214
   // V_PART_SELECT
215
   (I_SUBKIND | I_VALUE | I_LEFT | I_RIGHT),
216

217
   // V_IF_GENERATE
218
   (I_CONDS),
219

220
   // V_EVENT_TRIGGER
221
   (I_IDENT),
222

223
   // V_USER_FCALL
224
   (I_IDENT | I_REF | I_PARAMS),
225

226
   // V_UDP_LEVEL
227
   (I_SUBKIND | I_IVAL),
228

229
   // V_UDP_EDGE
230
   (I_SUBKIND | I_LEFT | I_RIGHT),
231

232
   // V_SPECPARAM
233
   (I_IDENT | I_VALUE),
234

235
   // V_FORK
236
   (I_IDENT | I_DECLS | I_STMTS),
237

238
   // V_ATTR_INST
239
   (0),
240

241
   // V_USER_TCALL
242
   (I_IDENT | I_REF | I_PARAMS),
243

244
   // V_VOID_CALL
245
   (I_VALUE),
246

247
   // V_GENVAR_DECL
248
   (I_IDENT | I_TYPE),
249

250
   // V_FOR_GENERATE
251
   (I_LEFT | I_VALUE | I_RIGHT | I_STMTS),
252

253
   // V_DEASSIGN
254
   (I_TARGET),
255

256
   // V_FORCE
257
   (I_TARGET | I_VALUE),
258

259
   // V_RELEASE
260
   (I_TARGET | I_VALUE),
261

262
   // V_DISABLE
263
   (I_IDENT),
264

265
   // V_HIER_REF
266
   (I_IDENT | I_IDENT2 | I_REF),
267

268
   // V_TF_PORT_DECL
269
   (I_IDENT | I_SUBKIND | I_RANGES | I_TYPE | I_VALUE | I_REF),
270

271
   // V_RETURN
272
   (I_REF | I_VALUE),
273

274
   // V_OP_ASSIGN
275
   (I_TARGET | I_SUBKIND | I_VALUE),
276

277
   // V_MEMBER_REF
278
   (I_VALUE | I_IDENT | I_REF),
279

280
   // V_PACKAGE
281
   (I_DECLS | I_IDENT | I_IDENT2),
282

283
   // V_MIN_TYP_MAX
284
   (I_LEFT | I_VALUE | I_RIGHT),
285

286
   // V_PROGRAM
287
   (I_IDENT | I_STMTS | I_DECLS | I_IDENT2),
288

289
   // V_CLASS_DECL
290
   (I_IDENT | I_IDENT2 | I_DECLS),
291

292
   // V_NULL
293
   (I_TYPE),
294

295
   // V_CLASS_NEW
296
   (I_TYPE | I_PARAMS),
297

298
   // V_CONSTRUCTOR
299
   (I_IDENT | I_PARAMS | I_STMTS | I_DECLS),
300

301
   // V_SUPER_CALL
302
   (I_PARAMS),
303

304
   // V_IMPORT_DECL
305
   (I_REF | I_IDENT),
306

307
   // V_NAMESPACE
308
   (I_DECLS),
309

310
   // V_DEFPARAM
311
   (I_TARGET | I_VALUE),
312

313
   // V_PORT_MAP
314
   (I_REF | I_VALUE),
315
};
316

317
static const char *kind_text_map[V_LAST_NODE_KIND] = {
318
   "V_MODULE",        "V_PORT_DECL",   "V_REF",           "V_ALWAYS",
319
   "V_TIMING",        "V_NBASSIGN",    "V_EVENT",         "V_INITIAL",
320
   "V_BLOCK",         "V_SYS_TCALL",   "V_STRING",        "V_NUMBER",
321
   "V_NET_DECL",      "V_ASSIGN",      "V_DIMENSION",     "V_IF",
322
   "V_COND",          "V_VAR_DECL",    "V_DELAY_CONTROL", "V_BINARY",
323
   "V_BASSIGN",       "V_UNARY",       "V_GATE_INST",     "V_STRENGTH",
324
   "V_MOD_INST",      "V_BIT_SELECT",  "V_SYS_FCALL",     "V_FOREVER",
325
   "V_SPECIFY",       "V_PRIMITIVE",   "V_UDP_TABLE",     "V_UDP_ENTRY",
326
   "V_DATA_TYPE",     "V_TYPE_DECL",   "V_ENUM_DECL",     "V_ENUM_NAME",
327
   "V_UNION_DECL",    "V_STRUCT_DECL", "V_EVENT_CONTROL", "V_EMPTY",
328
   "V_REPEAT",        "V_WHILE",       "V_DO_WHILE",      "V_TASK_DECL",
329
   "V_FUNC_DECL",     "V_WAIT",        "V_PARAM_DECL",    "V_COND_EXPR",
330
   "V_REAL",          "V_CONCAT",      "V_FOR_LOOP",      "V_FOR_INIT",
331
   "V_FOR_STEP",      "V_PREFIX",      "V_POSTFIX",       "V_LOCALPARAM",
332
   "V_CASE",          "V_CASE_ITEM",   "V_INST_LIST",     "V_PARAM_ASSIGN",
333
   "V_INST_BODY",     "V_PORT_CONN",   "V_PART_SELECT",   "V_IF_GENERATE",
334
   "V_EVENT_TRIGGER", "V_USER_FCALL",  "V_UDP_LEVEL",     "V_UDP_EDGE",
335
   "V_SPECPARAM",     "V_FORK",        "V_ATTR_INST",     "V_USER_TCALL",
336
   "V_VOID_CALL",     "V_GENVAR_DECL", "V_FOR_GENERATE",  "V_DEASSIGN",
337
   "V_FORCE",         "V_RELEASE",     "V_DISABLE",       "V_HIER_REF",
338
   "V_TF_PORT_DECL",  "V_RETURN",      "V_OP_ASSIGN",     "V_MEMBER_REF",
339
   "V_PACKAGE",       "V_MIN_TYP_MAX", "V_PROGRAM",       "V_CLASS_DECL",
340
   "V_NULL",          "V_CLASS_NEW",   "V_CONSTRUCTOR",   "V_SUPER_CALL",
341
   "V_IMPORT_DECL",   "V_NAMESPACE",   "V_DEFPARAM",      "V_PORT_MAP",
342
};
343

344
static const change_allowed_t change_allowed[] = {
345
   { -1, -1 }
346
};
347

348
object_class_t vlog_object = {
349
   .name           = "vlog",
350
   .change_allowed = change_allowed,
351
   .has_map        = has_map,
352
   .kind_text_map  = kind_text_map,
353
   .tag            = OBJECT_TAG_VLOG,
354
   .last_kind      = V_LAST_NODE_KIND,
355
   .has_loc        = true,
356
   .gc_roots       = { V_MODULE, V_PRIMITIVE, V_PROGRAM, V_PACKAGE },
357
   .gc_num_roots   = 4,
358
};
359

360
struct _vlog_node {
361
   object_t object;
362
};
363

364
static inline vlog_node_t vlog_array_nth(item_t *item, unsigned n)
91,372✔
365
{
366
   object_t *o = obj_array_nth(item->obj_array, n);
91,372✔
367
   return container_of(o, struct _vlog_node, object);
91,372✔
368
}
369

370
static inline void vlog_array_add(item_t *item, vlog_node_t v)
32,696✔
371
{
372
   obj_array_add(&(item->obj_array), &(v->object));
32,696✔
373
}
32,696✔
374

375
vlog_node_t vlog_new(vlog_kind_t kind)
59,005✔
376
{
377
   object_t *o = object_new(NULL, &vlog_object, kind);
59,005✔
378
   return container_of(o, struct _vlog_node, object);
59,005✔
379
}
380

381
vlog_kind_t vlog_kind(vlog_node_t v)
454,328✔
382
{
383
   return v->object.kind;
454,328✔
384
}
385

UNCOV
386
const char *vlog_kind_str(vlog_kind_t kind)
×
387
{
UNCOV
388
   return kind_text_map[kind];
×
389
}
390

391
ident_t vlog_ident(vlog_node_t v)
53,457✔
392
{
393
   item_t *item = lookup_item(&vlog_object, v, I_IDENT);
53,457✔
394
   assert(item->ident != NULL);
53,457✔
395
   return item->ident;
53,457✔
396
}
397

398
void vlog_set_ident(vlog_node_t v, ident_t i)
24,630✔
399
{
400
   lookup_item(&vlog_object, v, I_IDENT)->ident = i;
24,630✔
401
}
24,630✔
402

403
bool vlog_has_ident(vlog_node_t v)
1,130✔
404
{
405
   return lookup_item(&vlog_object, v, I_IDENT)->ident != NULL;
1,130✔
406
}
407

408
ident_t vlog_ident2(vlog_node_t v)
2,315✔
409
{
410
   item_t *item = lookup_item(&vlog_object, v, I_IDENT2);
2,315✔
411
   assert(item->ident != NULL);
2,315✔
412
   return item->ident;
2,315✔
413
}
414

415
bool vlog_has_ident2(vlog_node_t v)
1✔
416
{
417
   return lookup_item(&vlog_object, v, I_IDENT2)->ident != NULL;
1✔
418
}
419

420
void vlog_set_ident2(vlog_node_t v, ident_t i)
2,082✔
421
{
422
   lookup_item(&vlog_object, v, I_IDENT2)->ident = i;
2,082✔
423
}
2,082✔
424

425
const loc_t *vlog_loc(vlog_node_t v)
69,615✔
426
{
427
   assert(v != NULL);
69,615✔
428
   return &(v->object.loc);
69,615✔
429
}
430

431
void vlog_set_loc(vlog_node_t v, const loc_t *loc)
63,037✔
432
{
433
   assert(v != NULL);
63,037✔
434
   assert(loc != NULL);
63,037✔
435
   v->object.loc = *loc;
63,037✔
436
}
63,037✔
437

438
vlog_node_t vlog_ref(vlog_node_t v)
60,105✔
439
{
440
   item_t *item = lookup_item(&vlog_object, v, I_REF);
60,105✔
441
   assert(item->object != NULL);
60,105✔
442
   return container_of(item->object, struct _vlog_node, object);
60,105✔
443
}
444

445
bool vlog_has_ref(vlog_node_t v)
17,562✔
446
{
447
   return lookup_item(&vlog_object, v, I_REF)->object != NULL;
17,562✔
448
}
449

450
void vlog_set_ref(vlog_node_t v, vlog_node_t d)
13,577✔
451
{
452
   object_t *d_obj = vlog_to_object(d);
13,577✔
453
   lookup_item(&vlog_object, v, I_REF)->object = d_obj;
13,577✔
454
   object_write_barrier(&(v->object), d_obj);
13,577✔
455
}
13,577✔
456

457
unsigned vlog_stmts(vlog_node_t v)
15,592✔
458
{
459
   item_t *item = lookup_item(&vlog_object, v, I_STMTS);
15,592✔
460
   return obj_array_count(item->obj_array);
15,592✔
461
}
462

463
vlog_node_t vlog_stmt(vlog_node_t v, unsigned n)
29,804✔
464
{
465
   item_t *item = lookup_item(&vlog_object, v, I_STMTS);
29,804✔
466
   return vlog_array_nth(item, n);
29,804✔
467
}
468

469
void vlog_add_stmt(vlog_node_t v, vlog_node_t s)
14,430✔
470
{
471
   assert(s != NULL);
14,430✔
472
   vlog_array_add(lookup_item(&vlog_object, v, I_STMTS), s);
14,430✔
473
   object_write_barrier(&(v->object), &(s->object));
14,430✔
474
}
14,430✔
475

476
unsigned vlog_ports(vlog_node_t v)
5,543✔
477
{
478
   item_t *item = lookup_item(&vlog_object, v, I_PORTS);
5,543✔
479
   return obj_array_count(item->obj_array);
5,543✔
480
}
481

482
vlog_node_t vlog_port(vlog_node_t v, unsigned n)
8,521✔
483
{
484
   item_t *item = lookup_item(&vlog_object, v, I_PORTS);
8,521✔
485
   return vlog_array_nth(item, n);
8,521✔
486
}
487

488
void vlog_add_port(vlog_node_t v, vlog_node_t p)
1,181✔
489
{
490
   assert(p != NULL);
1,181✔
491
   assert(p->object.kind == V_REF || p->object.kind == V_PORT_DECL
1,181✔
492
          || p->object.kind == V_TF_PORT_DECL);
493
   vlog_array_add(lookup_item(&vlog_object, v, I_PORTS), p);
1,181✔
494
   object_write_barrier(&(v->object), &(p->object));
1,181✔
495
}
1,181✔
496

497
unsigned vlog_params(vlog_node_t v)
15,739✔
498
{
499
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
15,739✔
500
   return obj_array_count(item->obj_array);
15,739✔
501
}
502

503
vlog_node_t vlog_param(vlog_node_t v, unsigned n)
18,312✔
504
{
505
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
18,312✔
506
   return vlog_array_nth(item, n);
18,312✔
507
}
508

509
void vlog_add_param(vlog_node_t v, vlog_node_t p)
7,747✔
510
{
511
   assert(p != NULL);
7,747✔
512
   vlog_array_add(lookup_item(&vlog_object, v, I_PARAMS), p);
7,747✔
513
   object_write_barrier(&(v->object), &(p->object));
7,747✔
514
}
7,747✔
515

516
unsigned vlog_ranges(vlog_node_t v)
18,123✔
517
{
518
   item_t *item = lookup_item(&vlog_object, v, I_RANGES);
18,123✔
519
   return obj_array_count(item->obj_array);
18,123✔
520
}
521

522
vlog_node_t vlog_range(vlog_node_t v, unsigned n)
7,986✔
523
{
524
   item_t *item = lookup_item(&vlog_object, v, I_RANGES);
7,986✔
525
   return vlog_array_nth(item, n);
7,986✔
526
}
527

528
void vlog_add_range(vlog_node_t v, vlog_node_t r)
1,472✔
529
{
530
   assert(r != NULL);
1,472✔
531
   assert(r->object.kind == V_DIMENSION);
1,472✔
532
   vlog_array_add(lookup_item(&vlog_object, v, I_RANGES), r);
1,472✔
533
   object_write_barrier(&(v->object), &(r->object));
1,472✔
534
}
1,472✔
535

536
unsigned vlog_decls(vlog_node_t v)
8,739✔
537
{
538
   item_t *item = lookup_item(&vlog_object, v, I_DECLS);
8,739✔
539
   return obj_array_count(item->obj_array);
8,739✔
540
}
541

542
vlog_node_t vlog_decl(vlog_node_t v, unsigned n)
23,505✔
543
{
544
   item_t *item = lookup_item(&vlog_object, v, I_DECLS);
23,505✔
545
   return vlog_array_nth(item, n);
23,505✔
546
}
547

548
void vlog_add_decl(vlog_node_t v, vlog_node_t d)
6,253✔
549
{
550
   assert(d != NULL);
6,253✔
551
   vlog_array_add(lookup_item(&vlog_object, v, I_DECLS), d);
6,253✔
552
   object_write_barrier(&(v->object), &(d->object));
6,253✔
553
}
6,253✔
554

555
unsigned vlog_conds(vlog_node_t v)
2,621✔
556
{
557
   item_t *item = lookup_item(&vlog_object, v, I_CONDS);
2,621✔
558
   return obj_array_count(item->obj_array);
2,621✔
559
}
560

561
vlog_node_t vlog_cond(vlog_node_t v, unsigned n)
3,244✔
562
{
563
   item_t *item = lookup_item(&vlog_object, v, I_CONDS);
3,244✔
564
   return vlog_array_nth(item, n);
3,244✔
565
}
566

567
void vlog_add_cond(vlog_node_t v, vlog_node_t c)
1,613✔
568
{
569
   assert(c != NULL && c->object.kind == V_COND);
1,613✔
570
   vlog_array_add(lookup_item(&vlog_object, v, I_CONDS), c);
1,613✔
571
   object_write_barrier(&(v->object), &(c->object));
1,613✔
572
}
1,613✔
573

574
unsigned vlog_subkind(vlog_node_t v)
36,255✔
575
{
576
   return lookup_item(&vlog_object, v, I_SUBKIND)->ival;
36,255✔
577
}
578

579
void vlog_set_subkind(vlog_node_t v, unsigned sub)
11,259✔
580
{
581
   lookup_item(&vlog_object, v, I_SUBKIND)->ival = sub;
11,259✔
582
}
11,259✔
583

584
vlog_node_t vlog_value(vlog_node_t v)
26,871✔
585
{
586
   item_t *item = lookup_item(&vlog_object, v, I_VALUE);
26,871✔
587
   assert(item->object != NULL);
26,871✔
588
   return container_of(item->object, struct _vlog_node, object);
26,871✔
589
}
590

591
bool vlog_has_value(vlog_node_t v)
10,815✔
592
{
593
   return lookup_item(&vlog_object, v, I_VALUE)->object != NULL;
10,815✔
594
}
595

596
void vlog_set_value(vlog_node_t v, vlog_node_t e)
11,465✔
597
{
598
   lookup_item(&vlog_object, v, I_VALUE)->object = &(e->object);
11,465✔
599
   object_write_barrier(&(v->object), &(e->object));
11,465✔
600
}
11,465✔
601

602
vlog_node_t vlog_target(vlog_node_t v)
8,331✔
603
{
604
   item_t *item = lookup_item(&vlog_object, v, I_TARGET);
8,331✔
605
   assert(item->object != NULL);
8,331✔
606
   return container_of(item->object, struct _vlog_node, object);
8,331✔
607
}
608

609
void vlog_set_target(vlog_node_t v, vlog_node_t e)
4,104✔
610
{
611
   lookup_item(&vlog_object, v, I_TARGET)->object = &(e->object);
4,104✔
612
   object_write_barrier(&(v->object), &(e->object));
4,104✔
613
}
4,104✔
614

615
vlog_node_t vlog_delay(vlog_node_t v)
62✔
616
{
617
   item_t *item = lookup_item(&vlog_object, v, I_DELAY);
62✔
618
   assert(item->object != NULL);
62✔
619
   return container_of(item->object, struct _vlog_node, object);
62✔
620
}
621

622
bool vlog_has_delay(vlog_node_t v)
3,753✔
623
{
624
   return lookup_item(&vlog_object, v, I_DELAY)->object != NULL;
3,753✔
625
}
626

627
void vlog_set_delay(vlog_node_t v, vlog_node_t d)
457✔
628
{
629
   object_t *d_obj = vlog_to_object(d);
457✔
630
   lookup_item(&vlog_object, v, I_DELAY)->object = d_obj;
457✔
631
   object_write_barrier(&(v->object), d_obj);
457✔
632
}
457✔
633

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

641
bool vlog_has_type(vlog_node_t v)
1✔
642
{
643
   return lookup_item(&vlog_object, v, I_TYPE)->object != NULL;
1✔
644
}
645

646
void vlog_set_type(vlog_node_t v, vlog_node_t t)
3,684✔
647
{
648
   object_t *t_obj = vlog_to_object(t);
3,684✔
649
   lookup_item(&vlog_object, v, I_TYPE)->object = t_obj;
3,684✔
650
   object_write_barrier(&(v->object), t_obj);
3,684✔
651
}
3,684✔
652

653
number_t vlog_number(vlog_node_t v)
28,998✔
654
{
655
   return lookup_item(&vlog_object, v, I_NUMBER)->number;
28,998✔
656
}
657

658
void vlog_set_number(vlog_node_t v, number_t n)
13,444✔
659
{
660
   lookup_item(&vlog_object, v, I_NUMBER)->number = n;
13,444✔
661
}
13,444✔
662

663
vlog_node_t vlog_left(vlog_node_t v)
21,457✔
664
{
665
   item_t *item = lookup_item(&vlog_object, v, I_LEFT);
21,457✔
666
   assert(item->object != NULL);
21,457✔
667
   return container_of(item->object, struct _vlog_node, object);
21,457✔
668
}
669

670
void vlog_set_left(vlog_node_t v, vlog_node_t e)
5,287✔
671
{
672
   lookup_item(&vlog_object, v, I_LEFT)->object = &(e->object);
5,287✔
673
   object_write_barrier(&(v->object), &(e->object));
5,287✔
674
}
5,287✔
675

676
vlog_node_t vlog_right(vlog_node_t v)
21,045✔
677
{
678
   item_t *item = lookup_item(&vlog_object, v, I_RIGHT);
21,045✔
679
   assert(item->object != NULL);
21,045✔
680
   return container_of(item->object, struct _vlog_node, object);
21,045✔
681
}
682

683
void vlog_set_right(vlog_node_t v, vlog_node_t e)
5,287✔
684
{
685
   lookup_item(&vlog_object, v, I_RIGHT)->object = &(e->object);
5,287✔
686
   object_write_barrier(&(v->object), &(e->object));
5,287✔
687
}
5,287✔
688

689
double vlog_dval(vlog_node_t v)
45✔
690
{
691
   return lookup_item(&vlog_object, v, I_DVAL)->dval;
45✔
692
}
693

694
void vlog_set_dval(vlog_node_t v, double d)
74✔
695
{
696
   lookup_item(&vlog_object, v, I_DVAL)->dval = d;
74✔
697
}
74✔
698

699
int64_t vlog_ival(vlog_node_t v)
624✔
700
{
701
   return lookup_item(&vlog_object, v, I_IVAL)->ival;
624✔
702
}
703

704
void vlog_set_ival(vlog_node_t v, int64_t i)
609✔
705
{
706
   lookup_item(&vlog_object, v, I_IVAL)->ival = i;
609✔
707
}
609✔
708

709
vlog_flags_t vlog_flags(vlog_node_t t)
6,008✔
710
{
711
   return lookup_item(&vlog_object, t, I_FLAGS)->ival;
6,008✔
712
}
713

714
void vlog_set_flags(vlog_node_t v, vlog_flags_t mask)
413✔
715
{
716
   lookup_item(&vlog_object, v, I_FLAGS)->ival |= mask;
413✔
717
}
413✔
718

UNCOV
719
void vlog_visit(vlog_node_t v, vlog_visit_fn_t fn, void *context)
×
720
{
UNCOV
721
   vlog_visit_only(v, fn, context, V_LAST_NODE_KIND);
×
UNCOV
722
}
×
723

724
void vlog_visit_only(vlog_node_t v, vlog_visit_fn_t fn, void *context,
5✔
725
                     vlog_kind_t kind)
726
{
727
   assert(v != NULL);
5✔
728

729
   object_visit_ctx_t ctx = {
5✔
730
      .count      = 0,
731
      .postorder  = (object_visit_fn_t)fn,
732
      .preorder   = NULL,
733
      .context    = context,
734
      .kind       = kind,
735
      .tag        = OBJECT_TAG_VLOG,
736
      .generation = object_next_generation(),
5✔
737
      .deep       = false
738
   };
739

740
   object_visit(&(v->object), &ctx);
5✔
741
}
5✔
742

743
vlog_node_t vlog_rewrite(vlog_node_t v, vlog_rewrite_fn_t fn, void *context)
2,201✔
744
{
745
   object_arena_t *arena = object_arena(&(v->object));
2,201✔
746
   if (arena_frozen(arena))
2,201✔
747
      return v;
748

749
   object_rewrite_ctx_t ctx = {
2,201✔
750
      .generation = object_next_generation(),
2,201✔
751
      .context    = context,
752
      .arena      = arena,
753
   };
754

755
   ctx.post_fn[OBJECT_TAG_VLOG] = (object_rewrite_post_fn_t)fn;
2,201✔
756

757
   object_t *result = object_rewrite(&(v->object), &ctx);
2,201✔
758
   free(ctx.cache);
2,201✔
759
   return container_of(result, struct _vlog_node, object);
2,201✔
760
}
761

762
vlog_node_t vlog_copy(vlog_node_t v, vlog_copy_pred_t pred, void *ctx)
800✔
763
{
764
   object_copy_ctx_t *copy LOCAL = xcalloc_flex(sizeof(object_copy_ctx_t),
800✔
765
                                                1, sizeof(object_t *));
766
   copy->generation   = object_next_generation();
800✔
767
   copy->pred_context = ctx;
800✔
768
   copy->nroots       = 1;
800✔
769
   copy->roots[0]     = &(v->object);
800✔
770

771
   copy->should_copy[OBJECT_TAG_VLOG] = (object_copy_pred_t)pred;
800✔
772

773
   object_copy_begin(copy);
800✔
774
   object_copy_finish(copy);
800✔
775

776
   return container_of(copy->roots[0], struct _vlog_node, object);
800✔
777
}
778

779
object_t *vlog_to_object(vlog_node_t v)
24,631✔
780
{
781
   return v != NULL ? &(v->object) : NULL;
24,631✔
782
}
783

784
vlog_node_t vlog_from_object(object_t *obj)
20,653✔
785
{
786
   if (obj != NULL && obj->tag == OBJECT_TAG_VLOG)
20,653✔
787
      return container_of(obj, struct _vlog_node, object);
788
   else
789
      return NULL;
15,680✔
790
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc