summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-01-17 19:21:53 +0000
committerDouglas Gregor <dgregor@apple.com>2012-01-17 19:21:53 +0000
commitf3bccd77fcbe2c06bc0dd8893d222a19cecb9620 (patch)
tree632ca07a4836e5d5ac093a2ceb9b6348a7811edc
parent2ed67186168b7ad136d4cabf32e23895e16ec2a2 (diff)
downloadbcm5719-llvm-f3bccd77fcbe2c06bc0dd8893d222a19cecb9620.tar.gz
bcm5719-llvm-f3bccd77fcbe2c06bc0dd8893d222a19cecb9620.zip
Rework the way in which we (de-)serialize the declarations
corresponding to TagType and ObjCInterfaceType. Previously, we would serialize the definition (if available) or the canonical declaration (if no definition was available). However, this can end up forcing the deserialization of the definition even through we might not want to yet. Instead, always serialize the canonical declaration reference in the TagType/ObjCInterfaceType entry, and as part of loading a pending definition, update the "decl" pointer within the type node to point at the definition. This is more robust in hard-to-isolate cases where the *Type gets built and filled in before we see the definition. llvm-svn: 148323
-rw-r--r--clang/include/clang/AST/Decl.h1
-rw-r--r--clang/include/clang/AST/Type.h3
-rw-r--r--clang/lib/Serialization/ASTReader.cpp30
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp4
4 files changed, 28 insertions, 10 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 4016c2085f3..01177fa2773 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -2225,6 +2225,7 @@ class TypeDecl : public NamedDecl {
friend class TagDecl;
friend class TemplateTypeParmDecl;
friend class TagType;
+ friend class ASTReader;
protected:
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 436c02cd919..ed2e83763fe 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -3070,6 +3070,8 @@ class TagType : public Type {
/// TagDecl that declares the entity.
TagDecl * decl;
+ friend class ASTReader;
+
protected:
TagType(TypeClass TC, const TagDecl *D, QualType can);
@@ -4160,6 +4162,7 @@ class ObjCInterfaceType : public ObjCObjectType {
: ObjCObjectType(Nonce_ObjCInterface),
Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
friend class ASTContext; // ASTContext creates these.
+ friend class ASTReader;
friend class ObjCInterfaceDecl;
public:
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 57cd0212b3c..245e8b1b183 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -3901,8 +3901,9 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
}
unsigned Idx = 0;
bool IsDependent = Record[Idx++];
- QualType T
- = Context.getRecordType(ReadDeclAs<RecordDecl>(*Loc.F, Record, Idx));
+ RecordDecl *RD = ReadDeclAs<RecordDecl>(*Loc.F, Record, Idx);
+ RD = cast_or_null<RecordDecl>(RD->getCanonicalDecl());
+ QualType T = Context.getRecordType(RD);
const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
return T;
}
@@ -3966,7 +3967,7 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
unsigned Idx = 0;
ObjCInterfaceDecl *ItfD
= ReadDeclAs<ObjCInterfaceDecl>(*Loc.F, Record, Idx);
- return Context.getObjCInterfaceType(ItfD);
+ return Context.getObjCInterfaceType(ItfD->getCanonicalDecl());
}
case TYPE_OBJC_OBJECT: {
@@ -6124,6 +6125,7 @@ void ASTReader::finishPendingActions() {
// Load pending declaration chains.
for (unsigned I = 0; I != PendingDeclChains.size(); ++I) {
loadPendingDeclChain(PendingDeclChains[I]);
+ PendingDeclChainsKnown.erase(PendingDeclChains[I]);
}
PendingDeclChains.clear();
@@ -6143,16 +6145,28 @@ void ASTReader::finishPendingActions() {
for (llvm::SmallPtrSet<Decl *, 4>::iterator D = PendingDefinitions.begin(),
DEnd = PendingDefinitions.end();
D != DEnd; ++D) {
- if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(*D)) {
- for (CXXRecordDecl::redecl_iterator R = RD->redecls_begin(),
- REnd = RD->redecls_end();
- R != REnd; ++R)
- cast<CXXRecordDecl>(*R)->DefinitionData = RD->DefinitionData;
+ if (TagDecl *TD = dyn_cast<TagDecl>(*D)) {
+ if (const TagType *TagT = dyn_cast<TagType>(TD->TypeForDecl)) {
+ // Make sure that the TagType points at the definition.
+ const_cast<TagType*>(TagT)->decl = TD;
+ }
+ if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(*D)) {
+ for (CXXRecordDecl::redecl_iterator R = RD->redecls_begin(),
+ REnd = RD->redecls_end();
+ R != REnd; ++R)
+ cast<CXXRecordDecl>(*R)->DefinitionData = RD->DefinitionData;
+
+ }
+
continue;
}
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(*D)) {
+ // Make sure that the ObjCInterfaceType points at the definition.
+ const_cast<ObjCInterfaceType *>(cast<ObjCInterfaceType>(ID->TypeForDecl))
+ ->Decl = ID;
+
for (ObjCInterfaceDecl::redecl_iterator R = ID->redecls_begin(),
REnd = ID->redecls_end();
R != REnd; ++R)
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 7a09b32ac10..c5f9b2dc88a 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -239,7 +239,7 @@ void ASTTypeWriter::VisitAutoType(const AutoType *T) {
void ASTTypeWriter::VisitTagType(const TagType *T) {
Record.push_back(T->isDependentType());
- Writer.AddDeclRef(T->getDecl(), Record);
+ Writer.AddDeclRef(T->getDecl()->getCanonicalDecl(), Record);
assert(!T->isBeingDefined() &&
"Cannot serialize in the middle of a type definition");
}
@@ -369,7 +369,7 @@ void ASTTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
}
void ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
- Writer.AddDeclRef(T->getDecl(), Record);
+ Writer.AddDeclRef(T->getDecl()->getCanonicalDecl(), Record);
Code = TYPE_OBJC_INTERFACE;
}
OpenPOWER on IntegriCloud