[cfe-commits] r77523 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclCXX.h include/clang/AST/DeclTemplate.h lib/AST/Decl.cpp lib/AST/DeclCXX.cpp lib/AST/DeclTemplate.cpp lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriterDecl.cpp

Douglas Gregor dgregor at apple.com
Wed Jul 29 16:36:44 PDT 2009


Author: dgregor
Date: Wed Jul 29 18:36:44 2009
New Revision: 77523

URL: http://llvm.org/viewvc/llvm-project?rev=77523&view=rev
Log:
Make tag declarations redeclarable. This change has three purposes:

  1) Allow the Index library (and any other interested client) to walk
  the set of declarations for a given tag (enum, union, class,
  whatever). At the moment, this information is not readily available.

  2) Reduce our dependence on TagDecl::TypeForDecl being mapped down
  to a TagType (for which getDecl() will return the tag definition, if
  one exists). This property won't exist for class template partial
  specializations.

  3) Make the canonical declaration of a TagDecl actually canonical,
  e.g., so that it does not change when the tag is defined.


Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriterDecl.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Jul 29 18:36:44 2009
@@ -1178,7 +1178,8 @@
 class TypedefDecl;
   
 /// TagDecl - Represents the declaration of a struct/union/class/enum.
-class TagDecl : public TypeDecl, public DeclContext {
+class TagDecl 
+  : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
 public:
   enum TagKind {
     TK_struct,
@@ -1205,15 +1206,28 @@
 
 protected:
   TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
-          IdentifierInfo *Id, SourceLocation TKL = SourceLocation())
+          IdentifierInfo *Id, TagDecl *PrevDecl,
+          SourceLocation TKL = SourceLocation())
     : TypeDecl(DK, DC, L, Id), DeclContext(DK), TypedefForAnonDecl(0),
       TagKeywordLoc(TKL) {
     assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
     TagDeclKind = TK;
     IsDefinition = false;
+    setPreviousDeclaration(PrevDecl);
   }
+    
+  typedef Redeclarable<TagDecl> redeclarable_base;
+  virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+    
 public:
-  
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  redecl_iterator redecls_begin() const {
+    return redeclarable_base::redecls_begin();
+  } 
+  redecl_iterator redecls_end() const {
+    return redeclarable_base::redecls_end();
+  }
+    
   SourceLocation getRBraceLoc() const { return RBraceLoc; }
   void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
 
@@ -1307,8 +1321,8 @@
   EnumDecl *InstantiatedFrom;
 
   EnumDecl(DeclContext *DC, SourceLocation L,
-           IdentifierInfo *Id, SourceLocation TKL)
-    : TagDecl(Enum, TK_enum, DC, L, Id, TKL), InstantiatedFrom(0) {
+           IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL)
+    : TagDecl(Enum, TK_enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
       IntegerType = QualType();
     }
 public:
@@ -1380,7 +1394,8 @@
 
 protected:
   RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
-             SourceLocation L, IdentifierInfo *Id, SourceLocation TKL);
+             SourceLocation L, IdentifierInfo *Id, 
+             RecordDecl *PrevDecl, SourceLocation TKL);
   virtual ~RecordDecl();
 
 public:

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Wed Jul 29 18:36:44 2009
@@ -376,6 +376,7 @@
 protected:
   CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
                 SourceLocation L, IdentifierInfo *Id,
+                CXXRecordDecl *PrevDecl,
                 SourceLocation TKL = SourceLocation());
 
   ~CXXRecordDecl();

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Wed Jul 29 18:36:44 2009
@@ -883,7 +883,8 @@
   ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
                                   DeclContext *DC, SourceLocation L,
                                   ClassTemplateDecl *SpecializedTemplate,
-                                  TemplateArgumentListBuilder &Builder);
+                                  TemplateArgumentListBuilder &Builder,
+                                  ClassTemplateSpecializationDecl *PrevDecl);
                                   
 public:
   static ClassTemplateSpecializationDecl *
@@ -954,9 +955,12 @@
                                          DeclContext *DC, SourceLocation L,
                                          TemplateParameterList *Params,
                                          ClassTemplateDecl *SpecializedTemplate,
-                                         TemplateArgumentListBuilder &Builder)
-    : ClassTemplateSpecializationDecl(Context, ClassTemplatePartialSpecialization,
-                                      DC, L, SpecializedTemplate, Builder),
+                                         TemplateArgumentListBuilder &Builder,
+                               ClassTemplatePartialSpecializationDecl *PrevDecl)
+    : ClassTemplateSpecializationDecl(Context, 
+                                      ClassTemplatePartialSpecialization,
+                                      DC, L, SpecializedTemplate, Builder,
+                                      PrevDecl),
       TemplateParams(Params) { }
 
 public:

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

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed Jul 29 18:36:44 2009
@@ -184,7 +184,7 @@
 EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
                            IdentifierInfo *Id, SourceLocation TKL,
                            EnumDecl *PrevDecl) {
-  EnumDecl *Enum = new (C) EnumDecl(DC, L, Id, TKL);
+  EnumDecl *Enum = new (C) EnumDecl(DC, L, Id, PrevDecl, TKL);
   C.getTypeDeclType(Enum, PrevDecl);
   return Enum;
 }
