Add metadata test cases
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
CommitLineData
05628561
MD
1/*
2 * ctf-visitor-generate-io-struct.c
3 *
4 * Common Trace Format Metadata Visitor (generate I/O structures).
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19#include <stdio.h>
20#include <unistd.h>
21#include <string.h>
22#include <stdlib.h>
23#include <assert.h>
24#include <glib.h>
25#include <inttypes.h>
add40b62 26#include <endian.h>
05628561
MD
27#include <errno.h>
28#include <babeltrace/list.h>
a0720417
MD
29#include <babeltrace/types.h>
30#include <babeltrace/ctf/metadata.h>
41253107 31#include <uuid/uuid.h>
05628561
MD
32#include "ctf-scanner.h"
33#include "ctf-parser.h"
34#include "ctf-ast.h"
35
36#define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
37
de47353a
MD
38#define _cds_list_first_entry(ptr, type, member) \
39 cds_list_entry((ptr)->next, type, member)
05628561 40
a3cca9e9 41static
78af2bcd
MD
42struct declaration *ctf_type_specifier_list_visit(FILE *fd,
43 int depth, struct ctf_node *type_specifier_list,
ab4cf058
MD
44 struct declaration_scope *declaration_scope,
45 struct ctf_trace *trace);
a3cca9e9 46
05628561 47/*
41253107 48 * String returned must be freed by the caller using g_free.
05628561
MD
49 */
50static
add40b62 51char *concatenate_unary_strings(struct cds_list_head *head)
05628561 52{
41253107
MD
53 struct ctf_node *node;
54 GString *str;
55 int i = 0;
56
a0720417 57 str = g_string_new("");
41253107
MD
58 cds_list_for_each_entry(node, head, siblings) {
59 char *src_string;
60
61 assert(node->type == NODE_UNARY_EXPRESSION);
62 assert(node->u.unary_expression.type == UNARY_STRING);
63 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
a0720417 64 ^ (i != 0));
41253107
MD
65 switch (node->u.unary_expression.link) {
66 case UNARY_DOTLINK:
a0720417 67 g_string_append(str, ".");
41253107
MD
68 break;
69 case UNARY_ARROWLINK:
a0720417 70 g_string_append(str, "->");
41253107
MD
71 break;
72 case UNARY_DOTDOTDOT:
a0720417
MD
73 g_string_append(str, "...");
74 break;
75 default:
41253107
MD
76 break;
77 }
a0720417 78 src_string = node->u.unary_expression.u.string;
41253107
MD
79 g_string_append(str, src_string);
80 i++;
81 }
82 return g_string_free(str, FALSE);
05628561
MD
83}
84
85static
add40b62 86int get_unary_unsigned(struct cds_list_head *head, uint64_t *value)
05628561 87{
41253107
MD
88 struct ctf_node *node;
89 int i = 0;
90
91 cds_list_for_each_entry(node, head, siblings) {
92 assert(node->type == NODE_UNARY_EXPRESSION);
93 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
94 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
95 assert(i == 0);
a0720417 96 *value = node->u.unary_expression.u.unsigned_constant;
41253107
MD
97 i++;
98 }
99 return 0;
05628561
MD
100}
101
102static
add40b62 103int get_unary_uuid(struct cds_list_head *head, uuid_t *uuid)
05628561 104{
41253107
MD
105 struct ctf_node *node;
106 int i = 0;
107 int ret = -1;
108
109 cds_list_for_each_entry(node, head, siblings) {
110 const char *src_string;
111
112 assert(node->type == NODE_UNARY_EXPRESSION);
113 assert(node->u.unary_expression.type == UNARY_STRING);
114 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
115 assert(i == 0);
a0720417
MD
116 src_string = node->u.unary_expression.u.string;
117 ret = uuid_parse(node->u.unary_expression.u.string, *uuid);
41253107
MD
118 }
119 return ret;
05628561
MD
120}
121
122static
123struct ctf_stream *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
124{
125 if (trace->streams->len <= stream_id)
126 return NULL;
127 return g_ptr_array_index(trace->streams, stream_id);
128}
129
add40b62 130static
78af2bcd
MD
131int visit_type_specifier(FILE *fd, struct ctf_node *type_specifier, GString *str)
132{
133 assert(type_specifier->type == NODE_TYPE_SPECIFIER);
134
135 switch (type_specifier->u.type_specifier.type) {
136 case TYPESPEC_VOID:
137 g_string_append(str, "void");
138 break;
139 case TYPESPEC_CHAR:
140 g_string_append(str, "char");
141 break;
142 case TYPESPEC_SHORT:
143 g_string_append(str, "short");
144 break;
145 case TYPESPEC_INT:
146 g_string_append(str, "int");
147 break;
148 case TYPESPEC_LONG:
149 g_string_append(str, "long");
150 break;
151 case TYPESPEC_FLOAT:
152 g_string_append(str, "float");
153 break;
154 case TYPESPEC_DOUBLE:
155 g_string_append(str, "double");
156 break;
157 case TYPESPEC_SIGNED:
158 g_string_append(str, "signed");
159 break;
160 case TYPESPEC_UNSIGNED:
161 g_string_append(str, "unsigned");
162 break;
163 case TYPESPEC_BOOL:
164 g_string_append(str, "bool");
165 break;
166 case TYPESPEC_COMPLEX:
167 g_string_append(str, "_Complex");
168 break;
169 case TYPESPEC_IMAGINARY:
170 g_string_append(str, "_Imaginary");
171 break;
172 case TYPESPEC_CONST:
173 g_string_append(str, "const");
174 break;
175 case TYPESPEC_ID_TYPE:
176 if (type_specifier->u.type_specifier.id_type)
177 g_string_append(str, type_specifier->u.type_specifier.id_type);
178 break;
179 case TYPESPEC_STRUCT:
180 {
181 struct ctf_node *node = type_specifier->u.type_specifier.node;
182
183 if (!node->u._struct.name) {
184 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
185 return -EINVAL;
186 }
187 g_string_append(str, "struct ");
188 g_string_append(str, node->u._struct.name);
189 break;
190 }
191 case TYPESPEC_VARIANT:
192 {
193 struct ctf_node *node = type_specifier->u.type_specifier.node;
194
195 if (!node->u.variant.name) {
196 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
197 return -EINVAL;
198 }
199 g_string_append(str, "variant ");
200 g_string_append(str, node->u.variant.name);
201 break;
202 }
203 case TYPESPEC_ENUM:
204 {
205 struct ctf_node *node = type_specifier->u.type_specifier.node;
206
207 if (!node->u._enum.enum_id) {
208 fprintf(fd, "[error] %s: unexpected empty enum ID\n", __func__);
209 return -EINVAL;
210 }
211 g_string_append(str, "enum ");
212 g_string_append(str, node->u._enum.enum_id);
213 break;
214 }
215 case TYPESPEC_FLOATING_POINT:
216 case TYPESPEC_INTEGER:
217 case TYPESPEC_STRING:
218 default:
219 fprintf(fd, "[error] %s: unknown specifier\n", __func__);
220 return -EINVAL;
221 }
222 return 0;
223}
224
225static
226int visit_type_specifier_list(FILE *fd, struct ctf_node *type_specifier_list, GString *str)
add40b62
MD
227{
228 struct ctf_node *iter;
229 int alias_item_nr = 0;
78af2bcd 230 int ret;
add40b62 231
78af2bcd 232 cds_list_for_each_entry(iter, &type_specifier_list->u.type_specifier_list.head, siblings) {
add40b62
MD
233 if (alias_item_nr != 0)
234 g_string_append(str, " ");
235 alias_item_nr++;
78af2bcd
MD
236 ret = visit_type_specifier(fd, iter, str);
237 if (ret)
238 return ret;
add40b62
MD
239 }
240 return 0;
add40b62
MD
241}
242
243static
8fdba45b 244GQuark create_typealias_identifier(FILE *fd, int depth,
78af2bcd 245 struct ctf_node *type_specifier_list,
add40b62
MD
246 struct ctf_node *node_type_declarator)
247{
a0720417 248 struct ctf_node *iter;
add40b62 249 GString *str;
a0720417 250 char *str_c;
add40b62
MD
251 GQuark alias_q;
252 int ret;
253
a0720417 254 str = g_string_new("");
78af2bcd 255 ret = visit_type_specifier_list(fd, type_specifier_list, str);
add40b62
MD
256 if (ret) {
257 g_string_free(str, TRUE);
258 return 0;
259 }
260 cds_list_for_each_entry(iter, &node_type_declarator->u.type_declarator.pointers, siblings) {
261 g_string_append(str, " *");
262 if (iter->u.pointer.const_qualifier)
263 g_string_append(str, " const");
264 }
265 str_c = g_string_free(str, FALSE);
266 alias_q = g_quark_from_string(str_c);
267 g_free(str_c);
268 return alias_q;
269}
270
a3cca9e9 271static
8fdba45b 272struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
78af2bcd 273 struct ctf_node *type_specifier_list,
a3cca9e9
MD
274 GQuark *field_name,
275 struct ctf_node *node_type_declarator,
add40b62 276 struct declaration_scope *declaration_scope,
e397791f
MD
277 struct declaration *nested_declaration,
278 struct ctf_trace *trace)
a3cca9e9
MD
279{
280 /*
281 * Visit type declarator by first taking care of sequence/array
282 * (recursively). Then, when we get to the identifier, take care
283 * of pointers.
284 */
285
e397791f
MD
286 if (node_type_declarator) {
287 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
add40b62 288
e397791f
MD
289 /* TODO: gcc bitfields not supported yet. */
290 if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
78af2bcd 291 fprintf(fd, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
e397791f
MD
292 return NULL;
293 }
add40b62 294 }
a3cca9e9
MD
295
296 if (!nested_declaration) {
e397791f 297 if (node_type_declarator && !cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
add40b62
MD
298 GQuark alias_q;
299
a3cca9e9
MD
300 /*
301 * If we have a pointer declarator, it _has_ to be present in
302 * the typealiases (else fail).
303 */
add40b62 304 alias_q = create_typealias_identifier(fd, depth,
78af2bcd 305 type_specifier_list, node_type_declarator);
add40b62
MD
306 nested_declaration = lookup_declaration(alias_q, declaration_scope);
307 if (!nested_declaration) {
78af2bcd 308 fprintf(fd, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q));
add40b62
MD
309 return NULL;
310 }
a3cca9e9 311 } else {
78af2bcd
MD
312 nested_declaration = ctf_type_specifier_list_visit(fd, depth,
313 type_specifier_list, declaration_scope, trace);
a3cca9e9 314 }
a3cca9e9
MD
315 }
316
e397791f
MD
317 if (!node_type_declarator)
318 return nested_declaration;
319
a3cca9e9
MD
320 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
321 if (node_type_declarator->u.type_declarator.u.id)
322 *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
323 else
324 *field_name = 0;
325 return nested_declaration;
326 } else {
327 struct declaration *declaration;
78af2bcd 328 struct ctf_node *length;
a3cca9e9
MD
329
330 /* TYPEDEC_NESTED */
331
332 /* create array/sequence, pass nested_declaration as child. */
78af2bcd
MD
333 length = node_type_declarator->u.type_declarator.u.nested.length;
334 if (!length) {
335 fprintf(fd, "[error] %s: expecting length type or value.\n", __func__);
a0720417
MD
336 return NULL;
337 }
78af2bcd 338 switch (length->type) {
a0720417
MD
339 case NODE_UNARY_EXPRESSION:
340 {
341 struct declaration_array *array_declaration;
342 size_t len;
343
78af2bcd
MD
344 if (length->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
345 fprintf(fd, "[error] %s: array: unexpected unary expression.\n", __func__);
a0720417 346 return NULL;
a3cca9e9 347 }
78af2bcd 348 len = length->u.unary_expression.u.unsigned_constant;
a0720417
MD
349 array_declaration = array_declaration_new(len, nested_declaration,
350 declaration_scope);
351 declaration = &array_declaration->p;
352 break;
353 }
354 case NODE_INTEGER:
355 case NODE_TYPE_SPECIFIER:
356 {
357 struct declaration_sequence *sequence_declaration;
358 struct declaration_integer *integer_declaration;
359 GQuark dummy_id;
360
361 declaration = ctf_type_declarator_visit(fd, depth,
362 length,
363 &dummy_id, NULL,
364 declaration_scope,
365 NULL, trace);
366 assert(declaration->id == CTF_TYPE_INTEGER);
367 integer_declaration = container_of(declaration, struct declaration_integer, p);
368 sequence_declaration = sequence_declaration_new(integer_declaration,
369 nested_declaration, declaration_scope);
370 declaration = &sequence_declaration->p;
371 break;
372 }
373 default:
374 assert(0);
a3cca9e9
MD
375 }
376
377 /* Pass it as content of outer container */
378 declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 379 type_specifier_list, field_name,
a3cca9e9 380 node_type_declarator->u.type_declarator.u.nested.type_declarator,
e397791f 381 declaration_scope, declaration, trace);
a3cca9e9
MD
382 return declaration;
383 }
384}
385
386static
8fdba45b 387int ctf_struct_type_declarators_visit(FILE *fd, int depth,
a3cca9e9 388 struct declaration_struct *struct_declaration,
78af2bcd 389 struct ctf_node *type_specifier_list,
a3cca9e9 390 struct cds_list_head *type_declarators,
e397791f
MD
391 struct declaration_scope *declaration_scope,
392 struct ctf_trace *trace)
a3cca9e9
MD
393{
394 struct ctf_node *iter;
395 GQuark field_name;
396
397 cds_list_for_each_entry(iter, type_declarators, siblings) {
398 struct declaration *field_declaration;
399
400 field_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 401 type_specifier_list,
a3cca9e9
MD
402 &field_name, iter,
403 struct_declaration->scope,
e397791f 404 NULL, trace);
a3cca9e9
MD
405 struct_declaration_add_field(struct_declaration,
406 g_quark_to_string(field_name),
407 field_declaration);
408 }
add40b62
MD
409 return 0;
410}
a3cca9e9 411
add40b62 412static
8fdba45b 413int ctf_variant_type_declarators_visit(FILE *fd, int depth,
a0720417 414 struct declaration_untagged_variant *untagged_variant_declaration,
78af2bcd 415 struct ctf_node *type_specifier_list,
add40b62 416 struct cds_list_head *type_declarators,
e397791f
MD
417 struct declaration_scope *declaration_scope,
418 struct ctf_trace *trace)
add40b62
MD
419{
420 struct ctf_node *iter;
421 GQuark field_name;
422
423 cds_list_for_each_entry(iter, type_declarators, siblings) {
424 struct declaration *field_declaration;
425
426 field_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 427 type_specifier_list,
add40b62 428 &field_name, iter,
a0720417 429 untagged_variant_declaration->scope,
e397791f 430 NULL, trace);
a0720417 431 untagged_variant_declaration_add_field(untagged_variant_declaration,
add40b62
MD
432 g_quark_to_string(field_name),
433 field_declaration);
434 }
a3cca9e9
MD
435 return 0;
436}
437
438static
8fdba45b 439int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
78af2bcd 440 struct ctf_node *type_specifier_list,
e397791f
MD
441 struct cds_list_head *type_declarators,
442 struct ctf_trace *trace)
a3cca9e9
MD
443{
444 struct ctf_node *iter;
445 GQuark identifier;
446
447 cds_list_for_each_entry(iter, type_declarators, siblings) {
448 struct declaration *type_declaration;
449 int ret;
450
451 type_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 452 type_specifier_list,
a3cca9e9 453 &identifier, iter,
e397791f 454 scope, NULL, trace);
a3cca9e9
MD
455 ret = register_declaration(identifier, type_declaration, scope);
456 if (ret) {
457 type_declaration->declaration_free(type_declaration);
458 return ret;
459 }
460 }
461 return 0;
462}
463
464static
8fdba45b 465int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
e397791f
MD
466 struct ctf_node *target, struct ctf_node *alias,
467 struct ctf_trace *trace)
a3cca9e9
MD
468{
469 struct declaration *type_declaration;
a0720417 470 struct ctf_node *node;
add40b62 471 GQuark dummy_id;
a3cca9e9 472 GQuark alias_q;
a0720417 473 int err;
a3cca9e9
MD
474
475 /* See ctf_visitor_type_declarator() in the semantic validator. */
476
477 /*
478 * Create target type declaration.
479 */
480
427c09b7 481 if (cds_list_empty(&target->u.typealias_target.type_declarators))
a0720417
MD
482 node = NULL;
483 else
427c09b7 484 node = _cds_list_first_entry(&target->u.typealias_target.type_declarators,
a0720417 485 struct ctf_node, siblings);
a3cca9e9 486 type_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 487 target->u.typealias_target.type_specifier_list,
a0720417 488 &dummy_id, node,
e397791f 489 scope, NULL, trace);
a3cca9e9 490 if (!type_declaration) {
78af2bcd 491 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
a3cca9e9
MD
492 err = -EINVAL;
493 goto error;
494 }
495 /*
496 * The semantic validator does not check whether the target is
497 * abstract or not (if it has an identifier). Check it here.
498 */
499 if (dummy_id != 0) {
78af2bcd 500 fprintf(fd, "[error] %s: expecting empty identifier\n", __func__);
a3cca9e9
MD
501 err = -EINVAL;
502 goto error;
503 }
504 /*
505 * Create alias identifier.
506 */
a3cca9e9
MD
507
508 node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
a0720417 509 struct ctf_node, siblings);
add40b62 510 alias_q = create_typealias_identifier(fd, depth,
78af2bcd 511 alias->u.typealias_alias.type_specifier_list, node);
a0720417
MD
512 err = register_declaration(alias_q, type_declaration, scope);
513 if (err)
a3cca9e9
MD
514 goto error;
515 return 0;
516
517error:
518 type_declaration->declaration_free(type_declaration);
a0720417 519 return err;
a3cca9e9
MD
520}
521
522static
8fdba45b 523int ctf_struct_declaration_list_visit(FILE *fd, int depth,
e397791f
MD
524 struct ctf_node *iter, struct declaration_struct *struct_declaration,
525 struct ctf_trace *trace)
a3cca9e9 526{
a3cca9e9
MD
527 int ret;
528
529 switch (iter->type) {
530 case NODE_TYPEDEF:
531 /* For each declarator, declare type and add type to struct declaration scope */
532 ret = ctf_typedef_visit(fd, depth,
533 struct_declaration->scope,
78af2bcd 534 iter->u._typedef.type_specifier_list,
e397791f 535 &iter->u._typedef.type_declarators, trace);
a3cca9e9
MD
536 if (ret)
537 return ret;
538 break;
539 case NODE_TYPEALIAS:
540 /* Declare type with declarator and add type to struct declaration scope */
541 ret = ctf_typealias_visit(fd, depth,
542 struct_declaration->scope,
543 iter->u.typealias.target,
e397791f 544 iter->u.typealias.alias, trace);
a3cca9e9
MD
545 if (ret)
546 return ret;
547 break;
548 case NODE_STRUCT_OR_VARIANT_DECLARATION:
549 /* Add field to structure declaration */
550 ret = ctf_struct_type_declarators_visit(fd, depth,
551 struct_declaration,
78af2bcd 552 iter->u.struct_or_variant_declaration.type_specifier_list,
a0720417
MD
553 &iter->u.struct_or_variant_declaration.type_declarators,
554 struct_declaration->scope, trace);
a3cca9e9
MD
555 if (ret)
556 return ret;
557 break;
558 default:
78af2bcd 559 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
a3cca9e9
MD
560 assert(0);
561 }
562 return 0;
563}
564
add40b62 565static
8fdba45b 566int ctf_variant_declaration_list_visit(FILE *fd, int depth,
a0720417
MD
567 struct ctf_node *iter,
568 struct declaration_untagged_variant *untagged_variant_declaration,
e397791f 569 struct ctf_trace *trace)
add40b62 570{
add40b62
MD
571 int ret;
572
573 switch (iter->type) {
574 case NODE_TYPEDEF:
575 /* For each declarator, declare type and add type to variant declaration scope */
576 ret = ctf_typedef_visit(fd, depth,
a0720417 577 untagged_variant_declaration->scope,
78af2bcd 578 iter->u._typedef.type_specifier_list,
e397791f 579 &iter->u._typedef.type_declarators, trace);
add40b62
MD
580 if (ret)
581 return ret;
582 break;
583 case NODE_TYPEALIAS:
584 /* Declare type with declarator and add type to variant declaration scope */
585 ret = ctf_typealias_visit(fd, depth,
a0720417 586 untagged_variant_declaration->scope,
add40b62 587 iter->u.typealias.target,
e397791f 588 iter->u.typealias.alias, trace);
add40b62
MD
589 if (ret)
590 return ret;
591 break;
592 case NODE_STRUCT_OR_VARIANT_DECLARATION:
593 /* Add field to structure declaration */
594 ret = ctf_variant_type_declarators_visit(fd, depth,
a0720417 595 untagged_variant_declaration,
78af2bcd 596 iter->u.struct_or_variant_declaration.type_specifier_list,
a0720417
MD
597 &iter->u.struct_or_variant_declaration.type_declarators,
598 untagged_variant_declaration->scope, trace);
add40b62
MD
599 if (ret)
600 return ret;
601 break;
602 default:
78af2bcd 603 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
add40b62
MD
604 assert(0);
605 }
606 return 0;
607}
608
a3cca9e9 609static
a0720417 610struct declaration *ctf_declaration_struct_visit(FILE *fd,
a3cca9e9 611 int depth, const char *name, struct cds_list_head *declaration_list,
e397791f
MD
612 int has_body, struct declaration_scope *declaration_scope,
613 struct ctf_trace *trace)
a3cca9e9 614{
a3cca9e9
MD
615 struct declaration_struct *struct_declaration;
616 struct ctf_node *iter;
a0720417 617 int ret;
a3cca9e9
MD
618
619 /*
620 * For named struct (without body), lookup in
621 * declaration scope. Don't take reference on struct
622 * declaration: ref is only taken upon definition.
623 */
624 if (!has_body) {
625 assert(name);
626 struct_declaration =
627 lookup_struct_declaration(g_quark_from_string(name),
628 declaration_scope);
a0720417 629 return &struct_declaration->p;
a3cca9e9
MD
630 } else {
631 /* For unnamed struct, create type */
632 /* For named struct (with body), create type and add to declaration scope */
633 if (name) {
634 if (lookup_struct_declaration(g_quark_from_string(name),
635 declaration_scope)) {
636
78af2bcd 637 fprintf(fd, "[error] %s: struct %s already declared in scope\n", __func__, name);
a3cca9e9
MD
638 return NULL;
639 }
640 }
a0720417 641 struct_declaration = struct_declaration_new(declaration_scope);
a3cca9e9 642 cds_list_for_each_entry(iter, declaration_list, siblings) {
e397791f
MD
643 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
644 struct_declaration, trace);
a3cca9e9
MD
645 if (ret)
646 goto error;
647 }
648 if (name) {
649 ret = register_struct_declaration(g_quark_from_string(name),
650 struct_declaration,
651 declaration_scope);
652 assert(!ret);
653 }
a0720417 654 return &struct_declaration->p;
a3cca9e9
MD
655 }
656error:
657 struct_declaration->p.declaration_free(&struct_declaration->p);
658 return NULL;
659}
660
05628561 661static
a0720417
MD
662struct declaration *ctf_declaration_variant_visit(FILE *fd,
663 int depth, const char *name, const char *choice,
664 struct cds_list_head *declaration_list,
e397791f
MD
665 int has_body, struct declaration_scope *declaration_scope,
666 struct ctf_trace *trace)
05628561 667{
a0720417 668 struct declaration_untagged_variant *untagged_variant_declaration;
add40b62
MD
669 struct declaration_variant *variant_declaration;
670 struct ctf_node *iter;
a0720417 671 int ret;
de47353a 672
add40b62
MD
673 /*
674 * For named variant (without body), lookup in
675 * declaration scope. Don't take reference on variant
676 * declaration: ref is only taken upon definition.
677 */
678 if (!has_body) {
679 assert(name);
a0720417 680 untagged_variant_declaration =
add40b62
MD
681 lookup_variant_declaration(g_quark_from_string(name),
682 declaration_scope);
add40b62 683 } else {
de47353a 684 /* For unnamed variant, create type */
add40b62
MD
685 /* For named variant (with body), create type and add to declaration scope */
686 if (name) {
687 if (lookup_variant_declaration(g_quark_from_string(name),
688 declaration_scope)) {
689
78af2bcd 690 fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name);
add40b62
MD
691 return NULL;
692 }
693 }
a0720417 694 untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope);
add40b62 695 cds_list_for_each_entry(iter, declaration_list, siblings) {
e397791f 696 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
a0720417 697 untagged_variant_declaration, trace);
add40b62
MD
698 if (ret)
699 goto error;
700 }
701 if (name) {
702 ret = register_variant_declaration(g_quark_from_string(name),
a0720417 703 untagged_variant_declaration,
add40b62
MD
704 declaration_scope);
705 assert(!ret);
706 }
a0720417
MD
707 }
708 /*
709 * if tagged, create tagged variant and return. else return
710 * untagged variant.
711 */
712 if (!choice) {
713 return &untagged_variant_declaration->p;
714 } else {
715 variant_declaration = variant_declaration_new(untagged_variant_declaration, choice);
716 if (!variant_declaration)
717 goto error;
718 declaration_unref(&untagged_variant_declaration->p);
719 return &variant_declaration->p;
de47353a 720 }
add40b62 721error:
a0720417 722 untagged_variant_declaration->p.declaration_free(&variant_declaration->p);
add40b62 723 return NULL;
05628561
MD
724}
725
05628561 726static
8fdba45b 727int ctf_enumerator_list_visit(FILE *fd, int depth,
add40b62
MD
728 struct ctf_node *enumerator,
729 struct declaration_enum *enum_declaration)
730{
1cfda062
MD
731 GQuark q;
732 struct ctf_node *iter;
733
734 q = g_quark_from_string(enumerator->u.enumerator.id);
a0720417 735 if (enum_declaration->integer_declaration->signedness) {
1cfda062
MD
736 int64_t start, end;
737 int nr_vals = 0;
738
a0720417 739 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
1cfda062
MD
740 int64_t *target;
741
742 assert(iter->type == NODE_UNARY_EXPRESSION);
743 if (nr_vals == 0)
744 target = &start;
745 else
746 target = &end;
747
748 switch (iter->u.unary_expression.type) {
749 case UNARY_SIGNED_CONSTANT:
750 *target = iter->u.unary_expression.u.signed_constant;
751 break;
752 case UNARY_UNSIGNED_CONSTANT:
753 *target = iter->u.unary_expression.u.unsigned_constant;
754 break;
755 default:
78af2bcd 756 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
757 return -EINVAL;
758 }
759 if (nr_vals > 1) {
78af2bcd 760 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
761 return -EINVAL;
762 }
763 nr_vals++;
764 }
765 if (nr_vals == 1)
766 end = start;
767 enum_signed_insert(enum_declaration, start, end, q);
a0720417 768 } else {
1cfda062
MD
769 uint64_t start, end;
770 int nr_vals = 0;
771
a0720417
MD
772 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
773 uint64_t *target;
1cfda062
MD
774
775 assert(iter->type == NODE_UNARY_EXPRESSION);
776 if (nr_vals == 0)
777 target = &start;
778 else
779 target = &end;
780
781 switch (iter->u.unary_expression.type) {
782 case UNARY_UNSIGNED_CONSTANT:
783 *target = iter->u.unary_expression.u.unsigned_constant;
784 break;
785 case UNARY_SIGNED_CONSTANT:
786 /*
787 * We don't accept signed constants for enums with unsigned
788 * container type.
789 */
78af2bcd 790 fprintf(fd, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
1cfda062
MD
791 return -EINVAL;
792 default:
78af2bcd 793 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
794 return -EINVAL;
795 }
796 if (nr_vals > 1) {
78af2bcd 797 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
798 return -EINVAL;
799 }
800 nr_vals++;
801 }
802 if (nr_vals == 1)
803 end = start;
804 enum_unsigned_insert(enum_declaration, start, end, q);
805 }
add40b62
MD
806 return 0;
807}
808
809static
8fdba45b 810struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
add40b62 811 const char *name,
78af2bcd 812 struct ctf_node *container_type,
add40b62 813 struct cds_list_head *enumerator_list,
1cfda062
MD
814 int has_body,
815 struct declaration_scope *declaration_scope,
816 struct ctf_trace *trace)
05628561 817{
add40b62
MD
818 struct declaration *declaration;
819 struct declaration_enum *enum_declaration;
820 struct declaration_integer *integer_declaration;
78af2bcd 821 struct ctf_node *iter;
1cfda062 822 GQuark dummy_id;
a0720417 823 int ret;
add40b62 824
05628561 825 /*
add40b62
MD
826 * For named enum (without body), lookup in
827 * declaration scope. Don't take reference on enum
828 * declaration: ref is only taken upon definition.
05628561 829 */
add40b62
MD
830 if (!has_body) {
831 assert(name);
832 enum_declaration =
833 lookup_enum_declaration(g_quark_from_string(name),
834 declaration_scope);
a0720417 835 return &enum_declaration->p;
add40b62
MD
836 } else {
837 /* For unnamed enum, create type */
838 /* For named enum (with body), create type and add to declaration scope */
839 if (name) {
840 if (lookup_enum_declaration(g_quark_from_string(name),
841 declaration_scope)) {
842
78af2bcd 843 fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name);
add40b62
MD
844 return NULL;
845 }
846 }
78af2bcd 847 if (!container_type) {
6743829a
MD
848 declaration = lookup_declaration(g_quark_from_static_string("int"),
849 declaration_scope);
850 if (!declaration) {
851 fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__);
852 return NULL;
853 }
854 } else {
855 declaration = ctf_type_declarator_visit(fd, depth,
856 container_type,
857 &dummy_id, NULL,
858 declaration_scope,
859 NULL, trace);
1cfda062 860 }
30ea18a1
MD
861 if (!declaration) {
862 fprintf(fd, "[error] %s: unable to create container type for enumeration\n", __func__);
863 return NULL;
864 }
865 if (declaration->id != CTF_TYPE_INTEGER) {
866 fprintf(fd, "[error] %s: container type for enumeration is not integer\n", __func__);
867 return NULL;
1cfda062 868 }
30ea18a1 869 integer_declaration = container_of(declaration, struct declaration_integer, p);
a0720417 870 enum_declaration = enum_declaration_new(integer_declaration);
add40b62
MD
871 declaration_unref(&integer_declaration->p); /* leave ref to enum */
872 cds_list_for_each_entry(iter, enumerator_list, siblings) {
873 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration);
874 if (ret)
875 goto error;
876 }
877 if (name) {
878 ret = register_enum_declaration(g_quark_from_string(name),
879 enum_declaration,
880 declaration_scope);
881 assert(!ret);
882 }
a0720417 883 return &enum_declaration->p;
05628561 884 }
add40b62
MD
885error:
886 enum_declaration->p.declaration_free(&enum_declaration->p);
887 return NULL;
05628561
MD
888}
889
890static
8fdba45b 891struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
78af2bcd 892 struct ctf_node *type_specifier_list,
d20f5e59 893 struct declaration_scope *declaration_scope)
05628561 894{
add40b62
MD
895 GString *str;
896 struct declaration *declaration;
a0720417
MD
897 char *str_c;
898 int ret;
899 GQuark id_q;
05628561 900
a0720417 901 str = g_string_new("");
78af2bcd 902 ret = visit_type_specifier_list(fd, type_specifier_list, str);
add40b62
MD
903 if (ret)
904 return NULL;
905 str_c = g_string_free(str, FALSE);
906 id_q = g_quark_from_string(str_c);
907 g_free(str_c);
908 declaration = lookup_declaration(id_q, declaration_scope);
909 return declaration;
910}
911
ab4cf058
MD
912/*
913 * Returns 0/1 boolean, or < 0 on error.
914 */
915static
a0720417 916int get_boolean(FILE *fd, int depth, struct ctf_node *unary_expression)
ab4cf058
MD
917{
918 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
78af2bcd 919 fprintf(fd, "[error] %s: expecting unary expression\n",
ab4cf058
MD
920 __func__);
921 return -EINVAL;
922 }
923 switch (unary_expression->u.unary_expression.type) {
924 case UNARY_UNSIGNED_CONSTANT:
925 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
926 return 0;
927 else
928 return 1;
929 case UNARY_SIGNED_CONSTANT:
930 if (unary_expression->u.unary_expression.u.signed_constant == 0)
931 return 0;
932 else
933 return 1;
934 case UNARY_STRING:
935 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
936 return 1;
937 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
938 return 1;
939 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
940 return 0;
941 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
942 return 0;
943 else {
78af2bcd 944 fprintf(fd, "[error] %s: unexpected string \"%s\"\n",
ab4cf058
MD
945 __func__, unary_expression->u.unary_expression.u.string);
946 return -EINVAL;
947 }
948 break;
949 default:
78af2bcd 950 fprintf(fd, "[error] %s: unexpected unary expression type\n",
ab4cf058
MD
951 __func__);
952 return -EINVAL;
953 }
954
955}
956
957static
a0720417
MD
958int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
959 struct ctf_trace *trace)
ab4cf058
MD
960{
961 int byte_order;
962
963 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
78af2bcd 964 fprintf(fd, "[error] %s: byte_order: expecting string\n",
ab4cf058
MD
965 __func__);
966 return -EINVAL;
967 }
968 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
969 byte_order = trace->byte_order;
970 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
971 byte_order = BIG_ENDIAN;
972 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
973 byte_order = BIG_ENDIAN;
974 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
975 byte_order = LITTLE_ENDIAN;
976 else {
78af2bcd 977 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
a0720417 978 __func__, unary_expression->u.unary_expression.u.string);
ab4cf058
MD
979 return -EINVAL;
980 }
981 return byte_order;
982}
983
add40b62 984static
8fdba45b 985struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
ab4cf058
MD
986 struct cds_list_head *expressions,
987 struct ctf_trace *trace)
add40b62 988{
a0720417 989 struct ctf_node *expression;
ab4cf058
MD
990 uint64_t alignment, size;
991 int byte_order = trace->byte_order;
992 int signedness = 0;
add40b62
MD
993 int has_alignment = 0, has_size = 0;
994 struct declaration_integer *integer_declaration;
995
996 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 997 struct ctf_node *left, *right;
add40b62 998
a0720417
MD
999 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1000 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
add40b62
MD
1001 assert(left->u.unary_expression.type == UNARY_STRING);
1002 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
ab4cf058
MD
1003 signedness = get_boolean(fd, depth, right);
1004 if (signedness < 0)
1005 return NULL;
add40b62 1006 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
a0720417 1007 byte_order = get_byte_order(fd, depth, right, trace);
ab4cf058
MD
1008 if (byte_order < 0)
1009 return NULL;
add40b62 1010 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
ab4cf058 1011 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1012 fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
ab4cf058
MD
1013 __func__);
1014 return NULL;
1015 }
1016 size = right->u.unary_expression.u.unsigned_constant;
add40b62
MD
1017 has_size = 1;
1018 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
ab4cf058 1019 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1020 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
ab4cf058
MD
1021 __func__);
1022 return NULL;
1023 }
1024 alignment = right->u.unary_expression.u.unsigned_constant;
add40b62
MD
1025 has_alignment = 1;
1026 } else {
78af2bcd 1027 fprintf(fd, "[error] %s: unknown attribute name %s\n",
add40b62
MD
1028 __func__, left->u.unary_expression.u.string);
1029 return NULL;
1030 }
05628561 1031 }
add40b62 1032 if (!has_size) {
78af2bcd 1033 fprintf(fd, "[error] %s: missing size attribute\n", __func__);
add40b62
MD
1034 return NULL;
1035 }
ab4cf058
MD
1036 if (!has_alignment) {
1037 if (size % CHAR_BIT) {
1038 /* bit-packed alignment */
1039 alignment = 1;
1040 } else {
1041 /* byte-packed alignment */
1042 alignment = CHAR_BIT;
1043 }
1044 }
add40b62
MD
1045 integer_declaration = integer_declaration_new(size,
1046 byte_order, signedness, alignment);
1047 return &integer_declaration->p;
05628561
MD
1048}
1049
ab4cf058 1050static
8fdba45b 1051struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
ab4cf058
MD
1052 struct cds_list_head *expressions,
1053 struct ctf_trace *trace)
1054{
a0720417 1055 struct ctf_node *expression;
ab4cf058
MD
1056 uint64_t alignment, exp_dig, mant_dig, byte_order = trace->byte_order;
1057 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1058 struct declaration_float *float_declaration;
1059
1060 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 1061 struct ctf_node *left, *right;
ab4cf058 1062
a0720417
MD
1063 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1064 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
ab4cf058
MD
1065 assert(left->u.unary_expression.type == UNARY_STRING);
1066 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
a0720417 1067 byte_order = get_byte_order(fd, depth, right, trace);
ab4cf058
MD
1068 if (byte_order < 0)
1069 return NULL;
1070 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1071 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1072 fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
ab4cf058
MD
1073 __func__);
1074 return NULL;
1075 }
1076 exp_dig = right->u.unary_expression.u.unsigned_constant;
1077 has_exp_dig = 1;
1078 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1079 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1080 fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
ab4cf058
MD
1081 __func__);
1082 return NULL;
1083 }
1084 mant_dig = right->u.unary_expression.u.unsigned_constant;
1085 has_mant_dig = 1;
1086 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1087 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1088 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
ab4cf058
MD
1089 __func__);
1090 return NULL;
1091 }
1092 alignment = right->u.unary_expression.u.unsigned_constant;
1093 has_alignment = 1;
1094 } else {
78af2bcd 1095 fprintf(fd, "[error] %s: unknown attribute name %s\n",
ab4cf058
MD
1096 __func__, left->u.unary_expression.u.string);
1097 return NULL;
1098 }
1099 }
1100 if (!has_mant_dig) {
78af2bcd 1101 fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
ab4cf058
MD
1102 return NULL;
1103 }
1104 if (!has_exp_dig) {
78af2bcd 1105 fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
ab4cf058
MD
1106 return NULL;
1107 }
1108 if (!has_alignment) {
1109 if ((mant_dig + exp_dig) % CHAR_BIT) {
1110 /* bit-packed alignment */
1111 alignment = 1;
1112 } else {
1113 /* byte-packed alignment */
1114 alignment = CHAR_BIT;
1115 }
1116 }
1117 float_declaration = float_declaration_new(mant_dig, exp_dig,
1118 byte_order, alignment);
1119 return &float_declaration->p;
1120}
1121
1122static
8fdba45b 1123struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
ab4cf058
MD
1124 struct cds_list_head *expressions,
1125 struct ctf_trace *trace)
1126{
a0720417 1127 struct ctf_node *expression;
ab4cf058
MD
1128 const char *encoding_c = NULL;
1129 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1130 struct declaration_string *string_declaration;
1131
1132 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 1133 struct ctf_node *left, *right;
ab4cf058 1134
a0720417
MD
1135 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1136 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
ab4cf058
MD
1137 assert(left->u.unary_expression.type == UNARY_STRING);
1138 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
a0720417 1139 if (right->u.unary_expression.type != UNARY_STRING) {
78af2bcd 1140 fprintf(fd, "[error] %s: encoding: expecting string\n",
ab4cf058
MD
1141 __func__);
1142 return NULL;
1143 }
1144 encoding_c = right->u.unary_expression.u.string;
1145 } else {
78af2bcd 1146 fprintf(fd, "[error] %s: unknown attribute name %s\n",
ab4cf058
MD
1147 __func__, left->u.unary_expression.u.string);
1148 return NULL;
1149 }
1150 }
1151 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1152 encoding = CTF_STRING_ASCII;
1153 string_declaration = string_declaration_new(encoding);
1154 return &string_declaration->p;
1155}
1156
1157
05628561 1158static
78af2bcd
MD
1159struct declaration *ctf_type_specifier_list_visit(FILE *fd,
1160 int depth, struct ctf_node *type_specifier_list,
ab4cf058
MD
1161 struct declaration_scope *declaration_scope,
1162 struct ctf_trace *trace)
05628561 1163{
a0720417 1164 struct ctf_node *first;
78af2bcd 1165 struct ctf_node *node;
d20f5e59 1166
427c09b7
MD
1167 assert(type_specifier_list->type == NODE_TYPE_SPECIFIER_LIST);
1168
78af2bcd 1169 first = _cds_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
05628561 1170
78af2bcd
MD
1171 assert(first->type == NODE_TYPE_SPECIFIER);
1172
1173 node = first->u.type_specifier.node;
1174
1175 switch (first->u.type_specifier.type) {
1176 case TYPESPEC_FLOATING_POINT:
1177 return ctf_declaration_floating_point_visit(fd, depth,
1178 &node->u.floating_point.expressions, trace);
1179 case TYPESPEC_INTEGER:
1180 return ctf_declaration_integer_visit(fd, depth,
1181 &node->u.integer.expressions, trace);
1182 case TYPESPEC_STRING:
1183 return ctf_declaration_string_visit(fd, depth,
5039b4cc 1184 &node->u.string.expressions, trace);
78af2bcd 1185 case TYPESPEC_STRUCT:
add40b62 1186 return ctf_declaration_struct_visit(fd, depth,
78af2bcd
MD
1187 node->u._struct.name,
1188 &node->u._struct.declaration_list,
1189 node->u._struct.has_body,
ab4cf058
MD
1190 declaration_scope,
1191 trace);
78af2bcd 1192 case TYPESPEC_VARIANT:
add40b62 1193 return ctf_declaration_variant_visit(fd, depth,
78af2bcd
MD
1194 node->u.variant.name,
1195 node->u.variant.choice,
1196 &node->u.variant.declaration_list,
1197 node->u.variant.has_body,
ab4cf058
MD
1198 declaration_scope,
1199 trace);
78af2bcd 1200 case TYPESPEC_ENUM:
add40b62 1201 return ctf_declaration_enum_visit(fd, depth,
78af2bcd
MD
1202 node->u._enum.enum_id,
1203 node->u._enum.container_type,
1204 &node->u._enum.enumerator_list,
1205 node->u._enum.has_body,
1cfda062 1206 declaration_scope,
ab4cf058 1207 trace);
78af2bcd
MD
1208
1209 case TYPESPEC_VOID:
1210 case TYPESPEC_CHAR:
1211 case TYPESPEC_SHORT:
1212 case TYPESPEC_INT:
1213 case TYPESPEC_LONG:
1214 case TYPESPEC_FLOAT:
1215 case TYPESPEC_DOUBLE:
1216 case TYPESPEC_SIGNED:
1217 case TYPESPEC_UNSIGNED:
1218 case TYPESPEC_BOOL:
1219 case TYPESPEC_COMPLEX:
1220 case TYPESPEC_IMAGINARY:
1221 case TYPESPEC_CONST:
1222 case TYPESPEC_ID_TYPE:
add40b62 1223 return ctf_declaration_type_specifier_visit(fd, depth,
78af2bcd 1224 type_specifier_list, declaration_scope);
a0720417 1225 default:
78af2bcd 1226 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
a0720417 1227 return NULL;
add40b62 1228 }
05628561
MD
1229}
1230
1231static
1232int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
1233{
1234 int ret = 0;
1235
1236 switch (node->type) {
1237 case NODE_TYPEDEF:
1238 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1239 event->declaration_scope,
78af2bcd 1240 node->u._typedef.type_specifier_list,
05628561 1241 &node->u._typedef.type_declarators,
a0720417 1242 trace);
05628561
MD
1243 if (ret)
1244 return ret;
1245 break;
1246 case NODE_TYPEALIAS:
1247 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1248 event->declaration_scope,
1249 node->u.typealias.target, node->u.typealias.alias,
1250 trace);
05628561
MD
1251 if (ret)
1252 return ret;
1253 break;
1254 case NODE_CTF_EXPRESSION:
1255 {
1256 char *left;
1257
1258 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1259 if (!strcmp(left, "name")) {
1260 char *right;
1261
427c09b7
MD
1262 if (CTF_EVENT_FIELD_IS_SET(event, name)) {
1263 fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
05628561 1264 return -EPERM;
427c09b7 1265 }
05628561
MD
1266 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1267 if (!right) {
78af2bcd 1268 fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
05628561
MD
1269 return -EINVAL;
1270 }
1271 event->name = g_quark_from_string(right);
41253107 1272 g_free(right);
05628561
MD
1273 CTF_EVENT_SET_FIELD(event, name);
1274 } else if (!strcmp(left, "id")) {
427c09b7
MD
1275 if (CTF_EVENT_FIELD_IS_SET(event, id)) {
1276 fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
05628561 1277 return -EPERM;
427c09b7 1278 }
05628561
MD
1279 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1280 if (ret) {
78af2bcd 1281 fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
05628561
MD
1282 return -EINVAL;
1283 }
1284 CTF_EVENT_SET_FIELD(event, id);
1285 } else if (!strcmp(left, "stream_id")) {
427c09b7
MD
1286 if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1287 fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
05628561 1288 return -EPERM;
427c09b7 1289 }
05628561
MD
1290 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1291 if (ret) {
78af2bcd 1292 fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
05628561
MD
1293 return -EINVAL;
1294 }
1295 event->stream = trace_stream_lookup(trace, event->stream_id);
1296 if (!event->stream) {
78af2bcd 1297 fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
05628561
MD
1298 return -EINVAL;
1299 }
05628561
MD
1300 CTF_EVENT_SET_FIELD(event, stream_id);
1301 } else if (!strcmp(left, "context")) {
1302 struct declaration *declaration;
1303
427c09b7
MD
1304 if (event->context_decl) {
1305 fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
1306 return -EINVAL;
1307 }
78af2bcd
MD
1308 declaration = ctf_type_specifier_list_visit(fd, depth,
1309 _cds_list_first_entry(&node->u.ctf_expression.right,
1310 struct ctf_node, siblings),
ab4cf058 1311 event->declaration_scope, trace);
05628561
MD
1312 if (!declaration)
1313 return -EPERM;
a0720417 1314 if (declaration->id != CTF_TYPE_STRUCT)
05628561 1315 return -EPERM;
9e29e16e 1316 event->context_decl = container_of(declaration, struct declaration_struct, p);
05628561
MD
1317 } else if (!strcmp(left, "fields")) {
1318 struct declaration *declaration;
1319
427c09b7
MD
1320 if (event->fields_decl) {
1321 fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
1322 return -EINVAL;
1323 }
78af2bcd
MD
1324 declaration = ctf_type_specifier_list_visit(fd, depth,
1325 _cds_list_first_entry(&node->u.ctf_expression.right,
1326 struct ctf_node, siblings),
ab4cf058 1327 event->declaration_scope, trace);
05628561
MD
1328 if (!declaration)
1329 return -EPERM;
a0720417 1330 if (declaration->id != CTF_TYPE_STRUCT)
05628561 1331 return -EPERM;
9e29e16e 1332 event->fields_decl = container_of(declaration, struct declaration_struct, p);
05628561 1333 }
41253107 1334 g_free(left);
05628561
MD
1335 break;
1336 }
1337 default:
1338 return -EPERM;
1339 /* TODO: declaration specifier should be added. */
1340 }
1341
1342 return 0;
1343}
1344
1345static
1346int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1347 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1348{
1349 int ret = 0;
1350 struct ctf_node *iter;
1351 struct ctf_event *event;
9e29e16e 1352 struct definition_scope *parent_def_scope;
05628561
MD
1353
1354 event = g_new0(struct ctf_event, 1);
d20f5e59 1355 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561
MD
1356 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1357 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1358 if (ret)
1359 goto error;
1360 }
1361 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1362 ret = -EPERM;
427c09b7 1363 fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
05628561
MD
1364 goto error;
1365 }
1366 if (!CTF_EVENT_FIELD_IS_SET(event, id)) {
1367 ret = -EPERM;
427c09b7 1368 fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
05628561
MD
1369 goto error;
1370 }
1371 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1372 ret = -EPERM;
427c09b7 1373 fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
05628561
MD
1374 goto error;
1375 }
1376 if (event->stream->events_by_id->len <= event->id)
1377 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1378 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1379 g_hash_table_insert(event->stream->event_quark_to_id,
1380 (gpointer)(unsigned long) event->name,
1381 &event->id);
a0720417 1382 parent_def_scope = event->stream->definition_scope;
9e29e16e
MD
1383 if (event->context_decl) {
1384 event->context =
a0720417
MD
1385 container_of(
1386 event->context_decl->p.definition_new(&event->context_decl->p,
1387 parent_def_scope, 0, 0),
1388 struct definition_struct, p);
6a36ddca
MD
1389 set_dynamic_definition_scope(&event->context->p,
1390 event->context->scope,
d00d17d1 1391 "event.context");
9e29e16e 1392 parent_def_scope = event->context->scope;
a0720417 1393 declaration_unref(&event->context_decl->p);
9e29e16e
MD
1394 }
1395 if (event->fields_decl) {
1396 event->fields =
a0720417
MD
1397 container_of(
1398 event->fields_decl->p.definition_new(&event->fields_decl->p,
1399 parent_def_scope, 0, 0),
1400 struct definition_struct, p);
6a36ddca
MD
1401 set_dynamic_definition_scope(&event->fields->p,
1402 event->fields->scope,
d00d17d1 1403 "event.fields");
9e29e16e 1404 parent_def_scope = event->fields->scope;
a0720417 1405 declaration_unref(&event->fields_decl->p);
9e29e16e 1406 }
05628561
MD
1407 return 0;
1408
1409error:
a0720417
MD
1410 declaration_unref(&event->fields_decl->p);
1411 declaration_unref(&event->context_decl->p);
d20f5e59 1412 free_declaration_scope(event->declaration_scope);
05628561
MD
1413 g_free(event);
1414 return ret;
1415}
1416
1417
1418static
1419int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
1420{
1421 int ret = 0;
1422
1423 switch (node->type) {
1424 case NODE_TYPEDEF:
1425 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1426 stream->declaration_scope,
78af2bcd 1427 node->u._typedef.type_specifier_list,
05628561 1428 &node->u._typedef.type_declarators,
a0720417 1429 trace);
05628561
MD
1430 if (ret)
1431 return ret;
1432 break;
1433 case NODE_TYPEALIAS:
1434 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1435 stream->declaration_scope,
1436 node->u.typealias.target, node->u.typealias.alias,
1437 trace);
05628561
MD
1438 if (ret)
1439 return ret;
1440 break;
1441 case NODE_CTF_EXPRESSION:
1442 {
1443 char *left;
1444
1445 left = concatenate_unary_strings(&node->u.ctf_expression.left);
427c09b7
MD
1446 if (!strcmp(left, "id")) {
1447 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1448 fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
05628561 1449 return -EPERM;
427c09b7 1450 }
a0720417 1451 ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
05628561 1452 if (ret) {
427c09b7 1453 fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
05628561
MD
1454 return -EINVAL;
1455 }
a0720417 1456 CTF_STREAM_SET_FIELD(stream, stream_id);
9e29e16e 1457 } else if (!strcmp(left, "event.header")) {
05628561
MD
1458 struct declaration *declaration;
1459
427c09b7
MD
1460 if (stream->event_header_decl) {
1461 fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
1462 return -EINVAL;
1463 }
78af2bcd
MD
1464 declaration = ctf_type_specifier_list_visit(fd, depth,
1465 _cds_list_first_entry(&node->u.ctf_expression.right,
1466 struct ctf_node, siblings),
a0720417 1467 stream->declaration_scope, trace);
05628561
MD
1468 if (!declaration)
1469 return -EPERM;
a0720417 1470 if (declaration->id != CTF_TYPE_STRUCT)
05628561 1471 return -EPERM;
9e29e16e
MD
1472 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1473 } else if (!strcmp(left, "event.context")) {
05628561
MD
1474 struct declaration *declaration;
1475
427c09b7
MD
1476 if (stream->event_context_decl) {
1477 fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
1478 return -EINVAL;
1479 }
78af2bcd
MD
1480 declaration = ctf_type_specifier_list_visit(fd, depth,
1481 _cds_list_first_entry(&node->u.ctf_expression.right,
1482 struct ctf_node, siblings),
ab4cf058 1483 stream->declaration_scope, trace);
05628561
MD
1484 if (!declaration)
1485 return -EPERM;
a0720417 1486 if (declaration->id != CTF_TYPE_STRUCT)
05628561 1487 return -EPERM;
9e29e16e
MD
1488 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1489 } else if (!strcmp(left, "packet.context")) {
05628561
MD
1490 struct declaration *declaration;
1491
427c09b7
MD
1492 if (stream->packet_context_decl) {
1493 fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
1494 return -EINVAL;
1495 }
78af2bcd
MD
1496 declaration = ctf_type_specifier_list_visit(fd, depth,
1497 _cds_list_first_entry(&node->u.ctf_expression.right,
1498 struct ctf_node, siblings),
ab4cf058 1499 stream->declaration_scope, trace);
05628561
MD
1500 if (!declaration)
1501 return -EPERM;
a0720417 1502 if (declaration->id != CTF_TYPE_STRUCT)
05628561 1503 return -EPERM;
9e29e16e 1504 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
05628561 1505 }
41253107 1506 g_free(left);
05628561
MD
1507 break;
1508 }
1509 default:
1510 return -EPERM;
1511 /* TODO: declaration specifier should be added. */
1512 }
1513
1514 return 0;
1515}
1516
1517static
1518int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1519 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1520{
1521 int ret = 0;
1522 struct ctf_node *iter;
1523 struct ctf_stream *stream;
9e29e16e 1524 struct definition_scope *parent_def_scope;
05628561
MD
1525
1526 stream = g_new0(struct ctf_stream, 1);
d20f5e59 1527 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561 1528 stream->events_by_id = g_ptr_array_new();
068665f5 1529 stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
05628561
MD
1530 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1531 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1532 if (ret)
1533 goto error;
1534 }
a0720417 1535 if (!CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
05628561 1536 ret = -EPERM;
427c09b7 1537 fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
05628561
MD
1538 goto error;
1539 }
1540 if (trace->streams->len <= stream->stream_id)
1541 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1542 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
9e29e16e 1543
41253107 1544 parent_def_scope = NULL;
9e29e16e
MD
1545 if (stream->packet_context_decl) {
1546 stream->packet_context =
a0720417
MD
1547 container_of(
1548 stream->packet_context_decl->p.definition_new(&stream->packet_context_decl->p,
1549 parent_def_scope, 0, 0),
1550 struct definition_struct, p);
6a36ddca
MD
1551 set_dynamic_definition_scope(&stream->packet_context->p,
1552 stream->packet_context->scope,
d00d17d1 1553 "stream.packet.context");
9e29e16e 1554 parent_def_scope = stream->packet_context->scope;
a0720417 1555 declaration_unref(&stream->packet_context_decl->p);
9e29e16e
MD
1556 }
1557 if (stream->event_header_decl) {
1558 stream->event_header =
a0720417
MD
1559 container_of(
1560 stream->event_header_decl->p.definition_new(&stream->event_header_decl->p,
1561 parent_def_scope, 0, 0),
1562 struct definition_struct, p);
6a36ddca
MD
1563 set_dynamic_definition_scope(&stream->event_header->p,
1564 stream->event_header->scope,
d00d17d1 1565 "stream.event.header");
9e29e16e 1566 parent_def_scope = stream->event_header->scope;
a0720417 1567 declaration_unref(&stream->event_header_decl->p);
9e29e16e
MD
1568 }
1569 if (stream->event_context_decl) {
1570 stream->event_context =
a0720417
MD
1571 container_of(
1572 stream->event_context_decl->p.definition_new(&stream->event_context_decl->p,
1573 parent_def_scope, 0, 0),
1574 struct definition_struct, p);
6a36ddca
MD
1575 set_dynamic_definition_scope(&stream->event_context->p,
1576 stream->event_context->scope,
d00d17d1 1577 "stream.event.context");
9e29e16e 1578 parent_def_scope = stream->event_context->scope;
a0720417 1579 declaration_unref(&stream->event_context_decl->p);
9e29e16e 1580 }
41253107 1581 stream->definition_scope = parent_def_scope;
9e29e16e 1582
05628561
MD
1583 return 0;
1584
1585error:
a0720417
MD
1586 declaration_unref(&stream->event_header_decl->p);
1587 declaration_unref(&stream->event_context_decl->p);
1588 declaration_unref(&stream->packet_context_decl->p);
05628561 1589 g_ptr_array_free(stream->events_by_id, TRUE);
a0720417 1590 g_hash_table_destroy(stream->event_quark_to_id);
d20f5e59 1591 free_declaration_scope(stream->declaration_scope);
05628561
MD
1592 g_free(stream);
1593 return ret;
1594}
1595
1596static
1597int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1598{
1599 int ret = 0;
1600
1601 switch (node->type) {
1602 case NODE_TYPEDEF:
1603 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1604 trace->declaration_scope,
78af2bcd 1605 node->u._typedef.type_specifier_list,
05628561 1606 &node->u._typedef.type_declarators,
a0720417 1607 trace);
05628561
MD
1608 if (ret)
1609 return ret;
1610 break;
1611 case NODE_TYPEALIAS:
1612 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1613 trace->declaration_scope,
1614 node->u.typealias.target, node->u.typealias.alias,
1615 trace);
05628561
MD
1616 if (ret)
1617 return ret;
1618 break;
1619 case NODE_CTF_EXPRESSION:
1620 {
1621 char *left;
1622
1623 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1624 if (!strcmp(left, "major")) {
427c09b7
MD
1625 if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
1626 fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
05628561 1627 return -EPERM;
427c09b7 1628 }
05628561
MD
1629 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
1630 if (ret) {
78af2bcd 1631 fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
05628561
MD
1632 return -EINVAL;
1633 }
a0720417 1634 CTF_TRACE_SET_FIELD(trace, major);
05628561 1635 } else if (!strcmp(left, "minor")) {
427c09b7
MD
1636 if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
1637 fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
05628561 1638 return -EPERM;
427c09b7 1639 }
05628561
MD
1640 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
1641 if (ret) {
78af2bcd 1642 fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
05628561
MD
1643 return -EINVAL;
1644 }
a0720417 1645 CTF_TRACE_SET_FIELD(trace, minor);
05628561 1646 } else if (!strcmp(left, "word_size")) {
427c09b7
MD
1647 if (CTF_TRACE_FIELD_IS_SET(trace, word_size)) {
1648 fprintf(fd, "[error] %s: word_size already declared in trace declaration\n", __func__);
05628561 1649 return -EPERM;
427c09b7 1650 }
05628561
MD
1651 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->word_size);
1652 if (ret) {
78af2bcd 1653 fprintf(fd, "[error] %s: unexpected unary expression for trace word_size\n", __func__);
05628561
MD
1654 return -EINVAL;
1655 }
a0720417 1656 CTF_TRACE_SET_FIELD(trace, word_size);
05628561 1657 } else if (!strcmp(left, "uuid")) {
427c09b7
MD
1658 if (CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
1659 fprintf(fd, "[error] %s: uuid already declared in trace declaration\n", __func__);
05628561 1660 return -EPERM;
427c09b7 1661 }
05628561
MD
1662 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
1663 if (ret) {
78af2bcd 1664 fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
05628561
MD
1665 return -EINVAL;
1666 }
a0720417 1667 CTF_TRACE_SET_FIELD(trace, uuid);
05628561 1668 }
41253107 1669 g_free(left);
05628561
MD
1670 break;
1671 }
1672 default:
1673 return -EPERM;
1674 /* TODO: declaration specifier should be added. */
1675 }
1676
1677 return 0;
1678}
1679
05628561
MD
1680static
1681int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1682{
1683 int ret = 0;
1684 struct ctf_node *iter;
1685
d20f5e59 1686 if (trace->declaration_scope)
05628561 1687 return -EEXIST;
d20f5e59 1688 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
05628561
MD
1689 trace->streams = g_ptr_array_new();
1690 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
1691 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
1692 if (ret)
1693 goto error;
1694 }
a0720417 1695 if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
05628561 1696 ret = -EPERM;
427c09b7 1697 fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
05628561
MD
1698 goto error;
1699 }
a0720417 1700 if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
05628561 1701 ret = -EPERM;
427c09b7 1702 fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
05628561
MD
1703 goto error;
1704 }
a0720417 1705 if (!CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
05628561 1706 ret = -EPERM;
427c09b7 1707 fprintf(fd, "[error] %s: missing uuid field in trace declaration\n", __func__);
05628561
MD
1708 goto error;
1709 }
a0720417 1710 if (!CTF_TRACE_FIELD_IS_SET(trace, word_size)) {
05628561 1711 ret = -EPERM;
427c09b7 1712 fprintf(fd, "[error] %s: missing word_size field in trace declaration\n", __func__);
05628561
MD
1713 goto error;
1714 }
1715 return 0;
1716
1717error:
1718 g_ptr_array_free(trace->streams, TRUE);
a0720417 1719 free_declaration_scope(trace->declaration_scope);
05628561
MD
1720 return ret;
1721}
1722
78af2bcd
MD
1723static
1724int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1725{
1726 int ret = 0;
1727
1728 switch (node->type) {
1729 case NODE_TYPEDEF:
1730 ret = ctf_typedef_visit(fd, depth + 1,
1731 trace->root_declaration_scope,
1732 node->u._typedef.type_specifier_list,
1733 &node->u._typedef.type_declarators,
1734 trace);
1735 if (ret)
1736 return ret;
1737 break;
1738 case NODE_TYPEALIAS:
1739 ret = ctf_typealias_visit(fd, depth + 1,
1740 trace->root_declaration_scope,
1741 node->u.typealias.target, node->u.typealias.alias,
1742 trace);
1743 if (ret)
1744 return ret;
1745 break;
1746 case NODE_TYPE_SPECIFIER_LIST:
1747 {
1748 struct declaration *declaration;
1749
1750 /*
1751 * Just add the type specifier to the root scope
1752 * declaration scope. Release local reference.
1753 */
1754 declaration = ctf_type_specifier_list_visit(fd, depth + 1,
1755 node, trace->root_declaration_scope, trace);
1756 if (!declaration)
1757 return -ENOMEM;
1758 declaration_unref(declaration);
1759 break;
1760 }
1761 default:
1762 return -EPERM;
1763 }
1764
1765 return 0;
1766}
1767
ab4cf058
MD
1768int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
1769 struct ctf_trace *trace, int byte_order)
05628561
MD
1770{
1771 int ret = 0;
1772 struct ctf_node *iter;
1773
78af2bcd
MD
1774 fprintf(fd, "CTF visitor: metadata construction... ");
1775 trace->root_declaration_scope = new_declaration_scope(NULL);
ab4cf058
MD
1776 trace->byte_order = byte_order;
1777
05628561
MD
1778 switch (node->type) {
1779 case NODE_ROOT:
3e11b713 1780 cds_list_for_each_entry(iter, &node->u.root.declaration_list,
05628561 1781 siblings) {
78af2bcd 1782 ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
427c09b7
MD
1783 if (ret) {
1784 fprintf(fd, "[error] %s: root declaration error\n", __func__);
78af2bcd 1785 return ret;
427c09b7 1786 }
05628561
MD
1787 }
1788 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
1789 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
427c09b7
MD
1790 if (ret) {
1791 fprintf(fd, "[error] %s: trace declaration error\n", __func__);
05628561 1792 return ret;
427c09b7 1793 }
05628561 1794 }
5039b4cc
MD
1795 if (!trace->streams) {
1796 fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
1797 return -EINVAL;
1798 }
05628561
MD
1799 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
1800 ret = ctf_stream_visit(fd, depth + 1, iter,
41253107 1801 trace->root_declaration_scope, trace);
427c09b7
MD
1802 if (ret) {
1803 fprintf(fd, "[error] %s: stream declaration error\n", __func__);
05628561 1804 return ret;
427c09b7 1805 }
05628561
MD
1806 }
1807 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
1808 ret = ctf_event_visit(fd, depth + 1, iter,
41253107 1809 trace->root_declaration_scope, trace);
427c09b7
MD
1810 if (ret) {
1811 fprintf(fd, "[error] %s: event declaration error\n", __func__);
05628561 1812 return ret;
427c09b7 1813 }
05628561
MD
1814 }
1815 break;
05628561
MD
1816 case NODE_UNKNOWN:
1817 default:
78af2bcd 1818 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
05628561
MD
1819 (int) node->type);
1820 return -EINVAL;
1821 }
78af2bcd 1822 fprintf(fd, "done.\n");
05628561
MD
1823 return ret;
1824}
This page took 0.210151 seconds and 4 git commands to generate.