diff options
-rw-r--r-- | include/clang/Sema/ExternalSemaSource.h | 12 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 8 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 20 |
4 files changed, 35 insertions, 9 deletions
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index 00494641ba..7b83625fa3 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -27,6 +27,7 @@ struct ObjCMethodList; class Scope; class Sema; class TypedefNameDecl; +class ValueDecl; class VarDecl; /// \brief A simple structure that captures a vtable use for the purposes of @@ -162,6 +163,17 @@ public: /// source should take care not to introduce the same vtables repeatedly. virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {} + /// \brief Read the set of pending instantiations known to the external + /// Sema source. + /// + /// The external source should append its own pending instantiations to the + /// given vector. Note that this routine may be invoked multiple times; the + /// external source should take care not to introduce the same instantiations + /// repeatedly. + virtual void ReadPendingInstantiations( + SmallVectorImpl<std::pair<ValueDecl *, + SourceLocation> > &Pending) {} + // isa/cast/dyn_cast support static bool classof(const ExternalASTSource *Source) { return Source->SemaSource; diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 7af22548db..bd2115039f 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1406,6 +1406,10 @@ public: virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables); + virtual void ReadPendingInstantiations( + SmallVectorImpl<std::pair<ValueDecl *, + SourceLocation> > &Pending); + /// \brief Load a selector from disk, registering its ID if it exists. void LoadSelector(Selector Sel); diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 41818d329c..872bb87457 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3229,6 +3229,14 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, /// \brief Performs template instantiation for all implicit template /// instantiations we have seen until this point. void Sema::PerformPendingInstantiations(bool LocalOnly) { + // Load pending instantiations from the external source. + if (!LocalOnly && ExternalSource) { + SmallVector<std::pair<ValueDecl *, SourceLocation>, 4> Pending; + ExternalSource->ReadPendingInstantiations(Pending); + PendingInstantiations.insert(PendingInstantiations.begin(), + Pending.begin(), Pending.end()); + } + while (!PendingLocalImplicitInstantiations.empty() || (!LocalOnly && !PendingInstantiations.empty())) { PendingImplicitInstantiation Inst; diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index eced16a6ca..acd31c9a64 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -4405,15 +4405,6 @@ void ASTReader::InitializeSema(Sema &S) { SemaObj->StdBadAlloc = SemaDeclRefs[1]; } - // If there were any pending implicit instantiations, deserialize them - // and add them to Sema's queue of such instantiations. - for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) { - ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++])); - SourceLocation Loc - = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]); - SemaObj->PendingInstantiations.push_back(std::make_pair(D, Loc)); - } - if (!FPPragmaOptions.empty()) { assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS"); SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0]; @@ -4660,6 +4651,17 @@ void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) { VTableUses.clear(); } +void ASTReader::ReadPendingInstantiations( + SmallVectorImpl<std::pair<ValueDecl *, SourceLocation> > &Pending) { + for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) { + ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++])); + SourceLocation Loc + = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]); + Pending.push_back(std::make_pair(D, Loc)); + } + PendingInstantiations.clear(); +} + void ASTReader::LoadSelector(Selector Sel) { // It would be complicated to avoid reading the methods anyway. So don't. ReadMethodPool(Sel); |