Update typealias behavior
[babeltrace.git] / formats / ctf / metadata / ctf-parser.y
index 67180f6e4385bc5d44faa1e780098c85a1f12166..f6c6185957d52c1a632f751301e5e889091f8171 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include <assert.h>
-#include <helpers/list.h>
 #include <glib.h>
 #include <errno.h>
+#include <inttypes.h>
+#include <babeltrace/list.h>
 #include "ctf-scanner.h"
 #include "ctf-parser.h"
 #include "ctf-ast.h"
 
+/*
+ * TODO: support enum, variant and struct declarations in scopes.
+ */
+
 /* Join two lists, put "add" at the end of "head".  */
 static inline void
 _cds_list_splice_tail (struct cds_list_head *add, struct cds_list_head *head)
@@ -58,6 +63,39 @@ struct gc_string {
        char s[];
 };
 
+static const char *node_type_to_str[] = {
+       [ NODE_UNKNOWN ] = "NODE_UNKNOWN",
+       [ NODE_ROOT ] = "NODE_ROOT",
+       [ NODE_EVENT ] = "NODE_EVENT",
+       [ NODE_STREAM ] = "NODE_STREAM",
+       [ NODE_TRACE ] = "NODE_TRACE",
+       [ NODE_CTF_EXPRESSION ] = "NODE_CTF_EXPRESSION",
+       [ NODE_UNARY_EXPRESSION ] = "NODE_UNARY_EXPRESSION",
+       [ NODE_TYPEDEF ] = "NODE_TYPEDEF",
+       [ NODE_TYPEALIAS_TARGET ] = "NODE_TYPEALIAS_TARGET",
+       [ NODE_TYPEALIAS_ALIAS ] = "NODE_TYPEALIAS_ALIAS",
+       [ NODE_TYPEALIAS ] = "NODE_TYPEALIAS",
+       [ NODE_TYPE_SPECIFIER ] = "NODE_TYPE_SPECIFIER",
+       [ NODE_POINTER ] = "NODE_POINTER",
+       [ NODE_TYPE_DECLARATOR ] = "NODE_TYPE_DECLARATOR",
+       [ NODE_FLOATING_POINT ] = "NODE_FLOATING_POINT",
+       [ NODE_INTEGER ] = "NODE_INTEGER",
+       [ NODE_STRING ] = "NODE_STRING",
+       [ NODE_ENUMERATOR ] = "NODE_ENUMERATOR",
+       [ NODE_ENUM ] = "NODE_ENUM",
+       [ NODE_STRUCT_OR_VARIANT_DECLARATION ] = "NODE_STRUCT_OR_VARIANT_DECLARATION",
+       [ NODE_VARIANT ] = "NODE_VARIANT",
+       [ NODE_STRUCT ] = "NODE_STRUCT",
+};
+
+const char *node_type(struct ctf_node *node)
+{
+       if (node->type < NR_NODE_TYPES)
+               return node_type_to_str[node->type];
+       else
+               return NULL;
+}
+
 static struct gc_string *gc_string_alloc(struct ctf_scanner *scanner,
                                         size_t len)
 {
@@ -153,7 +191,7 @@ static int lookup_type(struct ctf_scanner_scope *s, const char *id)
 {
        int ret;
 
-       ret = (int) g_hash_table_lookup(s->types, id);
+       ret = (int) (long) g_hash_table_lookup(s->types, id);
        printf_dbg("lookup %p %s %d\n", s, id, ret);
        return ret;
 }
@@ -773,6 +811,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner)
 %type <n> stream_declaration
 %type <n> trace_declaration
 %type <n> declaration_specifiers
+%type <n> alias_declaration_specifiers
 
 %type <n> type_declarator_list
 %type <n> abstract_type_declarator_list
@@ -783,7 +822,6 @@ void ctf_scanner_free(struct ctf_scanner *scanner)
 %type <n> enum_type_specifier
 %type <n> struct_or_variant_declaration_list
 %type <n> struct_or_variant_declaration
