OSDN Git Service

PR c++/9189
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 6 Jan 2003 21:32:17 +0000 (21:32 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 6 Jan 2003 21:32:17 +0000 (21:32 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@60956 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/defarg3.C [new file with mode: 0644]

index d4284a5..70bc9ee 100644 (file)
@@ -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
index d1c2c30..e9b41e4 100644 (file)
@@ -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.  */
index c6c0cd0..2c8bb11 100644 (file)
@@ -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 (file)
index 0000000..5c81c69
--- /dev/null
@@ -0,0 +1,5 @@
+struct A {
+    enum { value = 10 };
+    A() { f(); }
+    static int f(int i=value);
+};