summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-08-09 21:55:28 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-08-09 21:55:28 +0000
commitab6a0883149c96d96b51381d59c9a09a47a76e1e (patch)
tree425b7e604d03124a416c8e25c72e47f59003ddc3 /clang/lib/Frontend
parentcdb847ba162f7827694c6ce0743986fd7391c523 (diff)
downloadbcm5719-llvm-ab6a0883149c96d96b51381d59c9a09a47a76e1e.tar.gz
bcm5719-llvm-ab6a0883149c96d96b51381d59c9a09a47a76e1e.zip
- Make ObjCInterfaceDecl redeclarable, and create separate decl nodes for forward declarations and the definition.
- Eagerly create ObjCInterfaceTypes for declarations. - The two above changes lead to a 0.5% increase in memory use and no speed regression when parsing Cocoa.h. On the other hand, now chained PCH works when there's a forward declaration in one PCH and the interface definition in another. - Add HandleInterestingDecl to ASTConsumer. PCHReader passes the "interesting" decls it finds to this function instead of HandleTopLevelDecl. The default implementation forwards to HandleTopLevelDecl, but ASTUnit's handler for example ignores them. This fixes a potential crash when lazy loading of PCH data would cause ASTUnit's "top level" declaration collection to change while being iterated. llvm-svn: 110610
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp3
-rw-r--r--clang/lib/Frontend/PCHReader.cpp4
-rw-r--r--clang/lib/Frontend/PCHReaderDecl.cpp22
-rw-r--r--clang/lib/Frontend/PCHWriter.cpp4
-rw-r--r--clang/lib/Frontend/PCHWriterDecl.cpp5
5 files changed, 24 insertions, 14 deletions
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index b287522806e..cd78abdaeb8 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -320,6 +320,9 @@ public:
Unit.addTopLevelDecl(D);
}
}
+
+ // We're not interested in "interesting" decls.
+ void HandleInterestingDecl(DeclGroupRef) {}
};
class TopLevelDeclTrackerAction : public ASTFrontendAction {
diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp
index 1bfc138d4fb..68acbb2faf9 100644
--- a/clang/lib/Frontend/PCHReader.cpp
+++ b/clang/lib/Frontend/PCHReader.cpp
@@ -2262,7 +2262,7 @@ QualType PCHReader::ReadTypeRecord(unsigned Index) {
SavedStreamPosition SavedPosition(DeclsCursor);
ReadingKindTracker ReadingKind(Read_Type, *this);
-
+
// Note that we are loading a type record.
Deserializing AType(this);
@@ -3027,7 +3027,7 @@ void PCHReader::PassInterestingDeclsToConsumer() {
while (!InterestingDecls.empty()) {
DeclGroupRef DG(InterestingDecls.front());
InterestingDecls.pop_front();
- Consumer->HandleTopLevelDecl(DG);
+ Consumer->HandleInterestingDecl(DG);
}
}
diff --git a/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp
index 7aab7b7557c..2930ca73b9a 100644
--- a/clang/lib/Frontend/PCHReaderDecl.cpp
+++ b/clang/lib/Frontend/PCHReaderDecl.cpp
@@ -34,7 +34,7 @@ namespace clang {
const pch::DeclID ThisDeclID;
const PCHReader::RecordData &Record;
unsigned &Idx;
- pch::TypeID TypeIDForTypeDecl;
+ pch::TypeID TypeIDForDecl;
uint64_t GetCurrentCursorOffset();
@@ -43,7 +43,7 @@ namespace clang {
pch::DeclID thisDeclID, const PCHReader::RecordData &Record,
unsigned &Idx)
: Reader(Reader), Cursor(Cursor), ThisDeclID(thisDeclID), Record(Record),
- Idx(Idx), TypeIDForTypeDecl(0) { }
+ Idx(Idx), TypeIDForDecl(0) { }
void Visit(Decl *D);
@@ -132,9 +132,11 @@ uint64_t PCHDeclReader::GetCurrentCursorOffset() {
void PCHDeclReader::Visit(Decl *D) {
DeclVisitor<PCHDeclReader, void>::Visit(D);
+ // if we have a fully initialized Decl, we can safely read its type now.
if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
- // if we have a fully initialized TypeDecl, we can safely read its type now.
- TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtr());
+ TD->setTypeForDecl(Reader.GetType(TypeIDForDecl).getTypePtr());
+ } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+ ID->setTypeForDecl(Reader.GetType(TypeIDForDecl).getTypePtr());
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// FunctionDecl's body was written last after all other Stmts/Exprs.
if (Record[Idx++])
@@ -170,7 +172,7 @@ void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {
void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {
VisitNamedDecl(TD);
// Delay type reading until after we have fully initialized the decl.
- TypeIDForTypeDecl = Record[Idx++];
+ TypeIDForDecl = Record[Idx++];
}
void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
@@ -367,7 +369,11 @@ void PCHDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
VisitObjCContainerDecl(ID);
- ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
+ ID->setForwardDecl(Record[Idx++]);
+ ID->setImplicitInterfaceDecl(Record[Idx++]);
+ VisitRedeclarable(ID);
+ // Must delay type reading until the redecl chain is complete.
+ TypeIDForDecl = Record[Idx++];
ID->setSuperClass(cast_or_null<ObjCInterfaceDecl>
(Reader.GetDecl(Record[Idx++])));
unsigned NumProtocols = Record[Idx++];
@@ -388,8 +394,6 @@ void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
ID->setCategoryList(
cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
- ID->setForwardDecl(Record[Idx++]);
- ID->setImplicitInterfaceDecl(Record[Idx++]);
ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
ID->setSuperClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
ID->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
@@ -1459,7 +1463,7 @@ Decl *PCHReader::ReadDeclRecord(unsigned Index, pch::DeclID ID) {
Selector(), QualType(), 0, 0);
break;
case pch::DECL_OBJC_INTERFACE:
- D = ObjCInterfaceDecl::Create(*Context, 0, SourceLocation(), 0);
+ D = ObjCInterfaceDecl::Create(*Context, Decl::EmptyShell());
break;
case pch::DECL_OBJC_IVAR:
D = ObjCIvarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp
index 0eed4ccd71e..990641294af 100644
--- a/clang/lib/Frontend/PCHWriter.cpp
+++ b/clang/lib/Frontend/PCHWriter.cpp
@@ -305,7 +305,9 @@ void PCHTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
}
void PCHTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
- Writer.AddDeclRef(T->getDecl(), Record);
+ // The stored declaration must be the first, but getDecl() returns the
+ // definition.
+ Writer.AddDeclRef(T->getDecl()->getFirstDeclaration(), Record);
Code = pch::TYPE_OBJC_INTERFACE;
}
diff --git a/clang/lib/Frontend/PCHWriterDecl.cpp b/clang/lib/Frontend/PCHWriterDecl.cpp
index a509ed1dce9..9917ad64194 100644
--- a/clang/lib/Frontend/PCHWriterDecl.cpp
+++ b/clang/lib/Frontend/PCHWriterDecl.cpp
@@ -340,6 +340,9 @@ void PCHDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
void PCHDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
VisitObjCContainerDecl(D);
+ Record.push_back(D->isForwardDecl());
+ Record.push_back(D->isImplicitInterfaceDecl());
+ VisitRedeclarable(D);
Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
Writer.AddDeclRef(D->getSuperClass(), Record);
Record.push_back(D->protocol_size());
@@ -356,8 +359,6 @@ void PCHDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
IEnd = D->ivar_end(); I != IEnd; ++I)
Writer.AddDeclRef(*I, Record);
Writer.AddDeclRef(D->getCategoryList(), Record);
- Record.push_back(D->isForwardDecl());
- Record.push_back(D->isImplicitInterfaceDecl());
Writer.AddSourceLocation(D->getClassLoc(), Record);
Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
Writer.AddSourceLocation(D->getLocEnd(), Record);
OpenPOWER on IntegriCloud