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