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