summaryrefslogtreecommitdiff
path: root/lib/AST/ExternalASTMerger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/ExternalASTMerger.cpp')
-rw-r--r--lib/AST/ExternalASTMerger.cpp45
1 files changed, 38 insertions, 7 deletions
diff --git a/lib/AST/ExternalASTMerger.cpp b/lib/AST/ExternalASTMerger.cpp
index 6b75c51c6420..ae28c588ca31 100644
--- a/lib/AST/ExternalASTMerger.cpp
+++ b/lib/AST/ExternalASTMerger.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExternalASTMerger.h"
using namespace clang;
@@ -153,7 +154,7 @@ public:
ToContainer->setMustBuildLookupTable();
assert(Parent.CanComplete(ToContainer));
}
- return ASTImporter::Imported(From, To);
+ return To;
}
ASTImporter &GetReverse() { return Reverse; }
};
@@ -228,7 +229,7 @@ void ExternalASTMerger::CompleteType(TagDecl *Tag) {
SourceTag->getASTContext().getExternalSource()->CompleteType(SourceTag);
if (!SourceTag->getDefinition())
return false;
- Forward.Imported(SourceTag, Tag);
+ Forward.MapImported(SourceTag, Tag);
Forward.ImportDefinition(SourceTag);
Tag->setCompleteDefinition(SourceTag->isCompleteDefinition());
return true;
@@ -247,7 +248,7 @@ void ExternalASTMerger::CompleteType(ObjCInterfaceDecl *Interface) {
SourceInterface);
if (!SourceInterface->getDefinition())
return false;
- Forward.Imported(SourceInterface, Interface);
+ Forward.MapImported(SourceInterface, Interface);
Forward.ImportDefinition(SourceInterface);
return true;
});
@@ -303,7 +304,7 @@ void ExternalASTMerger::ForceRecordOrigin(const DeclContext *ToDC,
void ExternalASTMerger::RecordOriginImpl(const DeclContext *ToDC, DCOrigin Origin,
ASTImporter &Importer) {
Origins[ToDC] = Origin;
- Importer.ASTImporter::Imported(cast<Decl>(Origin.DC), const_cast<Decl*>(cast<Decl>(ToDC)));
+ Importer.ASTImporter::MapImported(cast<Decl>(Origin.DC), const_cast<Decl*>(cast<Decl>(ToDC)));
}
ExternalASTMerger::ExternalASTMerger(const ImporterTarget &Target,
@@ -351,6 +352,27 @@ void ExternalASTMerger::RemoveSources(llvm::ArrayRef<ImporterSource> Sources) {
}
}
+template <typename DeclTy>
+static bool importSpecializations(DeclTy *D, ASTImporter *Importer) {
+ for (auto *Spec : D->specializations())
+ if (!Importer->Import(Spec))
+ return true;
+ return false;
+}
+
+/// Imports specializations from template declarations that can be specialized.
+static bool importSpecializationsIfNeeded(Decl *D, ASTImporter *Importer) {
+ if (!isa<TemplateDecl>(D))
+ return false;
+ if (auto *FunctionTD = dyn_cast<FunctionTemplateDecl>(D))
+ return importSpecializations(FunctionTD, Importer);
+ else if (auto *ClassTD = dyn_cast<ClassTemplateDecl>(D))
+ return importSpecializations(ClassTD, Importer);
+ else if (auto *VarTD = dyn_cast<VarTemplateDecl>(D))
+ return importSpecializations(VarTD, Importer);
+ return false;
+}
+
bool ExternalASTMerger::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
llvm::SmallVector<NamedDecl *, 1> Decls;
@@ -376,9 +398,18 @@ bool ExternalASTMerger::FindExternalVisibleDeclsByName(const DeclContext *DC,
Decls.reserve(Candidates.size());
for (const Candidate &C : Candidates) {
- NamedDecl *d = cast<NamedDecl>(C.second->Import(C.first.get()));
- assert(d);
- Decls.push_back(d);
+ Decl *LookupRes = C.first.get();
+ ASTImporter *Importer = C.second;
+ NamedDecl *ND = cast_or_null<NamedDecl>(Importer->Import(LookupRes));
+ assert(ND);
+ // If we don't import specialization, they are not available via lookup
+ // because the lookup result is imported TemplateDecl and it does not
+ // reference its specializations until they are imported explicitly.
+ bool IsSpecImportFailed =
+ importSpecializationsIfNeeded(LookupRes, Importer);
+ assert(!IsSpecImportFailed);
+ (void)IsSpecImportFailed;
+ Decls.push_back(ND);
}
SetExternalVisibleDeclsForName(DC, Name, Decls);
return true;