-%type <n> specifier_qualifier_list
 %type <n> struct_or_variant_declarator_list
 %type <n> struct_or_variant_declarator
 %type <n> enumerator_list
@@ -839,6 +877,8 @@ keywords:
                {       $$ = yylval.gs;         }
        |       _COMPLEX
                {       $$ = yylval.gs;         }
+       |       _IMAGINARY
+               {       $$ = yylval.gs;         }
        |       FLOATING_POINT
                {       $$ = yylval.gs;         }
        |       INTEGER
@@ -925,21 +965,21 @@ postfix_expression:
                {
                        $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
                        $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT;
-                       sscanf(yylval.gs->s, "%llu",
+                       sscanf(yylval.gs->s, "%" PRIu64,
                               &$$->u.unary_expression.u.unsigned_constant);
                }
        |       OCTAL_CONSTANT
                {
                        $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
                        $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT;
-                       sscanf(yylval.gs->s, "0%llo",
+                       sscanf(yylval.gs->s, "0%" PRIo64,
                               &$$->u.unary_expression.u.unsigned_constant);
                }
        |       HEXADECIMAL_CONSTANT
                {
                        $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
                        $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT;
-                       sscanf(yylval.gs->s, "0x%llx",
+                       sscanf(yylval.gs->s, "0x%" PRIx64,
                               &$$->u.unary_expression.u.unsigned_constant);
                }
        |       STRING_LITERAL_START DQUOTE
@@ -1076,7 +1116,7 @@ declaration:
                        _cds_list_splice_tail(&($1)->tmp_head, &($$)->u._typedef.declaration_specifier);
                        _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._typedef.type_declarators);
                }
-       |       TYPEALIAS declaration_specifiers abstract_declarator_list COLON declaration_specifiers abstract_type_declarator_list SEMICOLON
+       |       TYPEALIAS declaration_specifiers abstract_declarator_list COLON alias_declaration_specifiers abstract_type_declarator_list SEMICOLON
                {
                        $$ = make_node(scanner, NODE_TYPEALIAS);
                        $$->u.typealias.target = make_node(scanner, NODE_TYPEALIAS_TARGET);
@@ -1086,15 +1126,6 @@ declaration:
                        _cds_list_splice_tail(&($5)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.declaration_specifier);
                        _cds_list_splice_tail(&($6)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.type_declarators);
                }
-       |       TYPEALIAS declaration_specifiers abstract_declarator_list COLON type_declarator_list SEMICOLON
-               {
-                       $$ = make_node(scanner, NODE_TYPEALIAS);
-                       $$->u.typealias.target = make_node(scanner, NODE_TYPEALIAS_TARGET);
-                       $$->u.typealias.alias = make_node(scanner, NODE_TYPEALIAS_ALIAS);
-                       _cds_list_splice_tail(&($2)->tmp_head, &($$)->u.typealias.target->u.typealias_target.declaration_specifier);
-                       _cds_list_splice_tail(&($3)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.declaration_specifier);
-                       _cds_list_splice_tail(&($5)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.type_declarators);
-               }
        ;
 
 event_declaration:
@@ -1268,6 +1299,11 @@ type_specifier:
                        $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
                        $$->u.type_specifier.type = TYPESPEC_COMPLEX;
                }
