OSDN Git Service

* cp-tree.h (TREE_NONLOCAL_FLAG): Remove.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Apr 1999 13:16:50 +0000 (13:16 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Apr 1999 13:16:50 +0000 (13:16 +0000)
(storetags): Declare.
* class.c (finish_struct): Don't use TREE_NONLOCAL_FLAG.
(pushclass): Likewise.  Use storetags to install tag declarations,
not pushtag.
(invalidate_class_lookup_cache): Don't use TREE_NONLOCAL_FLAG.
* decl.c (storetags): Make it global.
(push_class_binding): Set INHERITED_VALUE_BINDING_P for an
implicit typename declaration.
(pushtag): Tidy.  Don't use TREE_NONLOCAL_FLAG.
* method.c (hack_identifier): Likewise.
* search.c (lookup_member): Likewise.

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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/method.c
gcc/cp/search.c
gcc/testsuite/g++.old-deja/g++.pt/typename20.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/typename21.C [new file with mode: 0644]

index 8f61598..b7b3a85 100644 (file)
@@ -1,5 +1,18 @@
 1999-04-16  Mark Mitchell  <mark@codesourcery.com>
 
+       * cp-tree.h (TREE_NONLOCAL_FLAG): Remove.
+       (storetags): Declare.
+       * class.c (finish_struct): Don't use TREE_NONLOCAL_FLAG.
+       (pushclass): Likewise.  Use storetags to install tag declarations,
+       not pushtag.
+       (invalidate_class_lookup_cache): Don't use TREE_NONLOCAL_FLAG.
+       * decl.c (storetags): Make it global.
+       (push_class_binding): Set INHERITED_VALUE_BINDING_P for an
+       implicit typename declaration.
+       (pushtag): Tidy.  Don't use TREE_NONLOCAL_FLAG.
+       * method.c (hack_identifier): Likewise.
+       * search.c (lookup_member): Likewise.
+       
        * decl.c (warn_about_implicit_typename_lookup): New function.
        (lookup_name_real): Use it.  Rework handling of implicit typename
        extension.
index 4d970f5..cc23b29 100644 (file)
@@ -4185,10 +4185,6 @@ finish_struct (t, attributes, warn_anon)
      as necessary.  */
   unreverse_member_declarations (t);
 
-  /* Mark all the tags in the class as class-local.  */
-  for (x = CLASSTYPE_TAGS (t); x; x = TREE_CHAIN (x))
-    TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0;
-
   cplus_decl_attributes (t, attributes, NULL_TREE);
 
   if (processing_template_decl)
@@ -4511,17 +4507,7 @@ pushclass (type, modify)
          unuse_fields (type);
        }
 
-      for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags))
-       {
-         tree tag_type = TREE_VALUE (tags);
-
-         TREE_NONLOCAL_FLAG (tag_type) = 1;
-         if (! TREE_PURPOSE (tags))
-           continue;
-         if (! (IS_AGGR_TYPE_CODE (TREE_CODE (tag_type))
-                && CLASSTYPE_IS_TEMPLATE (tag_type)))
-           pushtag (TREE_PURPOSE (tags), tag_type, 0);
-       }
+      storetags (CLASSTYPE_TAGS (type));
     }
 }
 
@@ -4541,11 +4527,6 @@ invalidate_class_lookup_cache ()
      them.  This is it!  */
   for (t = previous_class_values; t; t = TREE_CHAIN (t))
     IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
-  while (tags)
-    {
-      TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
-      tags = TREE_CHAIN (tags);
-    }
   
   previous_class_type = NULL_TREE;
 }
