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

nickg / nvc / 13980381364

20 Mar 2025 09:03AM UTC coverage: 92.305% (+0.02%) from 92.285%
13980381364

push

github

nickg
Simplify parsing for Verilog constant expressions

27 of 27 new or added lines in 2 files covered. (100.0%)

68 existing lines in 5 files now uncovered.

68315 of 74010 relevant lines covered (92.31%)

426139.33 hits per line

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

96.33
/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),
33

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

37
   // V_ALWAYS
38
   (I_IDENT | 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_SEQ_BLOCK
53
   (I_IDENT | I_STMTS),
54

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

58
   // V_STRING
59
   (I_TEXT),
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_SUBKIND | 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_IDENT2 | I_PARAMS),
102

103
   // V_BIT_SELECT
104
   (I_IDENT | I_REF | I_PARAMS),
105

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

109
   // V_FOREVER
110
   (I_STMTS),
111

112
   // V_SPECIFY
113
   (0),
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_TEXT),
123

124
   // V_DATA_TYPE
125
   (I_SUBKIND | I_RANGES),
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),
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_STMTS | I_DECLS),
159

160
   // V_FUNC_DECL
161
   (I_IDENT | I_STMTS | I_DECLS | I_TYPE),
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

197
static const char *kind_text_map[V_LAST_NODE_KIND] = {
198
   "V_MODULE",     "V_PORT_DECL",   "V_REF",           "V_ALWAYS",
199
   "V_TIMING",     "V_NBASSIGN",    "V_EVENT",         "V_INITIAL",
200
   "V_SEQ_BLOCK",  "V_SYS_TCALL",   "V_STRING",        "V_NUMBER",
201
   "V_NET_DECL",   "V_ASSIGN",      "V_DIMENSION",     "V_IF",
202
   "V_COND",       "V_VAR_DECL",    "V_DELAY_CONTROL", "V_BINARY",
203
   "V_BASSIGN",    "V_UNARY",       "V_GATE_INST",     "V_STRENGTH",
204
   "V_MOD_INST",   "V_BIT_SELECT",  "V_SYS_FCALL",     "V_FOREVER",
205
   "V_SPECIFY",    "V_PRIMITIVE",   "V_UDP_TABLE",     "V_UDP_ENTRY",
206
   "V_DATA_TYPE",  "V_TYPE_DECL",   "V_ENUM_DECL",     "V_ENUM_NAME",
207
   "V_UNION_DECL", "V_STRUCT_DECL", "V_EVENT_CONTROL", "V_EMPTY",
208
   "V_REPEAT",     "V_WHILE",       "V_DO_WHILE",      "V_TASK_DECL",
209
   "V_FUNC_DECL",  "V_WAIT",        "V_PARAM_DECL",    "V_COND_EXPR",
210
   "V_REAL",       "V_CONCAT",      "V_FOR_LOOP",      "V_FOR_INIT",
211
   "V_FOR_STEP",   "V_PREFIX",      "V_POSTFIX",       "V_LOCALPARAM",
212
};
213

214
static const change_allowed_t change_allowed[] = {
215
   { -1, -1 }
216
};
217

218
object_class_t vlog_object = {
219
   .name           = "vlog",
220
   .change_allowed = change_allowed,
221
   .has_map        = has_map,
222
   .kind_text_map  = kind_text_map,
223
   .tag            = OBJECT_TAG_VLOG,
224
   .last_kind      = V_LAST_NODE_KIND,
225
   .has_loc        = true,
226
   .gc_roots       = { V_MODULE, V_PRIMITIVE },
227
   .gc_num_roots   = 2
228
};
229

230
struct _vlog_node {
231
   object_t object;
232
};
233

234
static inline vlog_node_t vlog_array_nth(item_t *item, unsigned n)
7,764✔
235
{
236
   object_t *o = obj_array_nth(item->obj_array, n);
7,764✔
237
   return container_of(o, struct _vlog_node, object);
7,764✔
238
}
239

240
static inline void vlog_array_add(item_t *item, vlog_node_t v)
3,337✔
241
{
242
   obj_array_add(&(item->obj_array), &(v->object));
3,337✔
243
}
3,337✔
244