+       |       _IMAGINARY
+               {
+                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
+                       $$->u.type_specifier.type = TYPESPEC_IMAGINARY;
+               }
        |       ID_TYPE
                {
                        $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
@@ -1316,12 +1352,14 @@ struct_type_specifier:
                struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end
                {
                        $$ = make_node(scanner, NODE_STRUCT);
+                       $$->u._struct.has_body = 1;
                        if (set_parent_node($2, $$))
                                reparent_error(scanner, "struct reparent error");
                }
        |       IDENTIFIER struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end
                {
                        $$ = make_node(scanner, NODE_STRUCT);
+                       $$->u._struct.has_body = 1;
                        $$->u._struct.name = $1->s;
                        if (set_parent_node($3, $$))
                                reparent_error(scanner, "struct reparent error");
@@ -1329,6 +1367,7 @@ struct_type_specifier:
        |       ID_TYPE struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end
                {
                        $$ = make_node(scanner, NODE_STRUCT);
+                       $$->u._struct.has_body = 1;
                        $$->u._struct.name = $1->s;
                        if (set_parent_node($3, $$))
                                reparent_error(scanner, "struct reparent error");
@@ -1336,11 +1375,13 @@ struct_type_specifier:
        |       IDENTIFIER
                {
                        $$ = make_node(scanner, NODE_STRUCT);
+                       $$->u._struct.has_body = 0;
                        $$->u._struct.name = $1->s;
                }
        |       ID_TYPE
                {
                        $$ = make_node(scanner, NODE_STRUCT);
+                       $$->u._struct.has_body = 0;
                        $$->u._struct.name = $1->s;
                }
        ;
@@ -1359,12 +1400,14 @@ variant_type_specifier:
                variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 1;
                        if (set_parent_node($2, $$))
                                reparent_error(scanner, "variant reparent error");
                }
        |       LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 1;
                        $$->u.variant.choice = $2->s;
                        if (set_parent_node($5, $$))
                                reparent_error(scanner, "variant reparent error");
@@ -1372,6 +1415,7 @@ variant_type_specifier:
        |       LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 1;
                        $$->u.variant.choice = $2->s;
                        if (set_parent_node($5, $$))
                                reparent_error(scanner, "variant reparent error");
@@ -1379,6 +1423,7 @@ variant_type_specifier:
        |       IDENTIFIER variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 1;
                        $$->u.variant.name = $1->s;
                        if (set_parent_node($3, $$))
                                reparent_error(scanner, "variant reparent error");
@@ -1386,6 +1431,7 @@ variant_type_specifier:
        |       IDENTIFIER LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 1;
                        $$->u.variant.name = $1->s;
                        $$->u.variant.choice = $3->s;
                        if (set_parent_node($6, $$))
@@ -1394,12 +1440,14 @@ variant_type_specifier:
        |       IDENTIFIER LT IDENTIFIER GT
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 0;
                        $$->u.variant.name = $1->s;
                        $$->u.variant.choice = $3->s;
                }
        |       IDENTIFIER LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 1;
                        $$->u.variant.name = $1->s;
                        $$->u.variant.choice = $3->s;
                        if (set_parent_node($6, $$))
@@ -1408,12 +1456,14 @@ variant_type_specifier:
        |       IDENTIFIER LT ID_TYPE GT
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 0;
                        $$->u.variant.name = $1->s;
                        $$->u.variant.choice = $3->s;
                }
        |       ID_TYPE variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 1;
                        $$->u.variant.name = $1->s;
                        if (set_parent_node($3, $$))
                                reparent_error(scanner, "variant reparent error");
@@ -1421,6 +1471,7 @@ variant_type_specifier:
        |       ID_TYPE LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 1;
                        $$->u.variant.name = $1->s;
                        $$->u.variant.choice = $3->s;
                        if (set_parent_node($6, $$))
@@ -1429,12 +1480,14 @@ variant_type_specifier:
        |       ID_TYPE LT IDENTIFIER GT
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 0;
                        $$->u.variant.name = $1->s;
                        $$->u.variant.choice = $3->s;
                }
        |       ID_TYPE LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 1;
                        $$->u.variant.name = $1->s;
                        $$->u.variant.choice = $3->s;
                        if (set_parent_node($6, $$))
@@ -1443,6 +1496,7 @@ variant_type_specifier:
        |       ID_TYPE LT ID_TYPE GT
                {
                        $$ = make_node(scanner, NODE_VARIANT);
+                       $$->u.variant.has_body = 0;
                        $$->u.variant.name = $1->s;
                        $$->u.variant.choice = $3->s;
                }
