This patch extends the C++ frontend so that it optionally builds a BLT tree, by using an auto_blt_node class within the recursive descent through the parser, so that its ctor/dtors build the blt_node hierarchy; this is rapidly (I hope) rejected in the no -fblt case, so that by default, no blt nodes are created.
This version of the parser captures a blt_node for every token consumed by cp_parser_require, so there are a lot of leaf nodes in the resulting tree. Caveat: currently the patch blithely ignores "tentative parsing" (for the sake of posting this kit sooner rather than later). All of this is largely a no-op if -fblt is not provided. gcc/cp/ChangeLog: * cp-tree.h (class blt_node): Forward decl. (struct cp_parameter_declarator): Add "bltnode" field. (struct cp_declarator): Likewise. * decl.c: Include "blt.h" (grokdeclarator): Rename to... (grokdeclarator_1): ...this. (grokdeclarator): Reintroduce by calling grokdeclarator_1, and associating any bltnode in the declarator with the new tree. * parser.c: Include "blt.h". (class auto_blt_node): New class. (AUTO_BLT_NODE): New macro. AUTO_BLT_NODE_WITH_RETURN): New macro. (CURRENT_BLT_NODE): New macro. (BLT_ADD_NEXT_TOKEN): New macro. (ADD_NODE_FOR_NEXT_TOKEN): New macro. (BLT_SET_TREE): New macro. (add_node_for_next_token): New functions. (auto_blt_node::auto_blt_node): New ctor. (auto_blt_node::~auto_blt_node): New dtor. (auto_blt_node::set_tree): New method. (make_declarator): Initialize the bltnode field. (make_parameter_declarator): Add new "bltnode" param. (cp_parser_identifier): Add AUTO_BLT_NODE. (cp_parser_translation_unit): Likewise. (cp_parser_primary_expression): Likewise. (cp_parser_id_expression): Likewise. (cp_parser_unqualified_id): Likewise. (cp_parser_postfix_expression): Likewise; add BLT_ADD_NEXT_TOKEN. (cp_parser_parenthesized_expression_list): Add AUTO_BLT_NODE. (cp_parser_unary_expression): Add AUTO_BLT_NODE. (cp_parser_assignment_expression): Likewise. (cp_parser_declaration_seq_opt): Likewise. (cp_parser_declaration): Likewise. (cp_parser_block_declaration): Likewise. (cp_parser_simple_declaration): Likewise. (cp_parser_decl_specifier_seq): Likewise; add ADD_NODE_FOR_NEXT_TOKEN in various places. (cp_parser_template_declaration): Add AUTO_BLT_NODE. (cp_parser_template_parameter_list): Likewise. (cp_parser_explicit_instantiation): Likewise. (cp_parser_explicit_specialization): Likewise. (cp_parser_type_specifier): Likewise; add ADD_NODE_FOR_NEXT_TOKEN in various places. (update_blt_for_function_definition): New function. (cp_parser_init_declarator): Call update_blt_for_function_definition. (cp_parser_declarator): Add AUTO_BLT_NODE. (cp_parser_direct_declarator): Likewise; add BLT_ADD_NEXT_TOKEN; set the bltnode of the declarator. (cp_parser_cv_qualifier_seq_opt): Add AUTO_BLT_NODE; add ADD_NODE_FOR_NEXT_TOKEN. (cp_parser_parameter_declaration_clause): Add AUTO_BLT_NODE; add BLT_ADD_NEXT_TOKEN in various places. Add BLT_SET_TREE. (cp_parser_parameter_declaration_list): Add AUTO_BLT_NODE; add BLT_SET_TREE in various places. (cp_parser_parameter_declaration): Add AUTO_BLT_NODE; pass CURRENT_BLT_NODE to make_parameter_declarator. (cp_parser_class_specifier_1): Add AUTO_BLT_NODE; add BLT_SET_TREE. (cp_parser_class_head): Add AUTO_BLT_NODE. (cp_parser_class_key): Likewise. (cp_parser_member_declaration): Likewise. Ensure decl is initialized, and associate it with the blt_node. (cp_parser_type_id_list): Add AUTO_BLT_NODE. (cp_parser_try_block): Likewise. (cp_parser_function_try_block): Likewise. (cp_parser_handler_seq): Likewise. (cp_parser_handler): Likewise. (cp_parser_exception_declaration): Likewise. (cp_parser_throw_expression): Likewise. (cp_parser_asm_specification_opt): Likewise. (cp_parser_require): Call BLT_ADD_NEXT_TOKEN. (c_parse_file): Implement -fdump-blt. Set the_blt_root_node. * parser.h (class blt_node): Forward decl. (struct cp_parser): Add fields "blt_root_node" and "blt_current_node". * pt.c: Include "blt.h". (build_template_decl): Associate any blt_node for the decl with the template instantation. --- gcc/cp/cp-tree.h | 5 + gcc/cp/decl.c | 27 +++- gcc/cp/parser.c | 369 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- gcc/cp/parser.h | 7 ++ gcc/cp/pt.c | 8 ++ 5 files changed, 394 insertions(+), 22 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 0da8a5c..16d8a48 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -25,6 +25,8 @@ along with GCC; see the file COPYING3. If not see #include "hard-reg-set.h" #include "function.h" +class blt_node; + /* In order for the format checking to accept the C++ front end diagnostic framework extensions, you must include this file before diagnostic-core.h, not after. We override the definition of GCC_DIAG_STYLE @@ -5699,6 +5701,8 @@ struct cp_parameter_declarator { tree default_argument; /* True iff this is a template parameter pack. */ bool template_parameter_pack_p; + /* The blt_node for this parameter, if any. */ + blt_node *bltnode; }; /* A declarator. */ @@ -5774,6 +5778,7 @@ struct cp_declarator { bool rvalue_ref; } reference; } u; + blt_node *bltnode; }; /* A level of template instantiation. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5b8e6a2..bcf305c 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "gimplify.h" #include "asan.h" +#include "blt.h" /* Possible cases of bad specifiers type used by bad_specifiers. */ enum bad_spec_place { @@ -9876,12 +9877,12 @@ name_unnamed_type (tree type, tree decl) declarator, in cases like "struct S;"), or the ERROR_MARK_NODE if an error occurs. */ -tree -grokdeclarator (const cp_declarator *declarator, - cp_decl_specifier_seq *declspecs, - enum decl_context decl_context, - int initialized, - tree* attrlist) +static tree +grokdeclarator_1 (const cp_declarator *declarator, + cp_decl_specifier_seq *declspecs, + enum decl_context decl_context, + int initialized, + tree* attrlist) { tree type = NULL_TREE; int longlong = 0; @@ -12349,6 +12350,20 @@ grokdeclarator (const cp_declarator *declarator, return decl; } } + +tree +grokdeclarator (const cp_declarator *declarator, + cp_decl_specifier_seq *declspecs, + enum decl_context decl_context, + int initialized, + tree* attrlist) +{ + tree result = grokdeclarator_1 (declarator, declspecs, decl_context, + initialized, attrlist); + if (declarator && declarator->bltnode) + declarator->bltnode->set_tree (result); + return result; +} /* Subroutine of start_function. Ensure that each of the parameter types (as listed in PARMS) is complete, as is required for a diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 88d0b2b..5e0b34e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see #include "cp-cilkplus.h" #include "gcc-rich-location.h" #include "tree-iterator.h" +#include "blt.h" /* The lexer. */ @@ -1348,6 +1349,181 @@ cp_token_cache_new (cp_token *first, cp_token *last) return cache; } + + +/* A RAII-style class for optionally building a concrete parse tree (or + at least, something close to it) as the recursive descent parser runs. + + Close to a no-op if -fblt is not selected. */ + +class auto_blt_node +{ +public: + auto_blt_node (cp_parser* parser, enum blt_kind kind, + cp_expr *expr_ptr = NULL); + ~auto_blt_node (); + + void set_tree (tree node); + +private: + cp_parser *m_parser; + cp_expr *m_expr_ptr; + blt_node *m_parent; +}; + +/* RAII-style construction of the blt_node tree: push a blt_node of KIND + onto the current stack of blt_nodes, popping it when it goes out + of scope. */ + +#define AUTO_BLT_NODE(PARSER, KIND) \ + auto_blt_node tmp_blt_node ((PARSER), (KIND)) + +/* As above, but with an addition cp_expr *. + If non-NULL, then the node's tree will be set to that of the tree + within the cp_expr when the AUTO_BLT_NODE_WITH_RETURN goes out of + scope. */ + +#define AUTO_BLT_NODE_WITH_RETURN(PARSER, KIND, ADDR_OF_CP_EXPR) \ + auto_blt_node tmp_blt_node ((PARSER), (KIND), (ADDR_OF_CP_EXPR)) + +/* The blt_node currently being constructed (the macro assumes that "parser" + exists in the current scope). */ + +#define CURRENT_BLT_NODE (parser->blt_current_node) + +/* Peek the next token within PARSER and a child node for it to the + current blt_node. */ + +#define BLT_ADD_NEXT_TOKEN(PARSER) \ + add_node_for_next_token (PARSER) + +/* Peek the next token within "parser" and a child node for it to the + current blt_node, using KIND as the kind. */ + +#define ADD_NODE_FOR_NEXT_TOKEN(KIND) \ + add_node_for_next_token (parser, (KIND)) + +/* Set the tree node for the current AUTO_BLT_NODE. */ + +#define BLT_SET_TREE(TREE_NODE) \ + tmp_blt_node.set_tree (TREE_NODE); + +/* Peek the next token within PARSER and a child node for it to the + current blt_node. */ + +static blt_node * +add_node_for_next_token (cp_parser *parser) +{ + if (!flag_blt) + return NULL; + + cp_token *token = cp_lexer_peek_token (parser->lexer); + blt_node *parent = parser->blt_current_node; + enum blt_kind kind = (enum blt_kind)token->type; + blt_node *node = new blt_node (kind, token->location); + parent->add_child (node); + node->set_finish (token->location); + return node; +} + +/* As above, but use KIND as the kind of the new blt_node. */ + +static blt_node * +add_node_for_next_token (cp_parser *parser, enum blt_kind kind) +{ + if (!flag_blt) + return NULL; + + cp_token *token = cp_lexer_peek_token (parser->lexer); + blt_node *parent = parser->blt_current_node; + blt_node *node = new blt_node (kind, token->location); + parent->add_child (node); + node->set_finish (token->location); + return node; +} + +/* auto_blt_node's constructor. + + If -fblt was not enabled, return immediately. + + Otherwise push a new blt_node of KIND as a child of the previous top + of the blt stack, effectively constructing a tree. + + Set the new blt_node's start location to that of the next token + within PARSER. */ + +auto_blt_node::auto_blt_node (cp_parser *parser, enum blt_kind kind, + cp_expr *expr_ptr) +{ + if (!flag_blt) + return; + + /* Do this here rather than as an initializer list + to avoid doing work when -fblt is not set. */ + m_parser = parser; + m_expr_ptr = expr_ptr; + m_parent = parser->blt_current_node; + + cp_token *first_token = cp_lexer_peek_token (parser->lexer); + blt_node *node = new blt_node (kind, first_token->location); + parser->blt_current_node = node; + if (m_parent) + m_parent->add_child (node); + else + parser->blt_root_node = node; +} + +/* auto_blt_node's destructor. + + If -fblt was not enabled, return immediately. + + Otherwise, pop the current blt_node from the stack, + and set its finish location to that of the last + token that was consumed. + + If m_expr_ptr was set, set the blt_node's tree to be that + of the m_expr_ptr. */ + +auto_blt_node::~auto_blt_node () +{ + if (!flag_blt) + return; + + blt_node *node = m_parser->blt_current_node; + + cp_token_position prev + = cp_lexer_previous_token_position (m_parser->lexer); + node->set_finish (cp_lexer_token_at (m_parser->lexer, prev)->location); + + if (0) + { + location_t start = node->get_start (); + location_t finish = node->get_finish (); + location_t range = make_location (start, start, finish); + inform (range, "%qs", node->get_name ()); + } + + if (m_expr_ptr) + node->set_tree (m_expr_ptr->get_value ()); + + /* Use stashed parent, rather than the curent node's parent + to allow for reparenting within the tree. */ + m_parser->blt_current_node = m_parent; +} + +/* Set the tree node for the current blt_node within this AUTO_BLT_NODE. */ + +void +auto_blt_node::set_tree (tree tree_node) +{ + if (!flag_blt) + return; + + blt_node *node = m_parser->blt_current_node; + node->set_tree (tree_node); +} + + /* Diagnose if #pragma omp declare simd isn't followed immediately by function declaration or definition. */ @@ -1456,6 +1632,7 @@ make_declarator (cp_declarator_kind kind) declarator->declarator = NULL; declarator->parameter_pack_p = false; declarator->id_loc = UNKNOWN_LOCATION; + declarator->bltnode = NULL; return declarator; } @@ -1691,7 +1868,8 @@ cp_parameter_declarator * make_parameter_declarator (cp_decl_specifier_seq *decl_specifiers, cp_declarator *declarator, tree default_argument, - bool template_parameter_pack_p = false) + bool template_parameter_pack_p = false, + blt_node *bltnode = NULL) { cp_parameter_declarator *parameter; @@ -1705,6 +1883,7 @@ make_parameter_declarator (cp_decl_specifier_seq *decl_specifiers, parameter->declarator = declarator; parameter->default_argument = default_argument; parameter->template_parameter_pack_p = template_parameter_pack_p; + parameter->bltnode = bltnode; return parameter; } @@ -3868,6 +4047,10 @@ cp_parser_identifier (cp_parser* parser) { cp_token *token; + AUTO_BLT_NODE (parser, BLT_IDENTIFIER); + if (0) + BLT_ADD_NEXT_TOKEN (parser); + /* Look for the identifier. */ token = cp_parser_require (parser, CPP_NAME, RT_NAME); /* Return the value. */ @@ -4371,19 +4554,23 @@ cp_parser_translation_unit (cp_parser* parser) bool success; - /* Create the declarator obstack, if necessary. */ - if (!cp_error_declarator) - { - gcc_obstack_init (&declarator_obstack); - /* Create the error declarator. */ - cp_error_declarator = make_declarator (cdk_error); - /* Create the empty parameter list. */ - no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE); - /* Remember where the base of the declarator obstack lies. */ - declarator_obstack_base = obstack_next_free (&declarator_obstack); - } + { + AUTO_BLT_NODE (parser, BLT_TRANSLATION_UNIT); - cp_parser_declaration_seq_opt (parser); + /* Create the declarator obstack, if necessary. */ + if (!cp_error_declarator) + { + gcc_obstack_init (&declarator_obstack); + /* Create the error declarator. */ + cp_error_declarator = make_declarator (cdk_error); + /* Create the empty parameter list. */ + no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE); + /* Remember where the base of the declarator obstack lies. */ + declarator_obstack_base = obstack_next_free (&declarator_obstack); + } + + cp_parser_declaration_seq_opt (parser); + } /* If there are no tokens left then all went well. */ if (cp_lexer_next_token_is (parser->lexer, CPP_EOF)) @@ -4787,6 +4974,8 @@ cp_parser_primary_expression (cp_parser *parser, bool decltype_p, cp_id_kind *idk) { + AUTO_BLT_NODE (parser, BLT_PRIMARY_EXPRESSION); + cp_token *token = NULL; /* Assume the primary expression is not an id-expression. */ @@ -5419,6 +5608,8 @@ cp_parser_id_expression (cp_parser *parser, bool declarator_p, bool optional_p) { + AUTO_BLT_NODE (parser, BLT_ID_EXPRESSION); + bool global_scope_p; bool nested_name_specifier_p; @@ -5558,6 +5749,8 @@ cp_parser_unqualified_id (cp_parser* parser, bool declarator_p, bool optional_p) { + AUTO_BLT_NODE (parser, BLT_UNQUALIFIED_ID); + cp_token *token; /* Peek at the next token. */ @@ -6419,6 +6612,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, bool is_member_access = false; int saved_in_statement = -1; + AUTO_BLT_NODE_WITH_RETURN (parser, BLT_POSTFIX_EXPRESSION, &postfix_expression); + /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); loc = token->location; @@ -6438,6 +6633,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, const char *saved_message; bool saved_in_type_id_in_expr_p; + BLT_ADD_NEXT_TOKEN (parser); + /* All of these can be handled in the same way from the point of view of parsing. Begin by consuming the token identifying the cast. */ @@ -6524,6 +6721,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, bool saved_in_type_id_in_expr_p; /* Consume the `typeid' token. */ + BLT_ADD_NEXT_TOKEN (parser); cp_lexer_consume_token (parser->lexer); /* Look for the `(' token. */ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); @@ -7552,6 +7750,8 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, bool *non_constant_p, location_t *close_paren_loc) { + AUTO_BLT_NODE (parser, BLT_EXPRESSION_LIST); + vec<tree, va_gc> *expression_list; bool fold_expr_p = is_attribute_list != non_attr; tree identifier = NULL_TREE; @@ -7830,6 +8030,8 @@ static cp_expr cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk, bool address_p, bool cast_p, bool decltype_p) { + AUTO_BLT_NODE (parser, BLT_UNARY_EXPRESSION); + cp_token *token; enum tree_code unary_operator; @@ -9297,6 +9499,7 @@ static cp_expr cp_parser_assignment_expression (cp_parser* parser, cp_id_kind * pidk, bool cast_p, bool decltype_p) { + AUTO_BLT_NODE (parser, BLT_ASSIGNMENT_EXPRESSION); cp_expr expr; /* If the next token is the `throw' keyword, then we're looking at @@ -12502,6 +12705,8 @@ cp_parser_already_scoped_statement (cp_parser* parser, bool *if_p, static void cp_parser_declaration_seq_opt (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_DECLARATION_SEQ); + while (true) { cp_token *token; @@ -12573,6 +12778,8 @@ cp_parser_declaration_seq_opt (cp_parser* parser) static void cp_parser_declaration (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_DECLARATION); + cp_token token1; cp_token token2; int saved_pedantic; @@ -12717,6 +12924,8 @@ cp_parser_block_declaration (cp_parser *parser, return; } + AUTO_BLT_NODE (parser, BLT_BLOCK_DECLARATION); + /* Peek at the next token to figure out which kind of declaration is present. */ token1 = cp_lexer_peek_token (parser->lexer); @@ -12801,6 +13010,8 @@ cp_parser_simple_declaration (cp_parser* parser, bool function_definition_allowed_p, tree *maybe_range_for_decl) { + AUTO_BLT_NODE (parser, BLT_SIMPLE_DECLARATION); + cp_decl_specifier_seq decl_specifiers; int declares_class_or_enum; bool saw_declarator; @@ -13291,6 +13502,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser, cp_decl_specifier_seq *decl_specs, int* declares_class_or_enum) { + AUTO_BLT_NODE (parser, BLT_DECL_SPECIFIER_SEQ); + bool constructor_possible_p = !parser->in_declarator_p; bool found_decl_spec = false; cp_token *start_token = NULL; @@ -13390,6 +13603,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, else { ds = ds_friend; + ADD_NODE_FOR_NEXT_TOKEN (BLT_DECL_SPECIFIER); /* Consume the token. */ cp_lexer_consume_token (parser->lexer); } @@ -13397,6 +13611,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, case RID_CONSTEXPR: ds = ds_constexpr; + ADD_NODE_FOR_NEXT_TOKEN (BLT_DECL_SPECIFIER); cp_lexer_consume_token (parser->lexer); break; @@ -13419,6 +13634,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, typedef */ case RID_TYPEDEF: ds = ds_typedef; + ADD_NODE_FOR_NEXT_TOKEN (BLT_DECL_SPECIFIER); /* Consume the token. */ cp_lexer_consume_token (parser->lexer); /* A constructor declarator cannot appear in a typedef. */ @@ -13443,6 +13659,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, case RID_AUTO: if (cxx_dialect == cxx98) { + ADD_NODE_FOR_NEXT_TOKEN (BLT_DECL_SPECIFIER); /* Consume the token. */ cp_lexer_consume_token (parser->lexer); @@ -13467,6 +13684,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, case RID_STATIC: case RID_EXTERN: case RID_MUTABLE: + ADD_NODE_FOR_NEXT_TOKEN (BLT_DECL_SPECIFIER); /* Consume the token. */ cp_lexer_consume_token (parser->lexer); cp_parser_set_storage_class (parser, decl_specs, token->keyword, @@ -13475,6 +13693,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, case RID_THREAD: /* Consume the token. */ ds = ds_thread; + ADD_NODE_FOR_NEXT_TOKEN (BLT_DECL_SPECIFIER); cp_lexer_consume_token (parser->lexer); break; @@ -14852,6 +15071,8 @@ cp_parser_operator (cp_parser* parser) static void cp_parser_template_declaration (cp_parser* parser, bool member_p) { + AUTO_BLT_NODE (parser, BLT_TEMPLATE_DECLARATION); + /* Check for `export'. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXPORT)) { @@ -14876,6 +15097,8 @@ cp_parser_template_declaration (cp_parser* parser, bool member_p) static tree cp_parser_template_parameter_list (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_TEMPLATE_PARAMETER_LIST); + tree parameter_list = NULL_TREE; begin_template_parm_list (); @@ -16348,6 +16571,8 @@ cp_parser_template_argument (cp_parser* parser) static void cp_parser_explicit_instantiation (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_EXPLICIT_INSTANTIATION); + int declares_class_or_enum; cp_decl_specifier_seq decl_specifiers; tree extension_specifier = NULL_TREE; @@ -16461,6 +16686,8 @@ cp_parser_explicit_instantiation (cp_parser* parser) static void cp_parser_explicit_specialization (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_EXPLICIT_SPECIALIZATION); + bool need_lang_pop; cp_token *token = cp_lexer_peek_token (parser->lexer); @@ -16562,6 +16789,8 @@ cp_parser_type_specifier (cp_parser* parser, int* declares_class_or_enum, bool* is_cv_qualifier) { + AUTO_BLT_NODE (parser, BLT_TYPE_SPECIFIER); + tree type_spec = NULL_TREE; cp_token *token; enum rid keyword; @@ -16652,18 +16881,21 @@ cp_parser_type_specifier (cp_parser* parser, case RID_CONST: ds = ds_const; + ADD_NODE_FOR_NEXT_TOKEN (BLT_CV_QUALIFIER); if (is_cv_qualifier) *is_cv_qualifier = true; break; case RID_VOLATILE: ds = ds_volatile; + ADD_NODE_FOR_NEXT_TOKEN (BLT_CV_QUALIFIER); if (is_cv_qualifier) *is_cv_qualifier = true; break; case RID_RESTRICT: ds = ds_restrict; + ADD_NODE_FOR_NEXT_TOKEN (BLT_CV_QUALIFIER); if (is_cv_qualifier) *is_cv_qualifier = true; break; @@ -19108,6 +19340,48 @@ strip_declarator_types (tree type, cp_declarator *declarator) return type; } +/* Subroutine for cp_parser_init_declarator for once + we know we're dealing with a function-definition. + + We're below a: + + PARENT + `-block-declaration + `-simple-declaration + |-decl-specifier-seq + |-declarator + + Convert the simple-declaration to a function-definition, + and lose the block-declaration, resulting in: + + + PARENT + `-function-definition + |-decl-specifier-seq + |-declarator. */ + +static void +update_blt_for_function_definition (cp_parser *parser) +{ + if (!CURRENT_BLT_NODE) + return; + + blt_node *block_decl + = CURRENT_BLT_NODE->get_ancestor_of_kind (BLT_BLOCK_DECLARATION); + + if (!block_decl) + /* We might have a template-declaration. */ + return; + + blt_node *simple_decl + = block_decl->get_first_child_of_kind (BLT_SIMPLE_DECLARATION); + gcc_assert (simple_decl); + + blt_node *parent = block_decl->get_parent (); + gcc_assert (parent); + + simple_decl->set_kind (BLT_FUNCTION_DEFINITION); + parent->replace_child (block_decl, simple_decl); +} + /* Declarators [gram.dcl.decl] */ /* Parse an init-declarator. @@ -19324,6 +19598,7 @@ cp_parser_init_declarator (cp_parser* parser, "on a function-definition"); /* This is a function-definition. */ *function_definition_p = true; + update_blt_for_function_definition (parser); /* Parse the function definition. */ if (member_p) @@ -19640,6 +19915,8 @@ cp_parser_declarator (cp_parser* parser, bool* parenthesized_p, bool member_p, bool friend_p) { + AUTO_BLT_NODE (parser, BLT_DECLARATOR); + cp_declarator *declarator; enum tree_code code; cp_cv_quals cv_quals; @@ -19741,6 +20018,8 @@ cp_parser_direct_declarator (cp_parser* parser, int* ctor_dtor_or_conv_p, bool member_p, bool friend_p) { + AUTO_BLT_NODE (parser, BLT_DIRECT_DECLARATOR); + cp_token *token; cp_declarator *declarator = NULL; tree scope = NULL_TREE; @@ -19808,6 +20087,7 @@ cp_parser_direct_declarator (cp_parser* parser, cp_parser_parse_tentatively (parser); /* Consume the `('. */ + BLT_ADD_NEXT_TOKEN (parser); cp_lexer_consume_token (parser->lexer); if (first) { @@ -20254,6 +20534,9 @@ cp_parser_direct_declarator (cp_parser* parser, parser->default_arg_ok_p = saved_default_arg_ok_p; parser->in_declarator_p = saved_in_declarator_p; + if (declarator) + declarator->bltnode = CURRENT_BLT_NODE; + return declarator; } @@ -20396,6 +20679,8 @@ cp_parser_ptr_operator (cp_parser* parser, static cp_cv_quals cp_parser_cv_qualifier_seq_opt (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_CV_QUALIFIER_SEQ); + cp_cv_quals cv_quals = TYPE_UNQUALIFIED; while (true) @@ -20428,6 +20713,8 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser) if (!cv_qualifier) break; + ADD_NODE_FOR_NEXT_TOKEN (BLT_CV_QUALIFIER); + if (cv_quals & cv_qualifier) { gcc_rich_location richloc (token->location); @@ -21039,6 +21326,8 @@ function_being_declared_is_template_p (cp_parser* parser) static tree cp_parser_parameter_declaration_clause (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_PARAMETER_DECLARATION_CLAUSE); + tree parameters; cp_token *token; bool ellipsis_p; @@ -21068,6 +21357,7 @@ cp_parser_parameter_declaration_clause (cp_parser* parser) if (token->type == CPP_ELLIPSIS) { /* Consume the `...' token. */ + BLT_ADD_NEXT_TOKEN (parser); cp_lexer_consume_token (parser->lexer); return NULL_TREE; } @@ -21089,6 +21379,7 @@ cp_parser_parameter_declaration_clause (cp_parser* parser) == CPP_CLOSE_PAREN)) { /* Consume the `void' token. */ + BLT_ADD_NEXT_TOKEN (parser); cp_lexer_consume_token (parser->lexer); /* There are no parameters. */ return void_list_node; @@ -21108,6 +21399,7 @@ cp_parser_parameter_declaration_clause (cp_parser* parser) if (token->type == CPP_COMMA) { /* Consume the `,'. */ + BLT_ADD_NEXT_TOKEN (parser); cp_lexer_consume_token (parser->lexer); /* Expect an ellipsis. */ ellipsis_p @@ -21118,6 +21410,7 @@ cp_parser_parameter_declaration_clause (cp_parser* parser) else if (token->type == CPP_ELLIPSIS) { /* Consume the `...' token. */ + BLT_ADD_NEXT_TOKEN (parser); cp_lexer_consume_token (parser->lexer); /* And remember that we saw it. */ ellipsis_p = true; @@ -21129,6 +21422,7 @@ cp_parser_parameter_declaration_clause (cp_parser* parser) if (!ellipsis_p) parameters = chainon (parameters, void_list_node); + BLT_SET_TREE (parameters); return parameters; } @@ -21146,6 +21440,7 @@ cp_parser_parameter_declaration_clause (cp_parser* parser) static tree cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) { + AUTO_BLT_NODE (parser, BLT_PARAMETER_DECLARATION_LIST); tree parameters = NULL_TREE; tree *tail = ¶meters; bool saved_in_unbraced_linkage_specification_p; @@ -21203,6 +21498,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) PARM, parameter->default_argument != NULL_TREE, ¶meter->decl_specifiers.attributes); + BLT_SET_TREE (decl); } deprecated_state = DEPRECATED_NORMAL; @@ -21253,6 +21549,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) break; /* Otherwise, there must be more parameters. Consume the `,'. */ + BLT_ADD_NEXT_TOKEN (parser); cp_lexer_consume_token (parser->lexer); /* When parsing something like: @@ -21308,6 +21605,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) } } + BLT_SET_TREE (parameters); return parameters; } @@ -21333,6 +21631,8 @@ cp_parser_parameter_declaration (cp_parser *parser, bool template_parm_p, bool *parenthesized_p) { + AUTO_BLT_NODE (parser, BLT_PARAMETER_DECLARATION); + int declares_class_or_enum; cp_decl_specifier_seq decl_specifiers; cp_declarator *declarator; @@ -21543,7 +21843,8 @@ cp_parser_parameter_declaration (cp_parser *parser, return make_parameter_declarator (&decl_specifiers, declarator, default_argument, - template_parameter_pack_p); + template_parameter_pack_p, + CURRENT_BLT_NODE); } /* Parse a default argument and return it. @@ -22207,6 +22508,8 @@ cp_parser_class_specifier_1 (cp_parser* parser) tree scope = NULL_TREE; cp_token *closing_brace; + AUTO_BLT_NODE (parser, BLT_CLASS_SPECIFIER); + push_deferring_access_checks (dk_no_deferred); /* Parse the class-head. */ @@ -22515,6 +22818,8 @@ cp_parser_class_specifier_1 (cp_parser* parser) parser->in_unbraced_linkage_specification_p = saved_in_unbraced_linkage_specification_p; + BLT_SET_TREE (type); + return type; } @@ -22563,6 +22868,8 @@ static tree cp_parser_class_head (cp_parser* parser, bool* nested_name_specifier_p) { + AUTO_BLT_NODE (parser, BLT_CLASS_HEAD); + tree nested_name_specifier; enum tag_types class_key; tree id = NULL_TREE; @@ -23041,6 +23348,8 @@ cp_parser_class_key (cp_parser* parser) cp_token *token; enum tag_types tag_type; + AUTO_BLT_NODE (parser, BLT_CLASS_KEY); + /* Look for the class-key. */ token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_KEY); if (!token) @@ -23171,9 +23480,11 @@ cp_parser_member_specification_opt (cp_parser* parser) static void cp_parser_member_declaration (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_MEMBER_DECLARATION); + cp_decl_specifier_seq decl_specifiers; tree prefix_attributes; - tree decl; + tree decl = NULL_TREE; int declares_class_or_enum; bool friend_p; cp_token *token = NULL; @@ -23677,6 +23988,7 @@ cp_parser_member_declaration (cp_parser* parser) cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); out: parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; + BLT_SET_TREE (decl); } /* Parse a pure-specifier. @@ -24140,6 +24452,8 @@ cp_parser_exception_specification_opt (cp_parser* parser) static tree cp_parser_type_id_list (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_TYPE_ID_LIST); + tree types = NULL_TREE; while (true) @@ -24189,6 +24503,8 @@ cp_parser_type_id_list (cp_parser* parser) static tree cp_parser_try_block (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_TRY_BLOCK); + tree try_block; cp_parser_require_keyword (parser, RID_TRY, RT_TRY); @@ -24213,6 +24529,8 @@ cp_parser_try_block (cp_parser* parser) static bool cp_parser_function_try_block (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_FUNCTION_TRY_BLOCK); + tree compound_stmt; tree try_block; bool ctor_initializer_p; @@ -24243,6 +24561,8 @@ cp_parser_function_try_block (cp_parser* parser) static void cp_parser_handler_seq (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_HANDLER_SEQ); + while (true) { cp_token *token; @@ -24265,6 +24585,8 @@ cp_parser_handler_seq (cp_parser* parser) static void cp_parser_handler (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_HANDLER); + tree handler; tree declaration; @@ -24292,6 +24614,8 @@ cp_parser_handler (cp_parser* parser) static tree cp_parser_exception_declaration (cp_parser* parser) { + AUTO_BLT_NODE (parser, BLT_EXCEPTION_DECLARATION); + cp_decl_specifier_seq type_specifiers; cp_declarator *declarator; const char *saved_message; @@ -24345,6 +24669,8 @@ cp_parser_throw_expression (cp_parser* parser) tree expression; cp_token* token; + AUTO_BLT_NODE (parser, BLT_THROW_EXPRESSION); + cp_parser_require_keyword (parser, RID_THROW, RT_THROW); token = cp_lexer_peek_token (parser->lexer); /* Figure out whether or not there is an assignment-expression @@ -24386,6 +24712,8 @@ cp_parser_asm_specification_opt (cp_parser* parser) if (!cp_parser_is_keyword (token, RID_ASM)) return NULL_TREE; + AUTO_BLT_NODE (parser, BLT_ASM_SPECIFICATION); + /* Consume the `asm' token. */ cp_lexer_consume_token (parser->lexer); /* Look for the `('. */ @@ -28113,7 +28441,10 @@ cp_parser_require (cp_parser* parser, required_token token_desc) { if (cp_lexer_next_token_is (parser->lexer, type)) - return cp_lexer_consume_token (parser->lexer); + { + BLT_ADD_NEXT_TOKEN (parser); + return cp_lexer_consume_token (parser->lexer); + } else { /* Output the MESSAGE -- unless we're parsing tentatively. */ @@ -38647,6 +38978,12 @@ c_parse_file (void) push_deferring_access_checks (flag_access_control ? dk_no_deferred : dk_no_check); cp_parser_translation_unit (the_parser); + + if (flag_blt && flag_dump_blt) + the_parser->blt_root_node->dump (stderr); + + the_blt_root_node = the_parser->blt_root_node; + the_parser = NULL; } diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h index 0994e1e..49c8eb6 100644 --- a/gcc/cp/parser.h +++ b/gcc/cp/parser.h @@ -213,6 +213,8 @@ struct cp_oacc_routine_data : cp_omp_declare_simd_data { location_t loc; }; +class blt_node; + /* The cp_parser structure represents the C++ parser. */ struct GTY(()) cp_parser { @@ -412,6 +414,11 @@ struct GTY(()) cp_parser { context e.g., because they could never be deduced. */ int prevent_constrained_type_specifiers; + /* The top-level node for the translation-unit. */ + blt_node * GTY((skip)) blt_root_node; + + /* The current node being parsed. */ + blt_node * GTY((skip)) blt_current_node; }; /* In parser.c */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index da133bd..8db4b4b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "type-utils.h" #include "gimplify.h" #include "gcc-rich-location.h" +#include "blt.h" /* The type of functions taking a tree, and some additional data, and returning an int. */ @@ -4480,6 +4481,13 @@ build_template_decl (tree decl, tree parms, bool member_template_p) DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl); DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p; + if (flag_blt) + { + blt_node *decl_bltnode = blt_get_node_for_tree (decl); + if (decl_bltnode) + blt_set_node_for_tree (tmpl, decl_bltnode); + } + return tmpl; } -- 1.8.5.3