245
vlog_node_t vlog_new(vlog_kind_t kind)
5,980✔
246
{
247
   object_t *o = object_new(NULL, &vlog_object, kind);
5,980✔
248
   return container_of(o, struct _vlog_node, object);
5,980✔
249
}
250

251
vlog_kind_t vlog_kind(vlog_node_t v)
26,119✔
252
{
253
   return v->object.kind;
26,119✔
254
}
255

UNCOV
256
const char *vlog_kind_str(vlog_kind_t kind)
×
257
{
UNCOV
258
   return kind_text_map[kind];
×
259
}
260

261
ident_t vlog_ident(vlog_node_t v)
4,578✔
262
{
263
   item_t *item = lookup_item(&vlog_object, v, I_IDENT);
4,578✔
264
   assert(item->ident != NULL);
4,578✔
265
   return item->ident;
4,578✔
266
}
267

268
void vlog_set_ident(vlog_node_t v, ident_t i)
2,703✔
269
{
270
   lookup_item(&vlog_object, v, I_IDENT)->ident = i;
2,703✔
271
}
2,703✔
272

273
bool vlog_has_ident(vlog_node_t v)
32✔
274
{
275
   return lookup_item(&vlog_object, v, I_IDENT)->ident != NULL;
32✔
276
}
277

278
ident_t vlog_ident2(vlog_node_t v)
205✔
279
{
280
   item_t *item = lookup_item(&vlog_object, v, I_IDENT2);
205✔
281
   assert(item->ident != NULL);
205✔
282
   return item->ident;
205✔
283
}
284

285
void vlog_set_ident2(vlog_node_t v, ident_t i)
319✔
286
{
287
   lookup_item(&vlog_object, v, I_IDENT2)->ident = i;
319✔
288
}
319✔
289

290
const loc_t *vlog_loc(vlog_node_t v)
4,280✔
291
{
292
   assert(v != NULL);
4,280✔
293
   return &(v->object.loc);
4,280✔
294
}
295

296
void vlog_set_loc(vlog_node_t v, const loc_t *loc)
6,482✔
297
{
298
   assert(v != NULL);
6,482✔
299
   assert(loc != NULL);
6,482✔
300
   v->object.loc = *loc;
6,482✔
301
}
6,482✔
302

303
vlog_node_t vlog_ref(vlog_node_t v)
2,552✔
304
{
305
   item_t *item = lookup_item(&vlog_object, v, I_REF);
2,552✔
306
   assert(item->object != NULL);
2,552✔
307
   return container_of(item->object, struct _vlog_node, object);
2,552✔
308
}
309

310
bool vlog_has_ref(vlog_node_t v)
927✔
311
{
312
   return lookup_item(&vlog_object, v, I_REF)->object != NULL;
927✔
313
}
314

315
void vlog_set_ref(vlog_node_t v, vlog_node_t d)
1,343✔
316
{
317
   lookup_item(&vlog_object, v, I_REF)->object = &(d->object);
1,343✔
318
   object_write_barrier(&(v->object), &(d->object));
1,343✔
319
}
1,343✔
320

321
unsigned vlog_stmts(vlog_node_t v)
1,634✔
322
{
323
   item_t *item = lookup_item(&vlog_object, v, I_STMTS);
1,634✔
324
   return obj_array_count(item->obj_array);
1,634✔
325
}
326

327
vlog_node_t vlog_stmt(vlog_node_t v, unsigned n)
3,052✔
328
{
329
   item_t *item = lookup_item(&vlog_object, v, I_STMTS);
3,052✔
330
   return vlog_array_nth(item, n);
3,052✔
331
}
332

333
void vlog_add_stmt(vlog_node_t v, vlog_node_t s)
1,501✔
334
{
335
   assert(s != NULL);
1,501✔
336
   vlog_array_add(lookup_item(&vlog_object, v, I_STMTS), s);
1,501✔
337
   object_write_barrier(&(v->object), &(s->object));
1,501✔
338
}
1,501✔
339

340
unsigned vlog_ports(vlog_node_t v)
330✔
341
{
342
   item_t *item = lookup_item(&vlog_object, v, I_PORTS);
330✔
343
   return obj_array_count(item->obj_array);
330✔
344
}
345