@@ -4556,16 +4537,6 @@ invalidate_class_lookup_cache ()
 void
 popclass ()
 {
-  /* Just remove from this class what didn't make
-        it into IDENTIFIER_CLASS_VALUE.  */
-  tree tags = CLASSTYPE_TAGS (current_class_type);
-
-  while (tags)
-    {
-      TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
-      tags = TREE_CHAIN (tags);
-    }
-
   poplevel (1, 0, 0);
   /* Since poplevel_class does the popping of class decls nowadays,
      this really only frees the obstack used for these decls.  */
index dcfdeb3..282d1fa 100644 (file)
@@ -23,8 +23,7 @@ Boston, MA 02111-1307, USA.  */
 #define _CP_TREE_H
 
 /* Usage of TREE_LANG_FLAG_?:
-   0: TREE_NONLOCAL_FLAG (in TREE_LIST or _TYPE).
-      BINFO_MARKED (BINFO nodes).
+   0: BINFO_MARKED (BINFO nodes).
       COMPOUND_STMT_NO_SCOPE (in COMPOUND_STMT).
       NEW_EXPR_USE_GLOBAL (in NEW_EXPR).
       DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR).
@@ -803,9 +802,6 @@ struct lang_type
   (TYPE_NEEDS_DESTRUCTOR (NODE) \
    || (TYPE_LANG_SPECIFIC (NODE) && TYPE_VEC_DELETE_TAKES_SIZE (NODE)))
 
-/* Nonzero for TREE_LIST or _TYPE node means that this node is class-local.  */
-#define TREE_NONLOCAL_FLAG(NODE) (TREE_LANG_FLAG_0 (NODE))
-
 /* Nonzero means that this _CLASSTYPE node defines ways of converting
    itself to other types.  */
 #define TYPE_HAS_CONVERSION(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_type_conversion)
@@ -2885,6 +2881,7 @@ extern int push_class_binding                   PROTO((tree, tree));
 extern tree check_default_argument              PROTO((tree, tree));
 extern tree push_overloaded_decl               PROTO((tree, int));
 extern void clear_identifier_class_values       PROTO((void));
+extern void storetags                           PROTO((tree));
 
 /* in decl2.c */
 extern int check_java_method                   PROTO((tree));
index fe30586..d1f722c 100644 (file)
@@ -148,7 +148,6 @@ static struct binding_level *make_binding_level PROTO((void));
 static void declare_namespace_level PROTO((void));
 static void signal_catch PROTO((int)) ATTRIBUTE_NORETURN;
 static void storedecls PROTO((tree));
-static void storetags PROTO((tree));
 static void require_complete_types_for_parms PROTO((tree));
 static void push_overloaded_decl_1 PROTO((tree));
 static int ambi_op_p PROTO((tree));
@@ -1231,19 +1230,29 @@ push_class_binding (id, decl)
   binding = IDENTIFIER_BINDING (id);
   if (BINDING_VALUE (binding) == decl && TREE_CODE (decl) != TREE_LIST)
     {
-      if (TREE_CODE (decl) == OVERLOAD)
-       context = DECL_REAL_CONTEXT (OVL_CURRENT (decl));
+      /* Any implicit typename must be from a base-class.  The
+        context for an implicit typename declaration is always
+        the derived class in which the lookup was done, so the checks
+        based on the context of DECL below will not trigger.  */
+      if (TREE_CODE (decl) == TYPE_DECL 
+         && IMPLICIT_TYPENAME_P (TREE_TYPE (decl)))
+       INHERITED_VALUE_BINDING_P (binding) = 1;
       else
        {
-         my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd',
-                             0);
-         context = DECL_REAL_CONTEXT (decl);
-       }
+         if (TREE_CODE (decl) == OVERLOAD)
+           context = DECL_REAL_CONTEXT (OVL_CURRENT (decl));
+         else
+           {
+             my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd',
+                                 0);
+             context = DECL_REAL_CONTEXT (decl);
+           }
 
-      if (is_properly_derived_from (current_class_type, context))
-       INHERITED_VALUE_BINDING_P (binding) = 1;
-      else
-       INHERITED_VALUE_BINDING_P (binding) = 0;
+         if (is_properly_derived_from (current_class_type, context))
+           INHERITED_VALUE_BINDING_P (binding) = 1;
+         else
+           INHERITED_VALUE_BINDING_P (binding) = 0;
+       }
     }
   else if (BINDING_VALUE (binding) == decl)
     /* We only encounter a TREE_LIST when push_class_decls detects an
@@ -2616,7 +2625,6 @@ maybe_process_template_type_declaration (type, globalize, b)
                 binding level, but is instead the pseudo-global level.  */
              b->level_chain->tags = 
                saveable_tree_cons (name, type, b->level_chain->tags);
-             TREE_NONLOCAL_FLAG (type) = 1;
              if (TYPE_SIZE (current_class_type) == NULL_TREE)
                CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags;
            }