@@ -1465,21 +1519,21 @@ type_specifier_or_integer_constant:
                {
                        $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
                        $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT;
-                       sscanf(yylval.gs->s, "%llu",
+                       sscanf(yylval.gs->s, "%" PRIu64,
                               &$$->u.unary_expression.u.unsigned_constant);
                }
        |       OCTAL_CONSTANT
                {
                        $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
                        $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT;
-                       sscanf(yylval.gs->s, "0%llo",
+                       sscanf(yylval.gs->s, "0%" PRIo64,
                               &$$->u.unary_expression.u.unsigned_constant);
                }
        |       HEXADECIMAL_CONSTANT
                {
                        $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
                        $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT;
-                       sscanf(yylval.gs->s, "0x%llx",
+                       sscanf(yylval.gs->s, "0x%" PRIx64,
                               &$$->u.unary_expression.u.unsigned_constant);
                }
        ;
@@ -1599,32 +1653,32 @@ struct_or_variant_declaration_list:
        ;
 
 struct_or_variant_declaration:
-               specifier_qualifier_list struct_or_variant_declarator_list SEMICOLON
+               declaration_specifiers struct_or_variant_declarator_list SEMICOLON
                {
                        $$ = make_node(scanner, NODE_STRUCT_OR_VARIANT_DECLARATION);
                        _cds_list_splice_tail(&($1)->tmp_head, &($$)->u.struct_or_variant_declaration.declaration_specifier);
                        _cds_list_splice_tail(&($2)->tmp_head, &($$)->u.struct_or_variant_declaration.type_declarators);
                }
-       |       specifier_qualifier_list TYPEDEF specifier_qualifier_list type_declarator_list SEMICOLON
+       |       declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list SEMICOLON
                {
                        $$ = make_node(scanner, NODE_TYPEDEF);
                        _cds_list_splice_tail(&($1)->tmp_head, &($$)->u._typedef.declaration_specifier);
                        _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._typedef.declaration_specifier);
                        _cds_list_splice_tail(&($4)->tmp_head, &($$)->u._typedef.type_declarators);
                }
-       |       TYPEDEF specifier_qualifier_list type_declarator_list SEMICOLON
+       |       TYPEDEF declaration_specifiers type_declarator_list SEMICOLON
                {
                        $$ = make_node(scanner, NODE_TYPEDEF);
                        _cds_list_splice_tail(&($2)->tmp_head, &($$)->u._typedef.declaration_specifier);
                        _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._typedef.type_declarators);
                }
-       |       specifier_qualifier_list TYPEDEF type_declarator_list SEMICOLON
+       |       declaration_specifiers TYPEDEF type_declarator_list SEMICOLON
                {
                        $$ = make_node(scanner, NODE_TYPEDEF);
                        _cds_list_splice_tail(&($1)->tmp_head, &($$)->u._typedef.declaration_specifier);
                        _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._typedef.type_declarators);
                }
-       |       TYPEALIAS specifier_qualifier_list abstract_declarator_list COLON specifier_qualifier_list abstract_type_declarator_list SEMICOLON
+       |       TYPEALIAS declaration_specifiers abstract_declarator_list COLON alias_declaration_specifiers abstract_type_declarator_list SEMICOLON
                {
                        $$ = make_node(scanner, NODE_TYPEALIAS);
                        $$->u.typealias.target = make_node(scanner, NODE_TYPEALIAS_TARGET);
@@ -1634,18 +1688,9 @@ struct_or_variant_declaration:
                        _cds_list_splice_tail(&($5)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.declaration_specifier);
                        _cds_list_splice_tail(&($6)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.type_declarators);
                }