346
vlog_node_t vlog_port(vlog_node_t v, unsigned n)
412✔
347
{
348
   item_t *item = lookup_item(&vlog_object, v, I_PORTS);
412✔
349
   return vlog_array_nth(item, n);
412✔
350
}
351

352
void vlog_add_port(vlog_node_t v, vlog_node_t p)
174✔
353
{
354
   assert(p != NULL);
174✔
355
   assert(p->object.kind == V_REF);
174✔
356
   vlog_array_add(lookup_item(&vlog_object, v, I_PORTS), p);
174✔
357
   object_write_barrier(&(v->object), &(p->object));
174✔
358
}
174✔
359

360
unsigned vlog_params(vlog_node_t v)
1,453✔
361
{
362
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
1,453✔
363
   return obj_array_count(item->obj_array);
1,453✔
364
}
365

366
vlog_node_t vlog_param(vlog_node_t v, unsigned n)
2,228✔
367
{
368
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
2,228✔
369
   return vlog_array_nth(item, n);
2,228✔
370
}
371

372
void vlog_add_param(vlog_node_t v, vlog_node_t p)
894✔
373
{
374
   assert(p != NULL);
894✔
375
   vlog_array_add(lookup_item(&vlog_object, v, I_PARAMS), p);
894✔
376
   object_write_barrier(&(v->object), &(p->object));
894✔
377
}
894✔
378

379
unsigned vlog_ranges(vlog_node_t v)
2,917✔
380
{
381
   item_t *item = lookup_item(&vlog_object, v, I_RANGES);
2,917✔
382
   return obj_array_count(item->obj_array);
2,917✔
383
}
384

385
vlog_node_t vlog_range(vlog_node_t v, unsigned n)
295✔
386
{
387
   item_t *item = lookup_item(&vlog_object, v, I_RANGES);
295✔
388
   return vlog_array_nth(item, n);
295✔
389
}
390

391
void vlog_add_range(vlog_node_t v, vlog_node_t r)
54✔
392
{
393
   assert(r != NULL);
54✔
394
   assert(r->object.kind == V_DIMENSION);
54✔
395
   vlog_array_add(lookup_item(&vlog_object, v, I_RANGES), r);
54✔
396
   object_write_barrier(&(v->object), &(r->object));
54✔
397
}
54✔
398

399
unsigned vlog_decls(vlog_node_t v)
362✔
400
{
401
   item_t *item = lookup_item(&vlog_object, v, I_DECLS);
362✔
402
   return obj_array_count(item->obj_array);
362✔
403
}
404

405
vlog_node_t vlog_decl(vlog_node_t v, unsigned n)
1,466✔
406
{
407
   item_t *item = lookup_item(&vlog_object, v, I_DECLS);
1,466✔
408
   return vlog_array_nth(item, n);
1,466✔
409
}
410

411
void vlog_add_decl(vlog_node_t v, vlog_node_t d)
551✔
412
{
413
   assert(d != NULL);
551✔
414
   vlog_array_add(lookup_item(&vlog_object, v, I_DECLS), d);
551✔
415
   object_write_barrier(&(v->object), &(d->object));
551✔
416
}
551✔
417

418
unsigned vlog_conds(vlog_node_t v)
236✔
419
{
420
   item_t *item = lookup_item(&vlog_object, v, I_CONDS);
236✔
421
   return obj_array_count(item->obj_array);
236✔
422
}
423

424
vlog_node_t vlog_cond(vlog_node_t v, unsigned n)
311✔
425
{
426
   item_t *item = lookup_item(&vlog_object, v, I_CONDS);
311✔
427
   return vlog_array_nth(item, n);
311✔
428
}
429

430
void vlog_add_cond(vlog_node_t v, vlog_node_t c)
163✔
431
{
432
   assert(c != NULL && c->object.kind == V_COND);
163✔
433
   vlog_array_add(lookup_item(&vlog_object, v, I_CONDS), c);
163✔
434
   object_write_barrier(&(v->object), &(c->object));
163✔
435
}
163✔
436