@@ -2637,8 +2645,6 @@ pushtag (name, type, globalize)
      int globalize;
 {
   register struct binding_level *b;
-  tree context = 0;
-  tree c_decl = 0;
 
   b = current_binding_level;
   while (b->tag_transparent
@@ -2652,32 +2658,34 @@ pushtag (name, type, globalize)
 
   if (name)
     {
-      context = type ? TYPE_CONTEXT (type) : NULL_TREE;
-      if (! context)
-       {
-         tree cs = current_scope ();
-
-         if (! globalize)
-           context = cs;
-         else if (cs != NULL_TREE 
-                  && TREE_CODE_CLASS (TREE_CODE (cs)) == 't')
-           /* When declaring a friend class of a local class, we want
-              to inject the newly named class into the scope
-              containing the local class, not the namespace scope.  */
-           context = hack_decl_function_context (get_type_decl (cs));
-       }
-      if (context)
-       c_decl = TREE_CODE (context) == FUNCTION_DECL
-         ? context : TYPE_MAIN_DECL (context);
-
-      if (!context)
-       context = current_namespace;
-
       /* Do C++ gratuitous typedefing.  */
       if (IDENTIFIER_TYPE_VALUE (name) != type)
         {
           register tree d = NULL_TREE;
          int newdecl = 0, in_class = 0;
+         tree context;
+         tree c_decl = NULL_TREE;
+
+         context = type ? TYPE_CONTEXT (type) : NULL_TREE;
+         if (! context)
+           {
+             tree cs = current_scope ();
+
+             if (! globalize)
+               context = cs;
+             else if (cs != NULL_TREE 
+                      && TREE_CODE_CLASS (TREE_CODE (cs)) == 't')
+               /* When declaring a friend class of a local class, we want
+                  to inject the newly named class into the scope
+                  containing the local class, not the namespace scope.  */
+               context = hack_decl_function_context (get_type_decl (cs));
+           }
+         if (context)
+           c_decl = TREE_CODE (context) == FUNCTION_DECL
+             ? context : TYPE_MAIN_DECL (context);
+
+         if (!context)
+           context = current_namespace;
 
          if ((b->pseudo_global && b->level_chain->parm_flag == 2)
              || b->parm_flag == 2)
@@ -2732,7 +2740,6 @@ pushtag (name, type, globalize)
         }
       if (b->parm_flag == 2)
        {
-         TREE_NONLOCAL_FLAG (type) = 1;
          if (TYPE_SIZE (current_class_type) == NULL_TREE)
            CLASSTYPE_TAGS (current_class_type) = b->tags;
        }
@@ -4931,7 +4938,7 @@ storedecls (decls)
 
 /* Similarly, store the list of tags of the current level.  */
 
-static void
+void
 storetags (tags)
      tree tags;
 {
index edb690f..39f7f04 100644 (file)
@@ -2007,7 +2007,8 @@ hack_identifier (value, name)
            return error_mark_node;
        }
     }
-  else if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value))
+  else if (TREE_CODE (value) == TREE_LIST 
+          && TREE_TYPE (value) == error_mark_node)
     {
       error ("request for member `%s' is ambiguous in multiple inheritance lattice",
             IDENTIFIER_POINTER (name));
index c061d72..74b9c2d 100644 (file)
@@ -1406,9 +1406,9 @@ lookup_member (xbasetype, name, protect, want_type)
     {
       if (lfi.ambiguous)
        {
-         /* This flag tells hack_identifier that the lookup is
-            ambiguous.  */
-         TREE_NONLOCAL_FLAG (lfi.ambiguous) = 1;
+         /* An ERROR_MARK for the TREE_TYPE tells hack_identifier
+            that the lookup is ambiguous.  */
+         TREE_TYPE (lfi.ambiguous) = error_mark_node;
          return scratch_tree_cons (error_mark_node,
                                    lfi.ambiguous,
                                    NULL_TREE);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename20.C b/gcc/testsuite/g++.old-deja/g++.pt/typename20.C
new file mode 100644 (file)
index 0000000..0f6c4fc
--- /dev/null
@@ -0,0 +1,16 @@
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+// Special g++ Options:
+
+template <class T>
+struct B {
+  typedef int I;
+};
+
+template <class T, class X = int>
+struct S : public B <T> {
+  struct I {
+  };
+
+  void f(int i = true) {}
+};
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename21.C b/gcc/testsuite/g++.old-deja/g++.pt/typename21.C
new file mode 100644 (file)
index 0000000..2dc52aa
--- /dev/null
@@ -0,0 +1,25 @@
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+// Special g++ Options:
+
+template <class T>
+struct S1 {
+  typedef T X;
+};
+
+template <class T>
+struct B {
+  typedef T I;
+};
+
+template <class T>
+struct S2 : public B<T> {
+  struct I {};
+
+  typedef typename S1<I>::X IX;
+
+  void f(IX);
+};
+
+template <class T>
+void S2<T>::f(IX) {}