diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-07-29 23:36:44 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-07-29 23:36:44 +0000 |
commit | 8e9e9ef5348bce1a8f0741a5684fac3de9701c28 (patch) | |
tree | da4ef264be5202213f0470cd5c9fa42dcf654fa6 /lib | |
parent | 5266d2ed446e9588eb00579ddfc5a2d327a5b3ab (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77523 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Decl.cpp | 48 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 8 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 11 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 1 |
5 files changed, 43 insertions, 27 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index a15e13568d..240922afd8 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -184,7 +184,7 @@ TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, 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 @@ SourceRange TagDecl::getSourceRange() const { } 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 @@ TagDecl* TagDecl::getDefinition(ASTContext& C) const { //===----------------------------------------------------------------------===// 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 @@ RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, 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; } diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 57897b0460..11c7e6dfc2 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -25,8 +25,9 @@ using namespace clang; 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 @@ CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, 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; diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 686b78d023..4677d17dc9 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -369,13 +369,15 @@ ClassTemplateSpecializationDecl:: 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 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, ClassTemplateSpecialization, DC, L, SpecializedTemplate, - Builder); + Builder, + PrevDecl); Context.getTypeDeclType(Result, PrevDecl); return Result; } @@ -411,7 +414,7 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L, = new (Context)ClassTemplatePartialSpecializationDecl(Context, DC, L, Params, SpecializedTemplate, - Builder); + Builder, PrevDecl); Result->setSpecializationKind(TSK_ExplicitSpecialization); Context.getTypeDeclType(Result, PrevDecl); return Result; diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 99a1a16835..65da7dc451 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -112,6 +112,8 @@ void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) { 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( diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index 4239798ac8..fd7ea421dd 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -109,6 +109,7 @@ void PCHDeclWriter::VisitTypedefDecl(TypedefDecl *D) { 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); |