[cfe-commits] r92283 - in /cfe/trunk: include/clang/AST/Decl.h lib/AST/Decl.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaCXX/typedef-redecl.cpp

John McCall rjmccall at apple.com
Tue Dec 29 16:31:22 PST 2009


Author: rjmccall
Date: Tue Dec 29 18:31:22 2009
New Revision: 92283

URL: http://llvm.org/viewvc/llvm-project?rev=92283&view=rev
Log:
Typedefs can be redeclared.  That seems like something we should record in
the AST lest we run into some crazy canonicalization bug like PR5874.


Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/SemaCXX/typedef-redecl.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=92283&r1=92282&r2=92283&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Tue Dec 29 18:31:22 2009
@@ -1449,7 +1449,7 @@
 };
 
 
-class TypedefDecl : public TypeDecl {
+class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
   /// UnderlyingType - This is the type the typedef is set to.
   TypeSourceInfo *TInfo;
 
@@ -1457,7 +1457,7 @@
               IdentifierInfo *Id, TypeSourceInfo *TInfo)
     : TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
 
-  virtual ~TypedefDecl() {}
+  virtual ~TypedefDecl();
 public:
 
   static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
@@ -1468,6 +1468,14 @@
     return TInfo;
   }
 
+  /// Retrieves the canonical declaration of this typedef.
+  TypedefDecl *getCanonicalDecl() {
+    return getFirstDeclaration();
+  }
+  const TypedefDecl *getCanonicalDecl() const {
+    return getFirstDeclaration();
+  }
+
   QualType getUnderlyingType() const {
     return TInfo->getType();
   }

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=92283&r1=92282&r2=92283&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Tue Dec 29 18:31:22 2009
@@ -212,6 +212,9 @@
   return new (C) TypedefDecl(DC, L, Id, TInfo);
 }
 
+// Anchor TypedefDecl's vtable here.
+TypedefDecl::~TypedefDecl() {}
+
 EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
                            IdentifierInfo *Id, SourceLocation TKL,
                            EnumDecl *PrevDecl) {

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=92283&r1=92282&r2=92283&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Dec 29 18:31:22 2009
@@ -696,9 +696,8 @@
   }
 
   // Verify the old decl was also a type.
-  TypeDecl *Old = 0;
-  if (!OldDecls.isSingleResult() ||
-      !(Old = dyn_cast<TypeDecl>(OldDecls.getFoundDecl()))) {
+  TypeDecl *Old = OldDecls.getAsSingle<TypeDecl>();
+  if (!Old) {
     Diag(New->getLocation(), diag::err_redefinition_different_kind)
       << New->getDeclName();
 
@@ -733,6 +732,13 @@
     return New->setInvalidDecl();
   }
 
+  // The types match.  Link up the redeclaration chain if the old
+  // declaration was a typedef.
+  // FIXME: this is a potential source of wierdness if the type
+  // spellings don't match exactly.
+  if (isa<TypedefDecl>(Old))
+    New->setPreviousDeclaration(cast<TypedefDecl>(Old));
+
   if (getLangOptions().Microsoft)
     return;
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=92283&r1=92282&r2=92283&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Dec 29 18:31:22 2009
@@ -145,6 +145,11 @@
   if (Invalid)
     Typedef->setInvalidDecl();
 
+  if (TypedefDecl *Prev = D->getPreviousDeclaration()) {
+    NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(Prev, TemplateArgs);
+    Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev));
+  }
+
   Owner->addDecl(Typedef);
 
   return Typedef;

Modified: cfe/trunk/test/SemaCXX/typedef-redecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/typedef-redecl.cpp?rev=92283&r1=92282&r2=92283&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/typedef-redecl.cpp (original)
+++ cfe/trunk/test/SemaCXX/typedef-redecl.cpp Tue Dec 29 18:31:22 2009
@@ -29,3 +29,11 @@
 
 struct s { };
 
+// PR5874
+namespace test1 {
+  typedef int foo;
+  namespace a { using test1::foo; };
+  typedef int foo;
+  using namespace a; 
+  foo x;
+}





More information about the cfe-commits mailing list