cp-tree.h (LOOKUP_TEMPLATES_EXPECTED): Remove.
authorMark Mitchell <mark@codesourcery.com>
Wed, 1 Jan 2003 03:16:16 +0000 (03:16 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 1 Jan 2003 03:16:16 +0000 (03:16 +0000)
* cp-tree.h (LOOKUP_TEMPLATES_EXPECTED): Remove.
(lookup_name_namespace_only): Likewise.
(begin_only_namespace_names): Likewise.
(end_only_namespace_names): Likewise.
* decl.c (only_namespace_names): Remove.
(qualify_lookup): Do not check LOOKUP_TEMPLATES_EXPECTED.
(lookup_name_real): Do not check only_namespace_names.
(lookup_name_namespace_only): Remove.
(begin_only_namespace_names): Likewise.
(end_only_namespace_names): Likewise.
* parser.c (cp_parser_nested_name_specifier_opt): Handle erroneous
nested-name-specifiers more gracefully.
(cp_parser_class_or_namespace_name): Avoid looking up namespace
names when they cannot possibly appear.
(cp_parser_template_name): Adjust call to cp_parser_lookup_name.
(cp_parser_elaborated_type_specifier): Likewise.
(cp_parser_namespace_name): Only look for namespace names.
(cp_parser_lookup_name): Add is_namespace parameter.
(cp_parser_lookup_name_simple): Adjust call to
cp_parser_lookup_name.

* g++.dg/parse/namespace1.C: New test.

From-SVN: r60729

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/namespace1.C [new file with mode: 0644]

index bd626bf7e9fb840df621b267cec70223c8a59466..8fed4792f3fe276b8300b8841043d69870eebfd5 100644 (file)
@@ -1,11 +1,32 @@
-2002-12-31  Neil Booth  <neil@daikokuya.co.uk>
-
-       * .cvsignore: Update.
-
 2002-12-31  Mark Mitchell  <mark@codesourcery.com>
 
+       * cp-tree.h (LOOKUP_TEMPLATES_EXPECTED): Remove.
+       (lookup_name_namespace_only): Likewise.
+       (begin_only_namespace_names): Likewise.
+       (end_only_namespace_names): Likewise.
+       * decl.c (only_namespace_names): Remove.
+       (qualify_lookup): Do not check LOOKUP_TEMPLATES_EXPECTED.
+       (lookup_name_real): Do not check only_namespace_names.
+       (lookup_name_namespace_only): Remove.
+       (begin_only_namespace_names): Likewise.
+       (end_only_namespace_names): Likewise.
+       * parser.c (cp_parser_nested_name_specifier_opt): Handle erroneous
+       nested-name-specifiers more gracefully.
+       (cp_parser_class_or_namespace_name): Avoid looking up namespace
+       names when they cannot possibly appear.
+       (cp_parser_template_name): Adjust call to cp_parser_lookup_name.
+       (cp_parser_elaborated_type_specifier): Likewise.
+       (cp_parser_namespace_name): Only look for namespace names.
+       (cp_parser_lookup_name): Add is_namespace parameter.
+       (cp_parser_lookup_name_simple): Adjust call to
+       cp_parser_lookup_name.
+
        * parser.c (cp_parser_dependent_type_p): Fix thinko.
 
+2002-12-31  Neil Booth  <neil@daikokuya.co.uk>
+
+       * .cvsignore: Update.
+
 2002-12-31  Nathan Sidwell  <nathan@codesourcery.com>
 
        * class.c (modify_vtable_entry): Remove unused variable.
index e27c66832ea9d2195e8c45ab2d10f69c73973426..761976757134c3001157ad9653d63aecc12883a4 100644 (file)
@@ -3385,9 +3385,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
 
    LOOKUP_PREFER_TYPES means not to accept objects, and possibly namespaces.
    LOOKUP_PREFER_NAMESPACES means not to accept objects, and possibly types.
-   LOOKUP_PREFER_BOTH means class-or-namespace-name.
-   LOOKUP_TEMPLATES_EXPECTED means that class templates also count
-     as types.  */
+   LOOKUP_PREFER_BOTH means class-or-namespace-name.  */
 
 #define LOOKUP_PROTECT (1)
 #define LOOKUP_COMPLAIN (2)
@@ -3403,7 +3401,6 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
 #define LOOKUP_PREFER_TYPES (2048)
 #define LOOKUP_PREFER_NAMESPACES (4096)
 #define LOOKUP_PREFER_BOTH (6144)
-#define LOOKUP_TEMPLATES_EXPECTED (8192)
 
 #define LOOKUP_NAMESPACES_ONLY(F)  \
   (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
@@ -3738,10 +3735,7 @@ extern tree lookup_qualified_name               (tree, tree, bool, int);
 extern tree lookup_name                                PARAMS ((tree, int));
 extern tree lookup_name_current_level          PARAMS ((tree));
 extern tree lookup_type_current_level          PARAMS ((tree));
-extern tree lookup_name_namespace_only          PARAMS ((tree));
 extern tree lookup_name_real                    (tree, int, int, int, int);
-extern void begin_only_namespace_names          PARAMS ((void));
-extern void end_only_namespace_names            PARAMS ((void));
 extern tree namespace_ancestor                 PARAMS ((tree, tree));
 extern tree unqualified_namespace_lookup       PARAMS ((tree, int, tree *));
 extern tree check_for_out_of_scope_variable     (tree);
index 6cdbb763d2f1e782b0d8efd03f27631d3e79ef47..aaf426294e1c5f7cc99a85d74ee639758668acf2 100644 (file)
@@ -207,9 +207,6 @@ tree cp_global_trees[CPTI_MAX];
 
 static GTY(()) tree global_type_node;
 
-/* Expect only namespace names now.  */
-static int only_namespace_names;
-
 /* Used only for jumps to as-yet undefined labels, since jumps to
    defined labels can have their validity checked immediately.  */
 
@@ -5931,10 +5928,7 @@ qualify_lookup (val, flags)
     return val;
   if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
     return val;
-  if ((flags & LOOKUP_PREFER_TYPES)
-      && (TREE_CODE (val) == TYPE_DECL
-         || ((flags & LOOKUP_TEMPLATES_EXPECTED)
-             && DECL_CLASS_TEMPLATE_P (val))))
+  if ((flags & LOOKUP_PREFER_TYPES) && TREE_CODE (val) == TYPE_DECL)
     return val;
   if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
     return NULL_TREE;
@@ -6105,10 +6099,6 @@ lookup_name_real (tree name,
       return NULL_TREE;
     }
 
-  /* Hack: copy flag set by parser, if set. */
-  if (only_namespace_names)
-    namespaces_only = 1;
-
   flags |= lookup_flags (prefer_type, namespaces_only);
 
   /* First, look in non-namespace scopes.  */
@@ -6183,14 +6173,6 @@ lookup_function_nonclass (name, args)
   return lookup_arg_dependent (name, lookup_name_nonclass (name), args);
 }
 
-tree
-lookup_name_namespace_only (name)
-     tree name;
-{
-  /* type-or-namespace, nonclass, namespace_only */
-  return lookup_name_real (name, 1, 1, 1, LOOKUP_COMPLAIN);
-}
-
 tree
 lookup_name (name, prefer_type)
      tree name;
@@ -6267,17 +6249,6 @@ lookup_type_current_level (name)
   return t;
 }
 
