OSDN Git Service

* decl.c (duplicate_decls): Don't try to unify an implicit typedef
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Apr 2002 14:16:26 +0000 (14:16 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Apr 2002 14:16:26 +0000 (14:16 +0000)
with an explicit one.
(lookup_tag): Extract the tag of an explicit typedef.

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

gcc/cp/ChangeLog
gcc/cp/decl.c

index a2d8b8f..6f355c3 100644 (file)
@@ -1,3 +1,9 @@
+2002-04-11  Richard Sandiford  <rsandifo@redhat.com>
+
+       * decl.c (duplicate_decls): Don't try to unify an implicit typedef
+       with an explicit one.
+       (lookup_tag): Extract the tag of an explicit typedef.
+
 2002-04-10  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/5507
index dc9d373..f55e1d4 100644 (file)
@@ -3426,6 +3426,18 @@ duplicate_decls (newdecl, olddecl)
        }
     }
 
+  /* Do not merge an implicit typedef with an explicit one.  In:
+
+       class A;
+       ...
+       typedef class A A __attribute__ ((foo));
+
+     the attribute should apply only to the typedef.  */
+  if (TREE_CODE (olddecl) == TYPE_DECL
+      && (DECL_IMPLICIT_TYPEDEF_P (olddecl)
+         || DECL_IMPLICIT_TYPEDEF_P (newdecl)))
+    return 0;
+
   /* If new decl is `static' and an `extern' was seen previously,
      warn about it.  */
   warn_extern_redeclared_static (newdecl, olddecl);
@@ -5336,10 +5348,23 @@ lookup_tag (form, name, binding_level, thislevel_only)
            else
              old = BINDING_TYPE (old);
 
-           /* If it has an original type, it is a typedef, and we
-              should not return it.  */
+           /* If the declaration has an original type, it must a
+              typedef.  When it is an explicit typedef of the form:
+
+                  typedef struct A A;
+
+              the original type will be the tag that we want.
+              We should not return any other kind of typedef.
+
+              Detect the valid case by checking that the original
+              type has the same name and context as the typedef.  */
            if (old && DECL_ORIGINAL_TYPE (TYPE_NAME (old)))
-             old = NULL_TREE;
+             {
+               old = DECL_ORIGINAL_TYPE (TYPE_NAME (old));
+               if (TYPE_IDENTIFIER (old) != name
+                   || context_for_name_lookup (TYPE_NAME (old)) != tail)
+                 old = NULL_TREE;
+             }
            if (old && TREE_CODE (old) != form
                && (form == ENUMERAL_TYPE || TREE_CODE (old) == ENUMERAL_TYPE))
              {