437
unsigned vlog_subkind(vlog_node_t v)
842✔
438
{
439
   return lookup_item(&vlog_object, v, I_SUBKIND)->ival;
842✔
440
}
441

442
void vlog_set_subkind(vlog_node_t v, unsigned sub)
1,277✔
443
{
444
   lookup_item(&vlog_object, v, I_SUBKIND)->ival = sub;
1,277✔
445
}
1,277✔
446

447
vlog_node_t vlog_value(vlog_node_t v)
2,068✔
448
{
449
   item_t *item = lookup_item(&vlog_object, v, I_VALUE);
2,068✔
450
   assert(item->object != NULL);
2,068✔
451
   return container_of(item->object, struct _vlog_node, object);
2,068✔
452
}
453

454
bool vlog_has_value(vlog_node_t v)
474✔
455
{
456
   return lookup_item(&vlog_object, v, I_VALUE)->object != NULL;
474✔
457
}
458

459
void vlog_set_value(vlog_node_t v, vlog_node_t e)
1,050✔
460
{
461
   lookup_item(&vlog_object, v, I_VALUE)->object = &(e->object);
1,050✔
462
   object_write_barrier(&(v->object), &(e->object));
1,050✔
463
}
1,050✔
464

465
vlog_node_t vlog_target(vlog_node_t v)
817✔
466
{
467
   item_t *item = lookup_item(&vlog_object, v, I_TARGET);
817✔
468
   assert(item->object != NULL);
817✔
469
   return container_of(item->object, struct _vlog_node, object);
817✔
470
}
471

472
void vlog_set_target(vlog_node_t v, vlog_node_t e)
392✔
473
{
474
   lookup_item(&vlog_object, v, I_TARGET)->object = &(e->object);
392✔
475
   object_write_barrier(&(v->object), &(e->object));
392✔
476
}
392✔
477

478
vlog_node_t vlog_delay(vlog_node_t v)
74✔
479
{
480
   item_t *item = lookup_item(&vlog_object, v, I_DELAY);
74✔
481
   assert(item->object != NULL);
74✔
482
   return container_of(item->object, struct _vlog_node, object);
74✔
483
}
484

485
bool vlog_has_delay(vlog_node_t v)
557✔
486
{
487
   return lookup_item(&vlog_object, v, I_DELAY)->object != NULL;
557✔
488
}
489

490
void vlog_set_delay(vlog_node_t v, vlog_node_t d)
38✔
491
{
492
   lookup_item(&vlog_object, v, I_DELAY)->object = &(d->object);
38✔
493
   object_write_barrier(&(v->object), &(d->object));
38✔
494
}
38✔
495

496
vlog_node_t vlog_type(vlog_node_t v)
2,031✔
497
{
498
   item_t *item = lookup_item(&vlog_object, v, I_TYPE);
2,031✔
499
   assert(item->object != NULL);
2,031✔
500
   return container_of(item->object, struct _vlog_node, object);
2,031✔
501
}
502

UNCOV
503
bool vlog_has_type(vlog_node_t v)
×
504
{
UNCOV
505
   return lookup_item(&vlog_object, v, I_TYPE)->object != NULL;
×
506
}
507

508
void vlog_set_type(vlog_node_t v, vlog_node_t t)
553✔
509
{
510
   lookup_item(&vlog_object, v, I_TYPE)->object = &(t->object);
553✔
511
   object_write_barrier(&(v->object), &(t->object));
553✔
512
}
553✔
513

514
const char *vlog_text(vlog_node_t v)
544✔
515
{
516
   item_t *item = lookup_item(&vlog_object, v, I_TEXT);
544✔
517
   assert(item->text != NULL);
544✔
518
   return item->text;
544✔
519
}
520

521
void vlog_set_text(vlog_node_t v, const char *text)
398✔
522
{
523
   lookup_item(&vlog_object, v, I_TEXT)->text = xstrdup(text);
398✔
524
}
398✔
525

526
number_t vlog_number(vlog_node_t v)
1,102✔
527
{
528
   return lookup_item(&vlog_object, v, I_NUMBER)->number;
1,102✔
529
}
530

