diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-01-06 21:32:17 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-01-06 21:32:17 +0000 |
commit | 8218bd343200357293bca59a4d7673ab5ffa9385 (patch) | |
tree | bab0d0d9d1d1b658dddf4aebbea275c799fc2f10 | |
parent | 1c26d8fd84049ea0c57a9d5aba38bc2c0e552ebb (diff) | |
download | gcc-8218bd343200357293bca59a4d7673ab5ffa9385.zip gcc-8218bd343200357293bca59a4d7673ab5ffa9385.tar.gz gcc-8218bd343200357293bca59a4d7673ab5ffa9385.tar.bz2 |
re PR c++/9189 ([New parser] Order of default argument processing and function body compilation)
PR c++/9189
* parser.c (cp_parser): Remove default_arg_types. Update
documentation for unparsed_functions_queues.
(cp_parser_late_parsing_default_args): Take a FUNCTION_DECL as the
parameter.
(cp_parser_new): Don't set parser->default_arg_types.
(cp_parser_function_definition): Adjust usage of
unparsed_funtions_queues.
(cp_parser_class_specifier): Don't mess with
parser->default_arg_types. Handle default argument processing in
a separate phase from function body processing.
(cp_parser_template_declaration_after_export): Adjust usage of
unparsed_functions_queues.
(cp_parser_late_parsing_for_member): Do not handle default
arguments.
PR c++/9189
* g++.dg/parse/defarg3.C: New test.
From-SVN: r60956
-rw-r--r-- | gcc/cp/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/cp/parser.c | 89 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/defarg3.C | 5 |
4 files changed, 71 insertions, 46 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d4284a5..70bc9ee 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,21 @@ +2003-01-06 Mark Mitchell <mark@codesourcery.com> + + PR c++/9189 + * parser.c (cp_parser): Remove default_arg_types. Update + documentation for unparsed_functions_queues. + (cp_parser_late_parsing_default_args): Take a FUNCTION_DECL as the + parameter. + (cp_parser_new): Don't set parser->default_arg_types. + (cp_parser_function_definition): Adjust usage of + unparsed_funtions_queues. + (cp_parser_class_specifier): Don't mess with + parser->default_arg_types. Handle default argument processing in + a separate phase from function body processing. + (cp_parser_template_declaration_after_export): Adjust usage of + unparsed_functions_queues. + (cp_parser_late_parsing_for_member): Do not handle default + arguments. + 2003-01-06 Nathan Sidwell <nathan@codesourcery.com> PR c++/9109 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d1c2c30..e9b41e4 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1330,12 +1330,6 @@ typedef struct cp_parser GTY(()) issued as an error message if a type is defined. */ const char *type_definition_forbidden_message; - /* List of FUNCTION_TYPEs which contain unprocessed DEFAULT_ARGs - during class parsing, and are not FUNCTION_DECLs. G++ has an - awkward extension allowing default args on pointers to functions - etc. */ - tree default_arg_types; - /* A TREE_LIST of queues of functions whose bodies have been lexed, but may not have been parsed. These functions are friends of members defined within a class-specification; they are not @@ -1343,9 +1337,9 @@ typedef struct cp_parser GTY(()) front of the list. Within each queue, functions appear in the reverse order that - they appeared in the source. The TREE_PURPOSE of each node is - the class in which the function was defined or declared; the - TREE_VALUE is the FUNCTION_DECL itself. */ + they appeared in the source. Each TREE_VALUE is a + FUNCTION_DECL of TEMPLATE_DECL corresponding to a member + function. */ tree unparsed_functions_queues; /* The number of classes whose definitions are currently in @@ -1731,7 +1725,7 @@ static tree cp_parser_functional_cast static void cp_parser_late_parsing_for_member PARAMS ((cp_parser *, tree)); static void cp_parser_late_parsing_default_args - (cp_parser *, tree, tree); + (cp_parser *, tree); static tree cp_parser_sizeof_operand PARAMS ((cp_parser *, enum rid)); static bool cp_parser_declares_only_class_p @@ -2504,9 +2498,6 @@ cp_parser_new () /* We are not processing a declarator. */ parser->in_declarator_p = false; - /* There are no default args to process. */ - parser->default_arg_types = NULL; - /* The unparsed function queue is empty. */ parser->unparsed_functions_queues = build_tree_list (NULL_TREE, NULL_TREE); @@ -11243,7 +11234,7 @@ cp_parser_function_definition (parser, friend_p) /* Add FN to the queue of functions to be parsed later. */ TREE_VALUE (parser->unparsed_functions_queues) - = tree_cons (current_class_type, fn, + = tree_cons (NULL_TREE, fn, TREE_VALUE (parser->unparsed_functions_queues)); return fn; @@ -11695,29 +11686,44 @@ cp_parser_class_specifier (parser) if (--parser->num_classes_being_defined == 0) { tree last_scope = NULL_TREE; + tree queue_entry; + tree fn; - /* Process non FUNCTION_DECL related DEFAULT_ARGs. */ - for (parser->default_arg_types = nreverse (parser->default_arg_types); - parser->default_arg_types; - parser->default_arg_types = TREE_CHAIN (parser->default_arg_types)) - cp_parser_late_parsing_default_args - (parser, TREE_PURPOSE (parser->default_arg_types), NULL_TREE); - /* Reverse the queue, so that we process it in the order the functions were declared. */ TREE_VALUE (parser->unparsed_functions_queues) = nreverse (TREE_VALUE (parser->unparsed_functions_queues)); - /* Loop through all of the functions. */ + /* In a first pass, parse default arguments to the functions. + Then, in a second pass, parse the bodies of the functions. + This two-phased approach handles cases like: + + struct S { + void f() { g(); } + void g(int i = 3); + }; + + */ + for (queue_entry = TREE_VALUE (parser->unparsed_functions_queues); + queue_entry; + queue_entry = TREE_CHAIN (queue_entry)) + { + fn = TREE_VALUE (queue_entry); + if (DECL_FUNCTION_TEMPLATE_P (fn)) + fn = DECL_TEMPLATE_RESULT (fn); + /* Make sure that any template parameters are in scope. */ + maybe_begin_member_template_processing (fn); + /* If there are default arguments that have not yet been processed, + take care of them now. */ + cp_parser_late_parsing_default_args (parser, fn); + /* Remove any template parameters from the symbol table. */ + maybe_end_member_template_processing (); + } + /* Now parse the body of the functions. */ while (TREE_VALUE (parser->unparsed_functions_queues)) { - tree fn; - tree fn_scope; - tree queue_entry; - /* Figure out which function we need to process. */ queue_entry = TREE_VALUE (parser->unparsed_functions_queues); - fn_scope = TREE_PURPOSE (queue_entry); fn = TREE_VALUE (queue_entry); /* Parse the function. */ @@ -12448,7 +12454,7 @@ cp_parser_member_declaration (parser) there might be default arguments that need handling.) */ if (TREE_CODE (decl) == FUNCTION_DECL) TREE_VALUE (parser->unparsed_functions_queues) - = tree_cons (current_class_type, decl, + = tree_cons (NULL_TREE, decl, TREE_VALUE (parser->unparsed_functions_queues)); } } @@ -14238,7 +14244,7 @@ cp_parser_template_declaration_after_export (parser, member_p) && (TREE_CODE (decl) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (decl))) TREE_VALUE (parser->unparsed_functions_queues) - = tree_cons (current_class_type, decl, + = tree_cons (NULL_TREE, decl, TREE_VALUE (parser->unparsed_functions_queues)); } @@ -14384,13 +14390,6 @@ cp_parser_late_parsing_for_member (parser, member_function) /* Make sure that any template parameters are in scope. */ maybe_begin_member_template_processing (member_function); - /* If there are default arguments that have not yet been processed, - take care of them now. */ - cp_parser_late_parsing_default_args (parser, TREE_TYPE (member_function), - DECL_FUNCTION_MEMBER_P (member_function) - ? DECL_CONTEXT (member_function) - : NULL_TREE); - /* If the body of the function has not yet been parsed, parse it now. */ if (DECL_PENDING_INLINE_P (member_function)) @@ -14444,20 +14443,18 @@ cp_parser_late_parsing_for_member (parser, member_function) = TREE_CHAIN (parser->unparsed_functions_queues); } -/* TYPE is a FUNCTION_TYPE or METHOD_TYPE which contains a parameter - with an unparsed DEFAULT_ARG. If non-NULL, SCOPE is the class in - whose context name lookups in the default argument should occur. - Parse the default args now. */ +/* FN is a FUNCTION_DECL which may contains a parameter with an + unparsed DEFAULT_ARG. Parse the default args now. */ static void -cp_parser_late_parsing_default_args (cp_parser *parser, tree type, tree scope) +cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) { cp_lexer *saved_lexer; cp_token_cache *tokens; bool saved_local_variables_forbidden_p; tree parameters; - - for (parameters = TYPE_ARG_TYPES (type); + + for (parameters = TYPE_ARG_TYPES (TREE_TYPE (fn)); parameters; parameters = TREE_CHAIN (parameters)) { @@ -14481,10 +14478,10 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree type, tree scope) saved_local_variables_forbidden_p = parser->local_variables_forbidden_p; parser->local_variables_forbidden_p = true; /* Parse the assignment-expression. */ - if (scope) - push_nested_class (scope, 1); + if (DECL_CONTEXT (fn)) + push_nested_class (DECL_CONTEXT (fn), 1); TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser); - if (scope) + if (DECL_CONTEXT (fn)) pop_nested_class (); /* Restore saved state. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c6c0cd0..2c8bb11 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-01-06 Mark Mitchell <mark@codesourcery.com> + + PR c++/9189 + * g++.dg/parse/defarg3.C: New test. + 2003-01-06 Nathan Sidwell <nathan@codesourcery.com> * g++.dg/parse/ambig1.C: New test. diff --git a/gcc/testsuite/g++.dg/parse/defarg3.C b/gcc/testsuite/g++.dg/parse/defarg3.C new file mode 100644 index 0000000..5c81c69 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/defarg3.C @@ -0,0 +1,5 @@ +struct A { + enum { value = 10 }; + A() { f(); } + static int f(int i=value); +}; |