@@ -662,33 +662,38 @@
 }
 
 TagDecl* TagDecl::getCanonicalDecl() {
-  Type *T = getTypeForDecl();
-  if (T == 0)
-    T = getASTContext().getTagDeclType(this).getTypePtr();
-
-  return cast<TagDecl>(cast<TagType>(T->getCanonicalTypeInternal())->getDecl());
+  return getFirstDeclaration();
 }
 
 void TagDecl::startDefinition() {
-  TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>());
-  TagT->decl.setPointer(this);
-  TagT->getAs<TagType>()->decl.setInt(1);
+  if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
+    TagT->decl.setPointer(this);
+    TagT->decl.setInt(1);
+  }
 }
 
 void TagDecl::completeDefinition() {
-  assert((!TypeForDecl || 
-          TypeForDecl->getAs<TagType>()->decl.getPointer() == this) &&
-         "Attempt to redefine a tag definition?");
   IsDefinition = true;
-  TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>());
-  TagT->decl.setPointer(this);
-  TagT->decl.setInt(0);
+  if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
+    assert(TagT->decl.getPointer() == this &&
+           "Attempt to redefine a tag definition?");
+    TagT->decl.setInt(0);
+  }
 }
 
 TagDecl* TagDecl::getDefinition(ASTContext& C) const {
-  QualType T = C.getTypeDeclType(const_cast<TagDecl*>(this));
-  TagDecl* D = cast<TagDecl>(T->getAs<TagType>()->getDecl());
-  return D->isDefinition() ? D : 0;
+  if (isDefinition())
+    return const_cast<TagDecl *>(this);
+  
+  if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>()))
+    return TagT->getDecl()->isDefinition()? TagT->getDecl() : 0;
+  
+  for (redecl_iterator R = redecls_begin(), REnd = redecls_end(); 
+       R != REnd; ++R)
+    if (R->isDefinition())
+      return *R;
+  
+  return 0;
 }
 
 //===----------------------------------------------------------------------===//
@@ -696,8 +701,9 @@
 //===----------------------------------------------------------------------===//
 
 RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
-                       IdentifierInfo *Id, SourceLocation TKL)
-  : TagDecl(DK, TK, DC, L, Id, TKL) {
+                       IdentifierInfo *Id, RecordDecl *PrevDecl,
+                       SourceLocation TKL)
+  : TagDecl(DK, TK, DC, L, Id, PrevDecl, TKL) {
   HasFlexibleArrayMember = false;
   AnonymousStructOrUnion = false;
   HasObjectMember = false;
@@ -708,7 +714,7 @@
                                SourceLocation L, IdentifierInfo *Id,
                                SourceLocation TKL, RecordDecl* PrevDecl) {
   
-  RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id, TKL);
+  RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id, PrevDecl, TKL);
   C.getTypeDeclType(R, PrevDecl);
   return R;
 }

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

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Jul 29 18:36:44 2009
@@ -25,8 +25,9 @@
 
 CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
                              SourceLocation L, IdentifierInfo *Id,
+                             CXXRecordDecl *PrevDecl,
                              SourceLocation TKL) 
-  : RecordDecl(K, TK, DC, L, Id, TKL),
+  : RecordDecl(K, TK, DC, L, Id, PrevDecl, TKL),
     UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
     UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false),
     Aggregate(true), PlainOldData(true), Polymorphic(false), Abstract(false),
@@ -41,7 +42,10 @@
                                      SourceLocation TKL,
                                      CXXRecordDecl* PrevDecl,
                                      bool DelayTypeCreation) {
-  CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id, TKL);
+  CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id, 
+                                           PrevDecl, TKL);
+  
+  // FIXME: DelayTypeCreation seems like such a hack
   if (!DelayTypeCreation)
     C.getTypeDeclType(R, PrevDecl);  
   return R;

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

==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Wed Jul 29 18:36:44 2009
@@ -369,13 +369,15 @@
 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
                                 DeclContext *DC, SourceLocation L,
                                 ClassTemplateDecl *SpecializedTemplate,
-                                TemplateArgumentListBuilder &Builder)
+                                TemplateArgumentListBuilder &Builder,
+                                ClassTemplateSpecializationDecl *PrevDecl)
   : CXXRecordDecl(DK, 
                   SpecializedTemplate->getTemplatedDecl()->getTagKind(), 
                   DC, L,
                   // FIXME: Should we use DeclarationName for the name of
                   // class template specializations?
-                  SpecializedTemplate->getIdentifier()),
+                  SpecializedTemplate->getIdentifier(),
+                  PrevDecl),
     SpecializedTemplate(SpecializedTemplate),
     TemplateArgs(Context, Builder, /*TakeArgs=*/true),
     SpecializationKind(TSK_Undeclared) {
@@ -392,7 +394,8 @@
                                                    ClassTemplateSpecialization,
                                                    DC, L, 
                                                    SpecializedTemplate,
-                                                   Builder);
+                                                   Builder,
+                                                   PrevDecl);
   Context.getTypeDeclType(Result, PrevDecl);
   return Result;
 }
@@ -411,7 +414,7 @@
     = new (Context)ClassTemplatePartialSpecializationDecl(Context, 
                                                           DC, L, Params,
                                                           SpecializedTemplate,
-                                                          Builder);
+                                                          Builder, PrevDecl);
   Result->setSpecializationKind(TSK_ExplicitSpecialization);
   Context.getTypeDeclType(Result, PrevDecl);
   return Result;

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=77523&r1=77522&r2=77523&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Wed Jul 29 18:36:44 2009
@@ -112,6 +112,8 @@
 
 void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
   VisitTypeDecl(TD);
+  TD->setPreviousDeclaration(
+                        cast_or_null<TagDecl>(Reader.GetDecl(Record[Idx++])));
   TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
   TD->setDefinition(Record[Idx++]);
   TD->setTypedefForAnonDecl(

Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=77523&r1=77522&r2=77523&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Wed Jul 29 18:36:44 2009
@@ -109,6 +109,7 @@
 
 void PCHDeclWriter::VisitTagDecl(TagDecl *D) {
   VisitTypeDecl(D);
+  Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
   Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
   Record.push_back(D->isDefinition());
   Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record);





More information about the cfe-commits mailing list