summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Frontend/PCHReaderDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend/PCHReaderDecl.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Frontend/PCHReaderDecl.cpp609
1 files changed, 508 insertions, 101 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/PCHReaderDecl.cpp b/contrib/llvm/tools/clang/lib/Frontend/PCHReaderDecl.cpp
index 1ef0441..742f0e4 100644
--- a/contrib/llvm/tools/clang/lib/Frontend/PCHReaderDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Frontend/PCHReaderDecl.cpp
@@ -27,16 +27,19 @@ using namespace clang;
// Declaration deserialization
//===----------------------------------------------------------------------===//
-namespace {
+namespace clang {
class PCHDeclReader : public DeclVisitor<PCHDeclReader, void> {
PCHReader &Reader;
const PCHReader::RecordData &Record;
unsigned &Idx;
+ pch::TypeID TypeIDForTypeDecl;
public:
PCHDeclReader(PCHReader &Reader, const PCHReader::RecordData &Record,
unsigned &Idx)
- : Reader(Reader), Record(Record), Idx(Idx) { }
+ : Reader(Reader), Record(Record), Idx(Idx), TypeIDForTypeDecl(0) { }
+
+ void Visit(Decl *D);
void VisitDecl(Decl *D);
void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
@@ -46,7 +49,7 @@ namespace {
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
void VisitTypeDecl(TypeDecl *TD);
void VisitTypedefDecl(TypedefDecl *TD);
- void VisitUnresolvedUsingTypename(UnresolvedUsingTypenameDecl *D);
+ void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
void VisitTagDecl(TagDecl *TD);
void VisitEnumDecl(EnumDecl *ED);
void VisitRecordDecl(RecordDecl *RD);
@@ -58,7 +61,7 @@ namespace {
void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
void VisitValueDecl(ValueDecl *VD);
void VisitEnumConstantDecl(EnumConstantDecl *ECD);
- void VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D);
+ void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
void VisitDeclaratorDecl(DeclaratorDecl *DD);
void VisitFunctionDecl(FunctionDecl *FD);
void VisitCXXMethodDecl(CXXMethodDecl *D);
@@ -72,19 +75,21 @@ namespace {
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
void VisitTemplateDecl(TemplateDecl *D);
void VisitClassTemplateDecl(ClassTemplateDecl *D);
- void visitFunctionTemplateDecl(FunctionTemplateDecl *D);
+ void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
- void VisitUsing(UsingDecl *D);
- void VisitUsingShadow(UsingShadowDecl *D);
+ void VisitUsingDecl(UsingDecl *D);
+ void VisitUsingShadowDecl(UsingShadowDecl *D);
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
+ void VisitAccessSpecDecl(AccessSpecDecl *D);
+ void VisitFriendDecl(FriendDecl *D);
void VisitFriendTemplateDecl(FriendTemplateDecl *D);
void VisitStaticAssertDecl(StaticAssertDecl *D);
void VisitBlockDecl(BlockDecl *BD);
std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
- // FIXME: Reorder according to DeclNodes.def?
+ // FIXME: Reorder according to DeclNodes.td?
void VisitObjCMethodDecl(ObjCMethodDecl *D);
void VisitObjCContainerDecl(ObjCContainerDecl *D);
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
@@ -103,6 +108,19 @@ namespace {
};
}
+void PCHDeclReader::Visit(Decl *D) {
+ DeclVisitor<PCHDeclReader, void>::Visit(D);
+
+ 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());
+ } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ // FunctionDecl's body was written last after all other Stmts/Exprs.
+ if (Record[Idx++])
+ FD->setLazyBody(Reader.getDeclsCursor().GetCurrentBitNo());
+ }
+}
+
void PCHDeclReader::VisitDecl(Decl *D) {
D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
D->setLexicalDeclContext(
@@ -110,7 +128,7 @@ void PCHDeclReader::VisitDecl(Decl *D) {
D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
D->setInvalidDecl(Record[Idx++]);
if (Record[Idx++])
- D->addAttr(Reader.ReadAttributes());
+ D->initAttrs(Reader.ReadAttributes());
D->setImplicit(Record[Idx++]);
D->setUsed(Record[Idx++]);
D->setAccess((AccessSpecifier)Record[Idx++]);
@@ -130,21 +148,18 @@ void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {
void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {
VisitNamedDecl(TD);
- TD->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
+ // Delay type reading until after we have fully initialized the decl.
+ TypeIDForTypeDecl = Record[Idx++];
}
void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
- // Note that we cannot use VisitTypeDecl here, because we need to
- // set the underlying type of the typedef *before* we try to read
- // the type associated with the TypedefDecl.
- VisitNamedDecl(TD);
- uint64_t TypeData = Record[Idx++];
+ VisitTypeDecl(TD);
TD->setTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx));
- TD->setTypeForDecl(Reader.GetType(TypeData).getTypePtr());
}
void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
VisitTypeDecl(TD);
+ TD->IdentifierNamespace = Record[Idx++];
TD->setPreviousDeclaration(
cast_or_null<TagDecl>(Reader.GetDecl(Record[Idx++])));
TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
@@ -163,7 +178,8 @@ void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) {
ED->setPromotionType(Reader.GetType(Record[Idx++]));
ED->setNumPositiveBits(Record[Idx++]);
ED->setNumNegativeBits(Record[Idx++]);
- // FIXME: C++ InstantiatedFrom
+ ED->setInstantiationOfMemberEnum(
+ cast_or_null<EnumDecl>(Reader.GetDecl(Record[Idx++])));
}
void PCHDeclReader::VisitRecordDecl(RecordDecl *RD) {
@@ -181,7 +197,7 @@ void PCHDeclReader::VisitValueDecl(ValueDecl *VD) {
void PCHDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
VisitValueDecl(ECD);
if (Record[Idx++])
- ECD->setInitExpr(Reader.ReadDeclExpr());
+ ECD->setInitExpr(Reader.ReadExpr());
ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
}
@@ -195,9 +211,83 @@ void PCHDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
VisitDeclaratorDecl(FD);
- if (Record[Idx++])
- FD->setLazyBody(Reader.getDeclsCursor().GetCurrentBitNo());
- FD->setPreviousDeclaration(
+
+ FD->IdentifierNamespace = Record[Idx++];
+ switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
+ default: assert(false && "Unhandled TemplatedKind!");
+ break;
+ case FunctionDecl::TK_NonTemplate:
+ break;
+ case FunctionDecl::TK_FunctionTemplate:
+ FD->setDescribedFunctionTemplate(
+ cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++])));
+ break;
+ case FunctionDecl::TK_MemberSpecialization: {
+ FunctionDecl *InstFD = cast<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
+ TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
+ SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+ FD->setInstantiationOfMemberFunction(InstFD, TSK);
+ FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
+ break;
+ }
+ case FunctionDecl::TK_FunctionTemplateSpecialization: {
+ FunctionTemplateDecl *Template
+ = cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+ TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
+
+ // Template arguments.
+ llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+ Reader.ReadTemplateArgumentList(TemplArgs, Record, Idx);
+
+ // Template args as written.
+ llvm::SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
+ SourceLocation LAngleLoc, RAngleLoc;
+ if (Record[Idx++]) { // TemplateArgumentsAsWritten != 0
+ unsigned NumTemplateArgLocs = Record[Idx++];
+ TemplArgLocs.reserve(NumTemplateArgLocs);
+ for (unsigned i=0; i != NumTemplateArgLocs; ++i)
+ TemplArgLocs.push_back(Reader.ReadTemplateArgumentLoc(Record, Idx));
+
+ LAngleLoc = Reader.ReadSourceLocation(Record, Idx);
+ RAngleLoc = Reader.ReadSourceLocation(Record, Idx);
+ }
+
+ SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+
+ FD->setFunctionTemplateSpecialization(Template, TemplArgs.size(),
+ TemplArgs.data(), TSK,
+ TemplArgLocs.size(),
+ TemplArgLocs.data(),
+ LAngleLoc, RAngleLoc, POI);
+ break;
+ }
+ case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
+ // Templates.
+ UnresolvedSet<8> TemplDecls;
+ unsigned NumTemplates = Record[Idx++];
+ while (NumTemplates--)
+ TemplDecls.addDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
+
+ // Templates args.
+ TemplateArgumentListInfo TemplArgs;
+ unsigned NumArgs = Record[Idx++];
+ while (NumArgs--)
+ TemplArgs.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx));
+ TemplArgs.setLAngleLoc(Reader.ReadSourceLocation(Record, Idx));
+ TemplArgs.setRAngleLoc(Reader.ReadSourceLocation(Record, Idx));
+
+ FD->setDependentTemplateSpecialization(*Reader.getContext(),
+ TemplDecls, TemplArgs);
+ break;
+ }
+ }
+
+ // FunctionDecl's body is handled last at PCHReaderDecl::Visit,
+ // after everything else is read.
+
+ // Avoid side effects and invariant checking of FunctionDecl's
+ // setPreviousDeclaration.
+ FD->redeclarable_base::setPreviousDeclaration(
cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]);
FD->setStorageClassAsWritten((FunctionDecl::StorageClass)Record[Idx++]);
@@ -211,7 +301,6 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->setCopyAssignment(Record[Idx++]);
FD->setHasImplicitReturnZero(Record[Idx++]);
FD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
- // FIXME: C++ TemplateOrInstantiation
// Read in the parameters.
unsigned NumParams = Record[Idx++];
@@ -220,11 +309,6 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
for (unsigned I = 0; I != NumParams; ++I)
Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
FD->setParams(Params.data(), NumParams);
-
- // FIXME: order this properly w.r.t. friendness
- // FIXME: this same thing needs to happen for function templates
- if (FD->isOverloadedOperator() && !FD->getDeclContext()->isRecord())
- FD->setNonMemberOperator();
}
void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
@@ -232,7 +316,7 @@ void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
if (Record[Idx++]) {
// In practice, this won't be executed (since method definitions
// don't occur in header files).
- MD->setBody(Reader.ReadDeclStmt());
+ MD->setBody(Reader.ReadStmt());
MD->setSelfDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
MD->setCmdDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
}
@@ -374,10 +458,12 @@ void PCHDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
void PCHDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
VisitNamedDecl(D);
D->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- D->setType(Reader.GetType(Record[Idx++]));
+ D->setType(Reader.GetTypeSourceInfo(Record, Idx));
// FIXME: stable encoding
D->setPropertyAttributes(
(ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
+ D->setPropertyAttributesAsWritten(
+ (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
// FIXME: stable encoding
D->setPropertyImplementation(
(ObjCPropertyDecl::PropertyControl)Record[Idx++]);
@@ -424,7 +510,12 @@ void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {
VisitDeclaratorDecl(FD);
FD->setMutable(Record[Idx++]);
if (Record[Idx++])
- FD->setBitWidth(Reader.ReadDeclExpr());
+ FD->setBitWidth(Reader.ReadExpr());
+ if (!FD->getDeclName()) {
+ FieldDecl *Tmpl = cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+ if (Tmpl)
+ Reader.getContext()->setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
+ }
}
void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
@@ -439,7 +530,14 @@ void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
VD->setPreviousDeclaration(
cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
if (Record[Idx++])
- VD->setInit(Reader.ReadDeclExpr());
+ VD->setInit(Reader.ReadExpr());
+
+ if (Record[Idx++]) { // HasMemberSpecializationInfo.
+ VarDecl *Tmpl = cast<VarDecl>(Reader.GetDecl(Record[Idx++]));
+ TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
+ SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+ Reader.getContext()->setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI);
+ }
}
void PCHDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
@@ -450,16 +548,19 @@ void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
VisitVarDecl(PD);
PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
PD->setHasInheritedDefaultArg(Record[Idx++]);
+ if (Record[Idx++]) // hasUninstantiatedDefaultArg.
+ PD->setUninstantiatedDefaultArg(Reader.ReadExpr());
}
void PCHDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
VisitDecl(AD);
- AD->setAsmString(cast<StringLiteral>(Reader.ReadDeclExpr()));
+ AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr()));
}
void PCHDeclReader::VisitBlockDecl(BlockDecl *BD) {
VisitDecl(BD);
- BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadDeclStmt()));
+ BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt()));
+ BD->setSignatureAsWritten(Reader.GetTypeSourceInfo(Record, Idx));
unsigned NumParams = Record[Idx++];
llvm::SmallVector<ParmVarDecl *, 16> Params;
Params.reserve(NumParams);
@@ -481,13 +582,9 @@ void PCHDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
D->setNextNamespace(
cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
- // Only read one reference--the original or anonymous namespace.
bool IsOriginal = Record[Idx++];
- if (IsOriginal)
- D->setAnonymousNamespace(
- cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
- else
- D->setOriginalNamespace(
+ D->OrigOrAnonNamespace.setInt(IsOriginal);
+ D->OrigOrAnonNamespace.setPointer(
cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
}
@@ -501,7 +598,7 @@ void PCHDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
D->setAliasedNamespace(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
}
-void PCHDeclReader::VisitUsing(UsingDecl *D) {
+void PCHDeclReader::VisitUsingDecl(UsingDecl *D) {
VisitNamedDecl(D);
D->setUsingLocation(Reader.ReadSourceLocation(Record, Idx));
D->setNestedNameRange(Reader.ReadSourceRange(Record, Idx));
@@ -512,15 +609,24 @@ void PCHDeclReader::VisitUsing(UsingDecl *D) {
// would avoid existence checks.
unsigned NumShadows = Record[Idx++];
for(unsigned I = 0; I != NumShadows; ++I) {
- D->addShadowDecl(cast<UsingShadowDecl>(Reader.GetDecl(Record[Idx++])));
+ // Avoid invariant checking of UsingDecl::addShadowDecl, the decl may still
+ // be initializing.
+ D->Shadows.insert(cast<UsingShadowDecl>(Reader.GetDecl(Record[Idx++])));
}
D->setTypeName(Record[Idx++]);
+ NamedDecl *Pattern = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+ if (Pattern)
+ Reader.getContext()->setInstantiatedFromUsingDecl(D, Pattern);
}
-void PCHDeclReader::VisitUsingShadow(UsingShadowDecl *D) {
+void PCHDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {
VisitNamedDecl(D);
D->setTargetDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
D->setUsingDecl(cast<UsingDecl>(Reader.GetDecl(Record[Idx++])));
+ UsingShadowDecl *Pattern
+ = cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++]));
+ if (Pattern)
+ Reader.getContext()->setInstantiatedFromUsingShadowDecl(D, Pattern);
}
void PCHDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
@@ -534,14 +640,14 @@ void PCHDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Reader.GetDecl(Record[Idx++])));
}
-void PCHDeclReader::VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D) {
+void PCHDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
VisitValueDecl(D);
D->setTargetNestedNameRange(Reader.ReadSourceRange(Record, Idx));
D->setUsingLoc(Reader.ReadSourceLocation(Record, Idx));
D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));
}
-void PCHDeclReader::VisitUnresolvedUsingTypename(
+void PCHDeclReader::VisitUnresolvedUsingTypenameDecl(
UnresolvedUsingTypenameDecl *D) {
VisitTypeDecl(D);
D->setTargetNestedNameRange(Reader.ReadSourceRange(Record, Idx));
@@ -551,28 +657,196 @@ void PCHDeclReader::VisitUnresolvedUsingTypename(
}
void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
- // assert(false && "cannot read CXXRecordDecl");
+ ASTContext &C = *Reader.getContext();
+
+ // We need to allocate the DefinitionData struct ahead of VisitRecordDecl
+ // so that the other CXXRecordDecls can get a pointer even when the owner
+ // is still initializing.
+ bool OwnsDefinitionData = false;
+ enum DataOwnership { Data_NoDefData, Data_Owner, Data_NotOwner };
+ switch ((DataOwnership)Record[Idx++]) {
+ default:
+ assert(0 && "Out of sync with PCHDeclWriter or messed up reading");
+ case Data_NoDefData:
+ break;
+ case Data_Owner:
+ OwnsDefinitionData = true;
+ D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D);
+ break;
+ case Data_NotOwner:
+ D->DefinitionData
+ = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]))->DefinitionData;
+ break;
+ }
+
VisitRecordDecl(D);
+
+ if (OwnsDefinitionData) {
+ assert(D->DefinitionData);
+ struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
+
+ Data.UserDeclaredConstructor = Record[Idx++];
+ Data.UserDeclaredCopyConstructor = Record[Idx++];
+ Data.UserDeclaredCopyAssignment = Record[Idx++];
+ Data.UserDeclaredDestructor = Record[Idx++];
+ Data.Aggregate = Record[Idx++];
+ Data.PlainOldData = Record[Idx++];
+ Data.Empty = Record[Idx++];
+ Data.Polymorphic = Record[Idx++];
+ Data.Abstract = Record[Idx++];
+ Data.HasTrivialConstructor = Record[Idx++];
+ Data.HasTrivialCopyConstructor = Record[Idx++];
+ Data.HasTrivialCopyAssignment = Record[Idx++];
+ Data.HasTrivialDestructor = Record[Idx++];
+ Data.ComputedVisibleConversions = Record[Idx++];
+ Data.DeclaredDefaultConstructor = Record[Idx++];
+ Data.DeclaredCopyConstructor = Record[Idx++];
+ Data.DeclaredCopyAssignment = Record[Idx++];
+ Data.DeclaredDestructor = Record[Idx++];
+
+ // setBases() is unsuitable since it may try to iterate the bases of an
+ // unitialized base.
+ Data.NumBases = Record[Idx++];
+ Data.Bases = new(C) CXXBaseSpecifier [Data.NumBases];
+ for (unsigned i = 0; i != Data.NumBases; ++i)
+ Data.Bases[i] = Reader.ReadCXXBaseSpecifier(Record, Idx);
+
+ // FIXME: Make VBases lazily computed when needed to avoid storing them.
+ Data.NumVBases = Record[Idx++];
+ Data.VBases = new(C) CXXBaseSpecifier [Data.NumVBases];
+ for (unsigned i = 0; i != Data.NumVBases; ++i)
+ Data.VBases[i] = Reader.ReadCXXBaseSpecifier(Record, Idx);
+
+ Reader.ReadUnresolvedSet(Data.Conversions, Record, Idx);
+ Reader.ReadUnresolvedSet(Data.VisibleConversions, Record, Idx);
+ assert(Data.Definition && "Data.Definition should be already set!");
+ Data.FirstFriend
+ = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++]));
+ }
+
+ enum CXXRecKind {
+ CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
+ };
+ switch ((CXXRecKind)Record[Idx++]) {
+ default:
+ assert(false && "Out of sync with PCHDeclWriter::VisitCXXRecordDecl?");
+ case CXXRecNotTemplate:
+ break;
+ case CXXRecTemplate:
+ D->setDescribedClassTemplate(
+ cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++])));
+ break;
+ case CXXRecMemberSpecialization: {
+ CXXRecordDecl *RD = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]));
+ TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
+ SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+ D->setInstantiationOfMemberClass(RD, TSK);
+ D->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
+ break;
+ }
+ }
}
void PCHDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
- // assert(false && "cannot read CXXMethodDecl");
VisitFunctionDecl(D);
+ unsigned NumOverridenMethods = Record[Idx++];
+ while (NumOverridenMethods--) {
+ CXXMethodDecl *MD = cast<CXXMethodDecl>(Reader.GetDecl(Record[Idx++]));
+ // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
+ // MD may be initializing.
+ Reader.getContext()->addOverriddenMethod(D, MD);
+ }
}
void PCHDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
- // assert(false && "cannot read CXXConstructorDecl");
VisitCXXMethodDecl(D);
+
+ D->IsExplicitSpecified = Record[Idx++];
+ D->ImplicitlyDefined = Record[Idx++];
+
+ unsigned NumInitializers = Record[Idx++];
+ D->NumBaseOrMemberInitializers = NumInitializers;
+ if (NumInitializers) {
+ ASTContext &C = *Reader.getContext();
+
+ D->BaseOrMemberInitializers
+ = new (C) CXXBaseOrMemberInitializer*[NumInitializers];
+ for (unsigned i=0; i != NumInitializers; ++i) {
+ TypeSourceInfo *BaseClassInfo = 0;
+ bool IsBaseVirtual = false;
+ FieldDecl *Member = 0;
+
+ bool IsBaseInitializer = Record[Idx++];
+ if (IsBaseInitializer) {
+ BaseClassInfo = Reader.GetTypeSourceInfo(Record, Idx);
+ IsBaseVirtual = Record[Idx++];
+ } else {
+ Member = cast<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+ }
+ SourceLocation MemberLoc = Reader.ReadSourceLocation(Record, Idx);
+ Expr *Init = Reader.ReadExpr();
+ FieldDecl *AnonUnionMember
+ = cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+ SourceLocation LParenLoc = Reader.ReadSourceLocation(Record, Idx);
+ SourceLocation RParenLoc = Reader.ReadSourceLocation(Record, Idx);
+ bool IsWritten = Record[Idx++];
+ unsigned SourceOrderOrNumArrayIndices;
+ llvm::SmallVector<VarDecl *, 8> Indices;
+ if (IsWritten) {
+ SourceOrderOrNumArrayIndices = Record[Idx++];
+ } else {
+ SourceOrderOrNumArrayIndices = Record[Idx++];
+ Indices.reserve(SourceOrderOrNumArrayIndices);
+ for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
+ Indices.push_back(cast<VarDecl>(Reader.GetDecl(Record[Idx++])));
+ }
+
+ CXXBaseOrMemberInitializer *BOMInit;
+ if (IsBaseInitializer) {
+ BOMInit = new (C) CXXBaseOrMemberInitializer(C, BaseClassInfo,
+ IsBaseVirtual, LParenLoc,
+ Init, RParenLoc);
+ } else if (IsWritten) {
+ BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc,
+ LParenLoc, Init, RParenLoc);
+ } else {
+ BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc,
+ LParenLoc, Init, RParenLoc,
+ Indices.data(),
+ Indices.size());
+ }
+
+ BOMInit->setAnonUnionMember(AnonUnionMember);
+ D->BaseOrMemberInitializers[i] = BOMInit;
+ }
+ }
}
void PCHDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
- // assert(false && "cannot read CXXDestructorDecl");
VisitCXXMethodDecl(D);
+
+ D->ImplicitlyDefined = Record[Idx++];
+ D->OperatorDelete = cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
}
void PCHDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
- // assert(false && "cannot read CXXConversionDecl");
VisitCXXMethodDecl(D);
+ D->IsExplicitSpecified = Record[Idx++];
+}
+
+void PCHDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {
+ VisitDecl(D);
+ D->setColonLoc(Reader.ReadSourceLocation(Record, Idx));
+}
+
+void PCHDeclReader::VisitFriendDecl(FriendDecl *D) {
+ VisitDecl(D);
+ if (Record[Idx++])
+ D->Friend = Reader.GetTypeSourceInfo(Record, Idx);
+ else
+ D->Friend = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+ D->NextFriend = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++]));
+ D->FriendLoc = Reader.ReadSourceLocation(Record, Idx);
}
void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
@@ -580,37 +854,171 @@ void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
}
void PCHDeclReader::VisitTemplateDecl(TemplateDecl *D) {
- assert(false && "cannot read TemplateDecl");
+ VisitNamedDecl(D);
+
+ NamedDecl *TemplatedDecl
+ = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+ TemplateParameterList* TemplateParams
+ = Reader.ReadTemplateParameterList(Record, Idx);
+ D->init(TemplatedDecl, TemplateParams);
}
void PCHDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
- assert(false && "cannot read ClassTemplateDecl");
+ VisitTemplateDecl(D);
+
+ D->IdentifierNamespace = Record[Idx++];
+ ClassTemplateDecl *PrevDecl =
+ cast_or_null<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+ D->setPreviousDeclaration(PrevDecl);
+ if (PrevDecl == 0) {
+ // This ClassTemplateDecl owns a CommonPtr; read it.
+
+ // FoldingSets are filled in VisitClassTemplateSpecializationDecl.
+ unsigned size = Record[Idx++];
+ while (size--)
+ cast<ClassTemplateSpecializationDecl>(Reader.GetDecl(Record[Idx++]));
+
+ size = Record[Idx++];
+ while (size--)
+ cast<ClassTemplatePartialSpecializationDecl>(
+ Reader.GetDecl(Record[Idx++]));
+
+ // InjectedClassNameType is computed.
+
+ if (ClassTemplateDecl *CTD
+ = cast_or_null<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
+ D->setInstantiatedFromMemberTemplate(CTD);
+ if (Record[Idx++])
+ D->setMemberSpecialization();
+ }
+ }
}
void PCHDeclReader::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D) {
- assert(false && "cannot read ClassTemplateSpecializationDecl");
+ VisitCXXRecordDecl(D);
+
+ if (Decl *InstD = Reader.GetDecl(Record[Idx++])) {
+ if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(InstD)) {
+ D->setInstantiationOf(CTD);
+ } else {
+ llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+ Reader.ReadTemplateArgumentList(TemplArgs, Record, Idx);
+ D->setInstantiationOf(cast<ClassTemplatePartialSpecializationDecl>(InstD),
+ TemplArgs.data(), TemplArgs.size());
+ }
+ }
+
+ // Explicit info.
+ if (TypeSourceInfo *TyInfo = Reader.GetTypeSourceInfo(Record, Idx)) {
+ D->setTypeAsWritten(TyInfo);
+ D->setExternLoc(Reader.ReadSourceLocation(Record, Idx));
+ D->setTemplateKeywordLoc(Reader.ReadSourceLocation(Record, Idx));
+ }
+
+ llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+ Reader.ReadTemplateArgumentList(TemplArgs, Record, Idx);
+ D->initTemplateArgs(TemplArgs.data(), TemplArgs.size());
+ SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+ if (POI.isValid())
+ D->setPointOfInstantiation(POI);
+ D->setSpecializationKind((TemplateSpecializationKind)Record[Idx++]);
+
+ if (Record[Idx++]) { // IsKeptInFoldingSet.
+ ClassTemplateDecl *CanonPattern
+ = cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+ if (ClassTemplatePartialSpecializationDecl *Partial
+ = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
+ CanonPattern->getPartialSpecializations().InsertNode(Partial);
+ } else {
+ CanonPattern->getSpecializations().InsertNode(D);
+ }
+ }
}
void PCHDeclReader::VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D) {
- assert(false && "cannot read ClassTemplatePartialSpecializationDecl");
+ VisitClassTemplateSpecializationDecl(D);
+
+ D->initTemplateParameters(Reader.ReadTemplateParameterList(Record, Idx));
+
+ TemplateArgumentListInfo ArgInfos;
+ unsigned NumArgs = Record[Idx++];
+ while (NumArgs--)
+ ArgInfos.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx));
+ D->initTemplateArgsAsWritten(ArgInfos);
+
+ D->setSequenceNumber(Record[Idx++]);
+
+ // These are read/set from/to the first declaration.
+ if (D->getPreviousDeclaration() == 0) {
+ D->setInstantiatedFromMember(
+ cast_or_null<ClassTemplatePartialSpecializationDecl>(
+ Reader.GetDecl(Record[Idx++])));
+ if (Record[Idx++])
+ D->setMemberSpecialization();
+ }
}
-void PCHDeclReader::visitFunctionTemplateDecl(FunctionTemplateDecl *D) {
- assert(false && "cannot read FunctionTemplateDecl");
+void PCHDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+ VisitTemplateDecl(D);
+
+ D->IdentifierNamespace = Record[Idx++];
+ FunctionTemplateDecl *PrevDecl =
+ cast_or_null<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+ D->setPreviousDeclaration(PrevDecl);
+ if (PrevDecl == 0) {
+ // This FunctionTemplateDecl owns a CommonPtr; read it.
+
+ // Read the function specialization declarations.
+ // FunctionTemplateDecl's FunctionTemplateSpecializationInfos are filled
+ // through the specialized FunctionDecl's setFunctionTemplateSpecialization.
+ unsigned NumSpecs = Record[Idx++];
+ while (NumSpecs--)
+ Reader.GetDecl(Record[Idx++]);
+
+ if (FunctionTemplateDecl *CTD
+ = cast_or_null<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
+ D->setInstantiatedFromMemberTemplate(CTD);
+ if (Record[Idx++])
+ D->setMemberSpecialization();
+ }
+ }
}
void PCHDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
- assert(false && "cannot read TemplateTypeParmDecl");
+ VisitTypeDecl(D);
+
+ D->setDeclaredWithTypename(Record[Idx++]);
+ D->setParameterPack(Record[Idx++]);
+
+ bool Inherited = Record[Idx++];
+ TypeSourceInfo *DefArg = Reader.GetTypeSourceInfo(Record, Idx);
+ D->setDefaultArgument(DefArg, Inherited);
}
void PCHDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
- assert(false && "cannot read NonTypeTemplateParmDecl");
+ VisitVarDecl(D);
+ // TemplateParmPosition.
+ D->setDepth(Record[Idx++]);
+ D->setPosition(Record[Idx++]);
+ // Rest of NonTypeTemplateParmDecl.
+ if (Record[Idx++]) {
+ Expr *DefArg = Reader.ReadExpr();
+ bool Inherited = Record[Idx++];
+ D->setDefaultArgument(DefArg, Inherited);
+ }
}
void PCHDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
- assert(false && "cannot read TemplateTemplateParmDecl");
+ VisitTemplateDecl(D);
+ // TemplateParmPosition.
+ D->setDepth(Record[Idx++]);
+ D->setPosition(Record[Idx++]);
+ // Rest of TemplateTemplateParmDecl.
+ TemplateArgumentLoc Arg = Reader.ReadTemplateArgumentLoc(Record, Idx);
+ bool IsInherited = Record[Idx++];
+ D->setDefaultArgument(Arg, IsInherited);
}
void PCHDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
@@ -641,24 +1049,24 @@ Attr *PCHReader::ReadAttributes() {
(void)RecCode;
#define SIMPLE_ATTR(Name) \
- case Attr::Name: \
+ case attr::Name: \
New = ::new (*Context) Name##Attr(); \
break
#define STRING_ATTR(Name) \
- case Attr::Name: \
+ case attr::Name: \
New = ::new (*Context) Name##Attr(*Context, ReadString(Record, Idx)); \
break
#define UNSIGNED_ATTR(Name) \
- case Attr::Name: \
+ case attr::Name: \
New = ::new (*Context) Name##Attr(Record[Idx++]); \
break
Attr *Attrs = 0;
while (Idx < Record.size()) {
Attr *New = 0;
- Attr::Kind Kind = (Attr::Kind)Record[Idx++];
+ attr::Kind Kind = (attr::Kind)Record[Idx++];
bool IsInherited = Record[Idx++];
switch (Kind) {
@@ -674,14 +1082,14 @@ Attr *PCHReader::ReadAttributes() {
STRING_ATTR(AsmLabel);
SIMPLE_ATTR(BaseCheck);
- case Attr::Blocks:
+ case attr::Blocks:
New = ::new (*Context) BlocksAttr(
(BlocksAttr::BlocksAttrTypes)Record[Idx++]);
break;
SIMPLE_ATTR(CDecl);
- case Attr::Cleanup:
+ case attr::Cleanup:
New = ::new (*Context) CleanupAttr(
cast<FunctionDecl>(GetDecl(Record[Idx++])));
break;
@@ -695,7 +1103,7 @@ Attr *PCHReader::ReadAttributes() {
SIMPLE_ATTR(FastCall);
SIMPLE_ATTR(Final);
- case Attr::Format: {
+ case attr::Format: {
std::string Type = ReadString(Record, Idx);
unsigned FormatIdx = Record[Idx++];
unsigned FirstArg = Record[Idx++];
@@ -703,13 +1111,13 @@ Attr *PCHReader::ReadAttributes() {
break;
}
- case Attr::FormatArg: {
+ case attr::FormatArg: {
unsigned FormatIdx = Record[Idx++];
New = ::new (*Context) FormatArgAttr(FormatIdx);
break;
}
- case Attr::Sentinel: {
+ case attr::Sentinel: {
int sentinel = Record[Idx++];
int nullPos = Record[Idx++];
New = ::new (*Context) SentinelAttr(sentinel, nullPos);
@@ -719,15 +1127,15 @@ Attr *PCHReader::ReadAttributes() {
SIMPLE_ATTR(GNUInline);
SIMPLE_ATTR(Hiding);
- case Attr::IBActionKind:
+ case attr::IBAction:
New = ::new (*Context) IBActionAttr();
break;
- case Attr::IBOutletKind:
+ case attr::IBOutlet:
New = ::new (*Context) IBOutletAttr();
break;
- case Attr::IBOutletCollectionKind: {
+ case attr::IBOutletCollection: {
ObjCInterfaceDecl *D =
cast_or_null<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
New = ::new (*Context) IBOutletCollectionAttr(D);
@@ -740,7 +1148,7 @@ Attr *PCHReader::ReadAttributes() {
SIMPLE_ATTR(NoReturn);
SIMPLE_ATTR(NoThrow);
- case Attr::NonNull: {
+ case attr::NonNull: {
unsigned Size = Record[Idx++];
llvm::SmallVector<unsigned, 16> ArgNums;
ArgNums.insert(ArgNums.end(), &Record[Idx], &Record[Idx] + Size);
@@ -749,7 +1157,7 @@ Attr *PCHReader::ReadAttributes() {
break;
}
- case Attr::ReqdWorkGroupSize: {
+ case attr::ReqdWorkGroupSize: {
unsigned X = Record[Idx++];
unsigned Y = Record[Idx++];
unsigned Z = Record[Idx++];
@@ -777,7 +1185,7 @@ Attr *PCHReader::ReadAttributes() {
SIMPLE_ATTR(Unused);
SIMPLE_ATTR(Used);
- case Attr::Visibility:
+ case attr::Visibility:
New = ::new (*Context) VisibilityAttr(
(VisibilityAttr::VisibilityTypes)Record[Idx++]);
break;
@@ -848,6 +1256,8 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
// after reading this declaration.
SavedStreamPosition SavedPosition(DeclsCursor);
+ ReadingKindTracker ReadingKind(Read_Decl, *this);
+
// Note that we are loading a declaration record.
LoadingTypeOrDecl Loading(*this);
@@ -872,11 +1282,10 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
D = TypedefDecl::Create(*Context, 0, SourceLocation(), 0, 0);
break;
case pch::DECL_ENUM:
- D = EnumDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(), 0);
+ D = EnumDecl::Create(*Context, Decl::EmptyShell());
break;
case pch::DECL_RECORD:
- D = RecordDecl::Create(*Context, TTK_Struct, 0, SourceLocation(),
- 0, SourceLocation(), 0);
+ D = RecordDecl::Create(*Context, Decl::EmptyShell());
break;
case pch::DECL_ENUM_CONSTANT:
D = EnumConstantDecl::Create(*Context, 0, SourceLocation(), 0, QualType(),
@@ -923,8 +1332,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
DeclarationName());
break;
case pch::DECL_CXX_RECORD:
- D = CXXRecordDecl::Create(*Context, TTK_Struct, 0,
- SourceLocation(), 0, SourceLocation(), 0);
+ D = CXXRecordDecl::Create(*Context, Decl::EmptyShell());
break;
case pch::DECL_CXX_METHOD:
D = CXXMethodDecl::Create(*Context, 0, SourceLocation(), DeclarationName(),
@@ -939,36 +1347,40 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
case pch::DECL_CXX_CONVERSION:
D = CXXConversionDecl::Create(*Context, Decl::EmptyShell());
break;
+ case pch::DECL_ACCESS_SPEC:
+ D = AccessSpecDecl::Create(*Context, AS_none, 0, SourceLocation(),
+ SourceLocation());
+ break;
case pch::DECL_FRIEND:
- assert(false && "cannot read FriendDecl");
+ D = FriendDecl::Create(*Context, Decl::EmptyShell());
break;
case pch::DECL_FRIEND_TEMPLATE:
assert(false && "cannot read FriendTemplateDecl");
break;
- case pch::DECL_TEMPLATE:
- // FIXME: Should TemplateDecl be ABSTRACT_DECL???
- assert(false && "TemplateDecl should be abstract!");
- break;
case pch::DECL_CLASS_TEMPLATE:
- assert(false && "cannot read ClassTemplateDecl");
+ D = ClassTemplateDecl::Create(*Context, 0, SourceLocation(),
+ DeclarationName(), 0, 0, 0);
break;
case pch::DECL_CLASS_TEMPLATE_SPECIALIZATION:
- assert(false && "cannot read ClasstemplateSpecializationDecl");
+ D = ClassTemplateSpecializationDecl::Create(*Context, Decl::EmptyShell());
break;
case pch::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION:
- assert(false && "cannot read ClassTemplatePartialSpecializationDecl");
+ D = ClassTemplatePartialSpecializationDecl::Create(*Context,
+ Decl::EmptyShell());
break;
case pch::DECL_FUNCTION_TEMPLATE:
- assert(false && "cannot read FunctionTemplateDecl");
+ D = FunctionTemplateDecl::Create(*Context, 0, SourceLocation(),
+ DeclarationName(), 0, 0);
break;
case pch::DECL_TEMPLATE_TYPE_PARM:
- assert(false && "cannot read TemplateTypeParmDecl");
+ D = TemplateTypeParmDecl::Create(*Context, Decl::EmptyShell());
break;
case pch::DECL_NON_TYPE_TEMPLATE_PARM:
- assert(false && "cannot read NonTypeTemplateParmDecl");
+ D = NonTypeTemplateParmDecl::Create(*Context, 0, SourceLocation(), 0,0,0,
+ QualType(),0);
break;
case pch::DECL_TEMPLATE_TEMPLATE_PARM:
- assert(false && "cannot read TemplateTemplateParmDecl");
+ D = TemplateTemplateParmDecl::Create(*Context, 0, SourceLocation(),0,0,0,0);
break;
case pch::DECL_STATIC_ASSERT:
assert(false && "cannot read StaticAssertDecl");
@@ -1013,7 +1425,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
break;
case pch::DECL_OBJC_PROPERTY:
D = ObjCPropertyDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(),
- QualType());
+ 0);
break;
case pch::DECL_OBJC_PROPERTY_IMPL:
D = ObjCPropertyImplDecl::Create(*Context, 0, SourceLocation(),
@@ -1062,16 +1474,11 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
assert(Idx == Record.size());
// If we have deserialized a declaration that has a definition the
- // AST consumer might need to know about, notify the consumer
- // about that definition now or queue it for later.
- if (isConsumerInterestedIn(D)) {
- if (Consumer) {
- DeclGroupRef DG(D);
- Consumer->HandleTopLevelDecl(DG);
- } else {
- InterestingDecls.push_back(D);
- }
- }
+ // AST consumer might need to know about, queue it.
+ // We don't pass it to the consumer immediately because we may be in recursive
+ // loading, and some declarations may still be initializing.
+ if (isConsumerInterestedIn(D))
+ InterestingDecls.push_back(D);
return D;
}
OpenPOWER on IntegriCloud