-void
-begin_only_namespace_names ()
-{
-  only_namespace_names = 1;
-}
-
-void
-end_only_namespace_names ()
-{
-  only_namespace_names = 0;
-}
 \f
 /* Push the declarations of builtin types into the namespace.
    RID_INDEX is the index of the builtin type
index 57dae655f39e518dd64d33de38bf2d173f9b03de..9f7973c04d2466e28c2d2151400f0089813ceddb 100644 (file)
@@ -1684,7 +1684,7 @@ static void cp_parser_label_declaration
 /* Utility Routines */
 
 static tree cp_parser_lookup_name
-  PARAMS ((cp_parser *, tree, bool, bool, bool));
+  PARAMS ((cp_parser *, tree, bool, bool, bool, bool));
 static tree cp_parser_lookup_name_simple
   PARAMS ((cp_parser *, tree));
 static tree cp_parser_resolve_typename_type
@@ -3558,6 +3558,15 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
                           token->value);
                  parser->scope = NULL_TREE;
                  error_p = true;
+                 /* Treat this as a successful nested-name-specifier
+                    due to:
+
+                    [basic.lookup.qual]
+
+                    If the name found is not a class-name (clause
+                    _class_) or namespace-name (_namespace.def_), the
+                    program is ill-formed.  */
+                 success = true;
                }
              cp_lexer_consume_token (parser->lexer);
            }