531
void vlog_set_number(vlog_node_t v, number_t n)
743✔
532
{
533
   lookup_item(&vlog_object, v, I_NUMBER)->number = n;
743✔
534
}
743✔
535

536
vlog_node_t vlog_left(vlog_node_t v)
686✔
537
{
538
   item_t *item = lookup_item(&vlog_object, v, I_LEFT);
686✔
539
   assert(item->object != NULL);
686✔
540
   return container_of(item->object, struct _vlog_node, object);
686✔
541
}
542

543
void vlog_set_left(vlog_node_t v, vlog_node_t e)
276✔
544
{
545
   lookup_item(&vlog_object, v, I_LEFT)->object = &(e->object);
276✔
546
   object_write_barrier(&(v->object), &(e->object));
276✔
547
}
276✔
548

549
vlog_node_t vlog_right(vlog_node_t v)
686✔
550
{
551
   item_t *item = lookup_item(&vlog_object, v, I_RIGHT);
686✔
552
   assert(item->object != NULL);
686✔
553
   return container_of(item->object, struct _vlog_node, object);
686✔
554
}
555

556
void vlog_set_right(vlog_node_t v, vlog_node_t e)
276✔
557
{
558
   lookup_item(&vlog_object, v, I_RIGHT)->object = &(e->object);
276✔
559
   object_write_barrier(&(v->object), &(e->object));
276✔
560
}
276✔
561

562
double vlog_dval(vlog_node_t v)
1✔
563
{
564
   return lookup_item(&vlog_object, v, I_DVAL)->dval;
1✔
565
}
566

567
void vlog_set_dval(vlog_node_t v, double d)
6✔
568
{
569
   lookup_item(&vlog_object, v, I_DVAL)->dval = d;
6✔
570
}
6✔
571

572
void vlog_visit(vlog_node_t v, vlog_visit_fn_t fn, void *context)
171✔
573
{
574
   vlog_visit_only(v, fn, context, V_LAST_NODE_KIND);
171✔
575
}
171✔
576

577
void vlog_visit_only(vlog_node_t v, vlog_visit_fn_t fn, void *context,
171✔
578
                     vlog_kind_t kind)
579
{
580
   assert(v != NULL);
171✔
581

582
   object_visit_ctx_t ctx = {
171✔
583
      .count      = 0,
584
      .postorder  = (object_visit_fn_t)fn,
585
      .preorder   = NULL,
586
      .context    = context,
587
      .kind       = kind,
588
      .tag        = OBJECT_TAG_VLOG,
589
      .generation = object_next_generation(),
171✔
590
      .deep       = false
591
   };
592

593
   object_visit(&(v->object), &ctx);
171✔
594
}
171✔
595

596
vlog_node_t vlog_rewrite(vlog_node_t v, vlog_rewrite_fn_t fn, void *context)
92✔
597
{
598
   object_arena_t *arena = object_arena(&(v->object));
92✔
599
   if (arena_frozen(arena))
92✔
600
      return v;
601

602
   object_rewrite_ctx_t ctx = {
92✔
603
      .generation = object_next_generation(),
92✔
604
      .context    = context,
605
      .arena      = arena,
606
   };
607

608
   ctx.post_fn[OBJECT_TAG_VLOG] = (object_rewrite_post_fn_t)fn;
92✔
609

610
   object_t *result = object_rewrite(&(v->object), &ctx);
92✔
611
   free(ctx.cache);
92✔
612
   return container_of(result, struct _vlog_node, object);
92✔
613
}
614

615
object_t *vlog_to_object(vlog_node_t v)
820✔
616
{
617
   return &(v->object);
820✔
618
}
619

620
vlog_node_t vlog_from_object(object_t *obj)
4,387✔
621
{
622
   if (obj != NULL && obj->tag == OBJECT_TAG_VLOG)
4,387✔
623
      return container_of(obj, struct _vlog_node, object);
624
   else
625
      return NULL;
4,140✔
626
}
627

628
void vlog_locus(vlog_node_t v, ident_t *unit, ptrdiff_t *offset)
×
629
{
UNCOV
630
   assert(v != NULL);
×
UNCOV
631
   object_locus(&(v->object), unit, offset);
×
UNCOV
632
}
×
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