aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-07-29 23:36:44 +0000
committerDouglas Gregor <dgregor@apple.com>2009-07-29 23:36:44 +0000
commit8e9e9ef5348bce1a8f0741a5684fac3de9701c28 (patch)
treeda4ef264be5202213f0470cd5c9fa42dcf654fa6 /lib/AST/Decl.cpp
parent5266d2ed446e9588eb00579ddfc5a2d327a5b3ab (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/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp48
1 files changed, 27 insertions, 21 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;
}