From 7d4192cb80178ad534e460d56f67e55679c7d8ee Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 21 Apr 2011 14:23:02 -0400 Subject: [PATCH] enum, sequence, array: use declaration list for length/container type Signed-off-by: Mathieu Desnoyers --- formats/ctf/metadata/ctf-ast.h | 14 +++-- formats/ctf/metadata/ctf-parser.y | 62 ++++++++++--------- .../ctf/metadata/ctf-visitor-parent-links.c | 15 ++--- .../metadata/ctf-visitor-semantic-validator.c | 18 ++++-- formats/ctf/metadata/ctf-visitor-xml.c | 20 ++++-- 5 files changed, 81 insertions(+), 48 deletions(-) diff --git a/formats/ctf/metadata/ctf-ast.h b/formats/ctf/metadata/ctf-ast.h index 6ee937b6..c12d09a9 100644 --- a/formats/ctf/metadata/ctf-ast.h +++ b/formats/ctf/metadata/ctf-ast.h @@ -173,8 +173,11 @@ struct ctf_node { struct { /* typedec has no pointer list */ struct ctf_node *type_declarator; - /* value or first node of declaration specifier list */ - struct ctf_node *length; + /* + * unary expression (value) or + * declaration specifiers. + */ + struct cds_list_head length; /* for abstract type declarator */ unsigned int abstract_array; } nested; @@ -203,8 +206,11 @@ struct ctf_node { } enumerator; struct { char *enum_id; - /* NULL, value or declaration specifier */ - struct ctf_node *container_type; + /* + * Either empty, contains unary expression or + * declaration specifiers. + */ + struct cds_list_head container_type; struct cds_list_head enumerator_list; int has_body; } _enum; diff --git a/formats/ctf/metadata/ctf-parser.y b/formats/ctf/metadata/ctf-parser.y index 1a76c655..cdcfdcdb 100644 --- a/formats/ctf/metadata/ctf-parser.y +++ b/formats/ctf/metadata/ctf-parser.y @@ -292,6 +292,7 @@ static struct ctf_node *make_node(struct ctf_scanner *scanner, CDS_INIT_LIST_HEAD(&node->u.enumerator.values); break; case NODE_ENUM: + CDS_INIT_LIST_HEAD(&node->u._enum.container_type); CDS_INIT_LIST_HEAD(&node->u._enum.enumerator_list); break; case NODE_STRUCT_OR_VARIANT_DECLARATION: @@ -493,10 +494,11 @@ static int reparent_type_specifier(struct ctf_node *node, break; case NODE_TYPE_DECLARATOR: parent->u.type_declarator.type = TYPEDEC_NESTED; - parent->u.type_declarator.u.nested.length = node; + CDS_INIT_LIST_HEAD(&parent->u.type_declarator.u.nested.length); + _cds_list_splice_tail(&node->tmp_head, &parent->u.type_declarator.u.nested.length); break; case NODE_ENUM: - parent->u._enum.container_type = node; + _cds_list_splice_tail(&node->tmp_head, &parent->u._enum.container_type); break; case NODE_STRUCT_OR_VARIANT_DECLARATION: _cds_list_splice_tail(&node->tmp_head, &parent->u.struct_or_variant_declaration.declaration_specifier); @@ -817,7 +819,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner) %type type_specifier %type struct_type_specifier %type variant_type_specifier -%type type_specifier_or_integer_constant +%type declaration_specifiers_or_integer_constant %type enum_type_specifier %type struct_or_variant_declaration_list %type struct_or_variant_declaration @@ -1502,7 +1504,7 @@ variant_declaration_end: { pop_scope(scanner); } ; -type_specifier_or_integer_constant: +declaration_specifiers_or_integer_constant: declaration_specifiers { $$ = $1; } | DECIMAL_CONSTANT @@ -1535,11 +1537,11 @@ enum_type_specifier: $$->u._enum.has_body = 1; _cds_list_splice_tail(&($2)->tmp_head, &($$)->u._enum.enumerator_list); } - | LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC + | LT declaration_specifiers_or_integer_constant GT LBRAC enumerator_list RBRAC { $$ = make_node(scanner, NODE_ENUM); $$->u._enum.has_body = 1; - $$->u._enum.container_type = $2; + _cds_list_splice_tail(&($2)->tmp_head, &($$)->u._enum.container_type); _cds_list_splice_tail(&($5)->tmp_head, &($$)->u._enum.enumerator_list); } | IDENTIFIER LBRAC enumerator_list RBRAC @@ -1549,12 +1551,12 @@ enum_type_specifier: $$->u._enum.enum_id = $1->s; _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.enumerator_list); } - | IDENTIFIER LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC + | IDENTIFIER LT declaration_specifiers_or_integer_constant GT LBRAC enumerator_list RBRAC { $$ = make_node(scanner, NODE_ENUM); $$->u._enum.has_body = 1; $$->u._enum.enum_id = $1->s; - $$->u._enum.container_type = $3; + _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.container_type); _cds_list_splice_tail(&($6)->tmp_head, &($$)->u._enum.enumerator_list); } | ID_TYPE LBRAC enumerator_list RBRAC @@ -1564,12 +1566,12 @@ enum_type_specifier: $$->u._enum.enum_id = $1->s; _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.enumerator_list); } - | ID_TYPE LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC + | ID_TYPE LT declaration_specifiers_or_integer_constant GT LBRAC enumerator_list RBRAC { $$ = make_node(scanner, NODE_ENUM); $$->u._enum.has_body = 1; $$->u._enum.enum_id = $1->s; - $$->u._enum.container_type = $3; + _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.container_type); _cds_list_splice_tail(&($6)->tmp_head, &($$)->u._enum.enumerator_list); } | LBRAC enumerator_list COMMA RBRAC @@ -1578,11 +1580,11 @@ enum_type_specifier: $$->u._enum.has_body = 1; _cds_list_splice_tail(&($2)->tmp_head, &($$)->u._enum.enumerator_list); } - | LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC + | LT declaration_specifiers_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC { $$ = make_node(scanner, NODE_ENUM); $$->u._enum.has_body = 1; - $$->u._enum.container_type = $2; + _cds_list_splice_tail(&($2)->tmp_head, &($$)->u._enum.container_type); _cds_list_splice_tail(&($5)->tmp_head, &($$)->u._enum.enumerator_list); } | IDENTIFIER LBRAC enumerator_list COMMA RBRAC @@ -1592,12 +1594,12 @@ enum_type_specifier: $$->u._enum.enum_id = $1->s; _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.enumerator_list); } - | IDENTIFIER LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC + | IDENTIFIER LT declaration_specifiers_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC { $$ = make_node(scanner, NODE_ENUM); $$->u._enum.has_body = 1; $$->u._enum.enum_id = $1->s; - $$->u._enum.container_type = $3; + _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.container_type); _cds_list_splice_tail(&($6)->tmp_head, &($$)->u._enum.enumerator_list); } | IDENTIFIER @@ -1606,12 +1608,12 @@ enum_type_specifier: $$->u._enum.has_body = 0; $$->u._enum.enum_id = $1->s; } - | IDENTIFIER LT type_specifier_or_integer_constant GT + | IDENTIFIER LT declaration_specifiers_or_integer_constant GT { $$ = make_node(scanner, NODE_ENUM); $$->u._enum.has_body = 0; $$->u._enum.enum_id = $1->s; - $$->u._enum.container_type = $3; + _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.container_type); } | ID_TYPE LBRAC enumerator_list COMMA RBRAC { @@ -1620,12 +1622,12 @@ enum_type_specifier: $$->u._enum.enum_id = $1->s; _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.enumerator_list); } - | ID_TYPE LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC + | ID_TYPE LT declaration_specifiers_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC { $$ = make_node(scanner, NODE_ENUM); $$->u._enum.has_body = 1; $$->u._enum.enum_id = $1->s; - $$->u._enum.container_type = $3; + _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.container_type); _cds_list_splice_tail(&($6)->tmp_head, &($$)->u._enum.enumerator_list); } | ID_TYPE @@ -1634,12 +1636,12 @@ enum_type_specifier: $$->u._enum.has_body = 0; $$->u._enum.enum_id = $1->s; } - | ID_TYPE LT type_specifier_or_integer_constant GT + | ID_TYPE LT declaration_specifiers_or_integer_constant GT { $$ = make_node(scanner, NODE_ENUM); $$->u._enum.has_body = 0; $$->u._enum.enum_id = $1->s; - $$->u._enum.container_type = $3; + _cds_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.container_type); } ; @@ -1868,12 +1870,13 @@ direct_abstract_declarator: $$->u.type_declarator.type = TYPEDEC_NESTED; $$->u.type_declarator.u.nested.type_declarator = $2; } - | direct_abstract_declarator LSBRAC type_specifier_or_integer_constant RSBRAC + | direct_abstract_declarator LSBRAC declaration_specifiers_or_integer_constant RSBRAC { $$ = make_node(scanner, NODE_TYPE_DECLARATOR); $$->u.type_declarator.type = TYPEDEC_NESTED; $$->u.type_declarator.u.nested.type_declarator = $1; - $$->u.type_declarator.u.nested.length = $3; + CDS_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length); + _cds_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length); } | direct_abstract_declarator LSBRAC RSBRAC { @@ -1917,12 +1920,13 @@ direct_alias_abstract_declarator: $$->u.type_declarator.type = TYPEDEC_NESTED; $$->u.type_declarator.u.nested.type_declarator = $2; } - | direct_alias_abstract_declarator LSBRAC type_specifier_or_integer_constant RSBRAC + | direct_alias_abstract_declarator LSBRAC declaration_specifiers_or_integer_constant RSBRAC { $$ = make_node(scanner, NODE_TYPE_DECLARATOR); $$->u.type_declarator.type = TYPEDEC_NESTED; $$->u.type_declarator.u.nested.type_declarator = $1; - $$->u.type_declarator.u.nested.length = $3; + CDS_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length); + _cds_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length); } | direct_alias_abstract_declarator LSBRAC RSBRAC { @@ -1956,12 +1960,13 @@ direct_declarator: $$->u.type_declarator.type = TYPEDEC_NESTED; $$->u.type_declarator.u.nested.type_declarator = $2; } - | direct_declarator LSBRAC type_specifier_or_integer_constant RSBRAC + | direct_declarator LSBRAC declaration_specifiers_or_integer_constant RSBRAC { $$ = make_node(scanner, NODE_TYPE_DECLARATOR); $$->u.type_declarator.type = TYPEDEC_NESTED; $$->u.type_declarator.u.nested.type_declarator = $1; - $$->u.type_declarator.u.nested.length = $3; + CDS_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length); + _cds_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length); } ; @@ -1989,12 +1994,13 @@ direct_type_declarator: $$->u.type_declarator.type = TYPEDEC_NESTED; $$->u.type_declarator.u.nested.type_declarator = $2; } - | direct_type_declarator LSBRAC type_specifier_or_integer_constant RSBRAC + | direct_type_declarator LSBRAC declaration_specifiers_or_integer_constant RSBRAC { $$ = make_node(scanner, NODE_TYPE_DECLARATOR); $$->u.type_declarator.type = TYPEDEC_NESTED; $$->u.type_declarator.u.nested.type_declarator = $1; - $$->u.type_declarator.u.nested.length = $3; + CDS_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length); + _cds_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length); } ; diff --git a/formats/ctf/metadata/ctf-visitor-parent-links.c b/formats/ctf/metadata/ctf-visitor-parent-links.c index f23458d5..8c4b2124 100644 --- a/formats/ctf/metadata/ctf-visitor-parent-links.c +++ b/formats/ctf/metadata/ctf-visitor-parent-links.c @@ -135,10 +135,10 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node) if (ret) return ret; } - if (node->u.type_declarator.u.nested.length) { - node->u.type_declarator.u.nested.length->parent = node; - ret = ctf_visitor_parent_links(fd, depth + 1, - node->u.type_declarator.u.nested.length); + cds_list_for_each_entry(iter, &node->u.type_declarator.u.nested.length, + siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(fd, depth + 1, iter); if (ret) return ret; } @@ -358,9 +358,10 @@ int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node) case NODE_ENUM: depth++; - if (node->u._enum.container_type) { - node->u._enum.container_type->parent = node; - ret = ctf_visitor_parent_links(fd, depth + 1, node->u._enum.container_type); + cds_list_for_each_entry(iter, &node->u._enum.container_type, + siblings) { + iter->parent = node; + ret = ctf_visitor_parent_links(fd, depth + 1, iter); if (ret) return ret; } diff --git a/formats/ctf/metadata/ctf-visitor-semantic-validator.c b/formats/ctf/metadata/ctf-visitor-semantic-validator.c index da77f596..6f46bfbd 100644 --- a/formats/ctf/metadata/ctf-visitor-semantic-validator.c +++ b/formats/ctf/metadata/ctf-visitor-semantic-validator.c @@ -292,17 +292,25 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node) case TYPEDEC_ID: break; case TYPEDEC_NESTED: + { + int nr_nest_len; + if (node->u.type_declarator.u.nested.type_declarator) { ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u.type_declarator.u.nested.type_declarator); if (ret) return ret; } - if (node->u.type_declarator.u.nested.length) { + cds_list_for_each_entry(iter, &node->u.type_declarator.u.nested.length, + siblings) { ret = _ctf_visitor_semantic_check(fd, depth + 1, - node->u.type_declarator.u.nested.length); + iter); if (ret) return ret; + nr_nest_len++; + if (iter->type == NODE_UNARY_EXPRESSION && nr_nest_len > 1) { + goto errperm; + } } if (node->u.type_declarator.bitfield_len) { ret = _ctf_visitor_semantic_check(fd, depth + 1, @@ -311,6 +319,7 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node) return ret; } break; + } case TYPEDEC_UNKNOWN: default: fprintf(fd, "[error] %s: unknown type declarator %d\n", __func__, @@ -810,8 +819,9 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node) } depth++; - if (node->u._enum.container_type) { - ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u._enum.container_type); + cds_list_for_each_entry(iter, &node->u._enum.container_type, + siblings) { + ret = _ctf_visitor_semantic_check(fd, depth + 1, iter); if (ret) return ret; } diff --git a/formats/ctf/metadata/ctf-visitor-xml.c b/formats/ctf/metadata/ctf-visitor-xml.c index 68a2e554..7f08031a 100644 --- a/formats/ctf/metadata/ctf-visitor-xml.c +++ b/formats/ctf/metadata/ctf-visitor-xml.c @@ -218,13 +218,17 @@ int ctf_visitor_print_type_declarator(FILE *fd, int depth, struct ctf_node *node print_tabs(fd, depth); fprintf(fd, "\n"); } - if (node->u.type_declarator.u.nested.length) { + if (!cds_list_empty(&node->u.type_declarator.u.nested.length)) { print_tabs(fd, depth); fprintf(fd, "\n"); - ret = ctf_visitor_print_xml(fd, depth + 1, - node->u.type_declarator.u.nested.length); + } + cds_list_for_each_entry(iter, &node->u.type_declarator.u.nested.length, + siblings) { + ret = ctf_visitor_print_xml(fd, depth + 1, iter); if (ret) return ret; + } + if (!cds_list_empty(&node->u.type_declarator.u.nested.length)) { print_tabs(fd, depth); fprintf(fd, "\n"); } @@ -540,12 +544,18 @@ int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node) fprintf(fd, "\n"); depth++; - if (node->u._enum.container_type) { + if (!cds_list_empty(&node->u._enum.container_type)) { print_tabs(fd, depth); fprintf(fd, "\n"); - ret = ctf_visitor_print_xml(fd, depth + 1, node->u._enum.container_type); + } + + cds_list_for_each_entry(iter, &node->u._enum.container_type, + siblings) { + ret = ctf_visitor_print_xml(fd, depth + 1, iter); if (ret) return ret; + } + if (!cds_list_empty(&node->u._enum.container_type)) { print_tabs(fd, depth); fprintf(fd, "\n"); } -- 2.34.1