-       |       TYPEALIAS specifier_qualifier_list abstract_declarator_list COLON type_declarator_list SEMICOLON
-               {
-                       $$ = make_node(scanner, NODE_TYPEALIAS);
-                       $$->u.typealias.target = make_node(scanner, NODE_TYPEALIAS_TARGET);
-                       $$->u.typealias.alias = make_node(scanner, NODE_TYPEALIAS_ALIAS);
-                       _cds_list_splice_tail(&($2)->tmp_head, &($$)->u.typealias.target->u.typealias_target.declaration_specifier);
-                       _cds_list_splice_tail(&($3)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.declaration_specifier);
-                       _cds_list_splice_tail(&($5)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.type_declarators);
-               }
        ;
 
-specifier_qualifier_list:
+alias_declaration_specifiers:
                CONST
                {
                        $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
@@ -1653,7 +1698,14 @@ specifier_qualifier_list:
                }
        |       type_specifier
                {       $$ = $1;        }
-       |       specifier_qualifier_list CONST
+       |       IDENTIFIER
+               {
+                       add_type(scanner, $1);
+                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
+                       ($$)->u.type_specifier.type = TYPESPEC_ID_TYPE;
+                       ($$)->u.type_specifier.id_type = yylval.gs->s;
+               }
+       |       alias_declaration_specifiers CONST
                {
                        struct ctf_node *node;
 
@@ -1662,11 +1714,22 @@ specifier_qualifier_list:
                        node->u.type_specifier.type = TYPESPEC_CONST;
                        cds_list_add_tail(&node->siblings, &($$)->tmp_head);
                }
-       |       specifier_qualifier_list type_specifier
+       |       alias_declaration_specifiers type_specifier
                {
                        $$ = $1;
                        cds_list_add_tail(&($2)->siblings, &($$)->tmp_head);
                }
+       |       alias_declaration_specifiers IDENTIFIER
+               {
+                       struct ctf_node *node;
+
+                       add_type(scanner, $2);
+                       $$ = $1;
+                       node = make_node(scanner, NODE_TYPE_SPECIFIER);
+                       node->u.type_specifier.type = TYPESPEC_ID_TYPE;
+                       node->u.type_specifier.id_type = yylval.gs->s;
+                       cds_list_add_tail(&node->siblings, &($$)->tmp_head);
+               }
        ;
 
 struct_or_variant_declarator_list:
@@ -2007,7 +2070,7 @@ ctf_assignment_expression:
                        _cds_list_splice_tail(&($1)->tmp_head, &($$)->u._typedef.declaration_specifier);
                        _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._typedef.type_declarators);
                }
-       |       TYPEALIAS declaration_specifiers abstract_declarator_list COLON declaration_specifiers abstract_type_declarator_list
+       |       TYPEALIAS declaration_specifiers abstract_declarator_list COLON alias_declaration_specifiers abstract_type_declarator_list
                {
                        $$ = make_node(scanner, NODE_TYPEALIAS);
                        $$->u.typealias.target = make_node(scanner, NODE_TYPEALIAS_TARGET);
@@ -2017,13 +2080,4 @@ ctf_assignment_expression:
                        _cds_list_splice_tail(&($5)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.declaration_specifier);
                        _cds_list_splice_tail(&($6)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.type_declarators);
                }
-       |       TYPEALIAS declaration_specifiers abstract_declarator_list COLON type_declarator_list
-               {
-                       $$ = make_node(scanner, NODE_TYPEALIAS);
-                       $$->u.typealias.target = make_node(scanner, NODE_TYPEALIAS_TARGET);
-                       $$->u.typealias.alias = make_node(scanner, NODE_TYPEALIAS_ALIAS);
-                       _cds_list_splice_tail(&($2)->tmp_head, &($$)->u.typealias.target->u.typealias_target.declaration_specifier);
-                       _cds_list_splice_tail(&($3)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.declaration_specifier);
-                       _cds_list_splice_tail(&($5)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.type_declarators);
-               }
        ;
This page took 0.02941 seconds and 4 git commands to generate.