Update typealias behavior
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 21 Apr 2011 02:01:24 +0000 (22:01 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 21 Apr 2011 02:01:24 +0000 (22:01 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
formats/ctf/metadata/ctf-ast.h
formats/ctf/metadata/ctf-parser.y
formats/ctf/metadata/ctf-visitor-semantic-validator.c
include/babeltrace/types.h

index 8b5ad887b6df6ea16334b7b86e6e88435751ec07..0ce21a5a4b2163e1adf952dd2b0039a10e523766 100644 (file)
@@ -216,11 +216,13 @@ struct ctf_node {
                        char *choice;
                        /* list of typedef, typealias and declarations */
                        struct cds_list_head declaration_list;
+                       int has_body;
                } variant;
                struct {
                        char *name;
                        /* list of typedef, typealias and declarations */
                        struct cds_list_head declaration_list;
+                       int has_body;
                } _struct;
        } u;
 };
index 2ded0aeff0c9945368dbec4a9c307a7627519fb2..f6c6185957d52c1a632f751301e5e889091f8171 100644 (file)
@@ -811,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
@@ -821,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
@@ -1116,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);
@@ -1126,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:
@@ -1361,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");
@@ -1374,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");
@@ -1381,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;
                }
        ;
@@ -1404,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");
@@ -1417,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");
@@ -1424,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");
@@ -1431,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, $$))
@@ -1439,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, $$))
@@ -1453,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");
@@ -1466,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, $$))
@@ -1474,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, $$))
@@ -1488,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;
                }
@@ -1644,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);
@@ -1679,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);
@@ -1698,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;
 
@@ -1707,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:
@@ -2052,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);
@@ -2062,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);
-               }
        ;
index fae2b711ec4069513a59fde8004184fa70728d17..da77f596733bad47249a0648bd73a819a1c6c50c 100644 (file)
@@ -232,10 +232,30 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
                 */
                if (!cds_list_empty(&node->u.type_declarator.pointers))
                        goto errperm;
-               /* Fall-through */
-       case NODE_TYPEDEF:
+               break;                  /* OK */
        case NODE_TYPEALIAS_TARGET:
+               break;                  /* OK */
        case NODE_TYPEALIAS_ALIAS:
+               /*
+                * Only accept alias name containing:
+                * - identifier
+                * - identifier *   (any number of pointers)
+                * NOT accepting alias names containing [] (would otherwise
+                * cause semantic clash for later declarations of
+                * arrays/sequences of elements, where elements could be
+                * arrays/sequences themselves (if allowed in typealias).
+                * NOT accepting alias with identifier. The declarator should
+                * be either empty or contain pointer(s).
+                */
+               if (node->u.type_declarator.type == TYPEDEC_NESTED)
+                       goto errperm;
+               if (cds_list_empty(&node->u.type_declarator.pointers))
+                       goto errperm;
+               if (node->u.type_declarator.type == TYPEDEC_ID &&
+                   node->u.type_declarator.u.id != NULL)
+                       goto errperm;
+               break;                  /* OK */
+       case NODE_TYPEDEF:
        case NODE_STRUCT_OR_VARIANT_DECLARATION:
                break;                  /* OK */
 
@@ -484,6 +504,9 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
                depth--;
                break;
        case NODE_TYPEALIAS_TARGET:
+       {
+               int nr_declarators;
+
                switch (node->parent->type) {
                case NODE_TYPEALIAS:
                        break;                  /* OK */
@@ -497,14 +520,25 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
                        if (ret)
                                return ret;
                }
+               nr_declarators = 0;
                cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
                        ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
                        if (ret)
                                return ret;
+                       nr_declarators++;
+               }
+               if (nr_declarators > 1) {
+                       fprintf(fd, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__, nr_declarators);
+               
+                       return -EINVAL;
                }
                depth--;
                break;
+       }
        case NODE_TYPEALIAS_ALIAS:
+       {
+               int nr_declarators;
+
                switch (node->parent->type) {
                case NODE_TYPEALIAS:
                        break;                  /* OK */
@@ -518,13 +552,21 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
                        if (ret)
                                return ret;
                }
+               nr_declarators = 0;
                cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
                        ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
                        if (ret)
                                return ret;
+                       nr_declarators++;
+               }
+               if (nr_declarators > 1) {
+                       fprintf(fd, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__, nr_declarators);
+               
+                       return -EINVAL;
                }
                depth--;
                break;
+       }
        case NODE_TYPEALIAS:
                switch (node->parent->type) {
                case NODE_ROOT:
index c8e31337c7bf452baed599e0b3fd3dfd50998a53..ad28ac0912c85e98e8bc2c27acd0474e446e1d47 100644 (file)
@@ -90,6 +90,7 @@ struct definition;
 /* type scope */
 struct declaration_scope {
        /* Hash table mapping type name GQuark to "struct declaration" */
+       /* Used for both typedef and typealias. */
        GHashTable *typedef_declarations;
        /* Hash table mapping struct name GQuark to "struct declaration_struct" */
        GHashTable *struct_declarations;
This page took 0.031613 seconds and 4 git commands to generate.