@@ -3663,7 +3672,8 @@ cp_parser_nested_name_specifier (cp_parser *parser,
    scope.
 
    Returns the class (TYPE_DECL) or namespace (NAMESPACE_DECL)
-   specified by the class-or-namespace-name.  */
+   specified by the class-or-namespace-name.  If neither is found the
+   ERROR_MARK_NODE is returned.  */
 
 static tree
 cp_parser_class_or_namespace_name (cp_parser *parser, 
@@ -3676,6 +3686,7 @@ cp_parser_class_or_namespace_name (cp_parser *parser,
   tree saved_qualifying_scope;
   tree saved_object_scope;
   tree scope;
+  bool only_class_p;
 
   /* If the next token is the `template' keyword, we know that we are
      looking at a class-name.  */
@@ -3693,8 +3704,11 @@ cp_parser_class_or_namespace_name (cp_parser *parser,
   saved_scope = parser->scope;
   saved_qualifying_scope = parser->qualifying_scope;
   saved_object_scope = parser->object_scope;
-  /* Try for a class-name first.  */
-  cp_parser_parse_tentatively (parser);
+  /* Try for a class-name first.  If the SAVED_SCOPE is a type, then
+     there is no need to look for a namespace-name.  */
+  only_class_p = saved_scope && TYPE_P (saved_scope);
+  if (!only_class_p)
+    cp_parser_parse_tentatively (parser);
   scope = cp_parser_class_name (parser, 
                                typename_keyword_p,
                                template_keyword_p,
@@ -3703,13 +3717,19 @@ cp_parser_class_or_namespace_name (cp_parser *parser,
                                check_dependency_p,
                                /*class_head_p=*/false);
   /* If that didn't work, try for a namespace-name.  */
-  if (!cp_parser_parse_definitely (parser))
+  if (!only_class_p && !cp_parser_parse_definitely (parser))
     {
       /* Restore the saved scope.  */
       parser->scope = saved_scope;
       parser->qualifying_scope = saved_qualifying_scope;
       parser->object_scope = saved_object_scope;
-      /* Now look for a namespace-name.  */
+      /* If we are not looking at an identifier followed by the scope
+        resolution operator, then this is not part of a
+        nested-name-specifier.  (Note that this function is only used
+        to parse the components of a nested-name-specifier.)  */
+      if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)
+         || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
+       return error_mark_node;
       scope = cp_parser_namespace_name (parser);
     }
 
@@ -8225,6 +8245,7 @@ cp_parser_template_name (parser, template_keyword_p, check_dependency_p)
   decl = cp_parser_lookup_name (parser, identifier,
                                /*check_access=*/true,
                                /*is_type=*/false,
+                               /*is_namespace=*/false,
                                check_dependency_p);
   decl = maybe_get_template_decl_from_type_decl (decl);
 
@@ -8966,6 +8987,7 @@ cp_parser_elaborated_type_specifier (parser, is_friend, is_declaration)
          decl = cp_parser_lookup_name (parser, identifier, 
                                        /*check_access=*/true,
                                        /*is_type=*/true,
+                                       /*is_namespace=*/false,
                                        /*check_dependency=*/true);
          decl = (cp_parser_maybe_treat_template_as_class 
                  (decl, /*tag_name_p=*/is_friend));
@@ -9193,8 +9215,29 @@ cp_parser_namespace_name (parser)
   if (identifier == error_mark_node)
     return error_mark_node;
 
-  /* Look up the identifier in the currently active scope.  */
-  namespace_decl = cp_parser_lookup_name_simple (parser, identifier);
+  /* Look up the identifier in the currently active scope.  Look only
+     for namespaces, due to:
+
+       [basic.lookup.udir]
+
+       When looking up a namespace-name in a using-directive or alias
+       definition, only namespace names are considered.  
+
+     And:
+
+       [basic.lookup.qual]
+
+       During the lookup of a name preceding the :: scope resolution
+       operator, object, function, and enumerator names are ignored.  
+
+     (Note that cp_parser_class_or_namespace_name only calls this
+     function if the token after the name is the scope resolution
+     operator.)  */
+  namespace_decl = cp_parser_lookup_name (parser, identifier,
+                                         /*check_access=*/true,
+                                         /*is_type=*/false,
+                                         /*is_namespace=*/true,
+                                         /*check_dependency=*/true);
   /* If it's not a namespace, issue an error.  */
   if (namespace_decl == error_mark_node
       || TREE_CODE (namespace_decl) != NAMESPACE_DECL)
@@ -11406,6 +11449,7 @@ cp_parser_class_name (cp_parser *parser,
          decl = cp_parser_lookup_name (parser, identifier, 
                                        check_access_p,
                                        type_p,
+                                       /*is_namespace=*/false,
                                        check_dependency_p);
        }
     }
@@ -13268,17 +13312,15 @@ cp_parser_label_declaration (parser)
    If IS_TYPE is TRUE, bindings that do not refer to types are
    ignored.
 
+   If IS_NAMESPACE is TRUE, bindings that do not refer to namespaces
+   are ignored.
+
    If CHECK_DEPENDENCY is TRUE, names are not looked up in dependent
    types.  */
 
 static tree
-cp_parser_lookup_name (parser, name, check_access, is_type, 
-                      check_dependency)
-     cp_parser *parser;
-     tree name;
-     bool check_access;
-     bool is_type;
-     bool check_dependency;
+cp_parser_lookup_name (cp_parser *parser, tree name, bool check_access, 
+                      bool is_type, bool is_namespace, bool check_dependency)
 {
   tree decl;
   tree object_type = parser->context->object_type;
@@ -13396,7 +13438,7 @@ cp_parser_lookup_name (parser, name, check_access, is_type,
                                     /*protect=*/0, is_type);
       /* Look it up in the enclosing context, too.  */
       decl = lookup_name_real (name, is_type, /*nonclass=*/0, 
-                              /*namespaces_only=*/0, 
+                              is_namespace,
                               /*flags=*/0);
       parser->object_scope = object_type;
       parser->qualifying_scope = NULL_TREE;
@@ -13406,7 +13448,7 @@ cp_parser_lookup_name (parser, name, check_access, is_type,
   else
     {
       decl = lookup_name_real (name, is_type, /*nonclass=*/0, 
-                              /*namespaces_only=*/0, 
+                              is_namespace,
                               /*flags=*/0);
       parser->qualifying_scope = NULL_TREE;
       parser->object_scope = NULL_TREE;
@@ -13481,7 +13523,8 @@ cp_parser_lookup_name_simple (parser, name)
 {
   return cp_parser_lookup_name (parser, name, 
                                /*check_access=*/true,
-                               /*is_type=*/false, 
+                               /*is_type=*/false,
+                               /*is_namespace=*/false,
                                /*check_dependency=*/true);
 }
 
index a2aa73db9178944f3beec3f944a6072509850b11..4af49305c02d3be33b89b708712e69fabd61e5b8 100644 (file)
@@ -1,3 +1,7 @@
+2002-12-31  Mark Mitchell  <mark@codesourcery.com>
+
+       * g++.dg/parse/namespace1.C: New test.
+       
 2003-01-01  Neil Booth  <neil@daikokuya.co.uk>
 
        * g++.dg/parse/parse4.C: New test.
diff --git a/gcc/testsuite/g++.dg/parse/namespace1.C b/gcc/testsuite/g++.dg/parse/namespace1.C
new file mode 100644 (file)
index 0000000..7740bce
--- /dev/null
@@ -0,0 +1,7 @@
+namespace foo {
+void baz(int);
+}
+
+int bar(int foo) {
+  foo::baz (3);
+}