[ASTImporter] Import described template (if any) of function.
authorBalazs Keri <1.int32@gmail.com>
Tue, 17 Jul 2018 09:52:41 +0000 (09:52 +0000)
committerBalazs Keri <1.int32@gmail.com>
Tue, 17 Jul 2018 09:52:41 +0000 (09:52 +0000)
Summary:
When a function is imported, check if it has a described template.
The name lookup is corrected to find the templated entity in this case.
The described template of the function is imported too.

Reviewers: a.sidorin, a_sidorin

Reviewed By: a_sidorin

Subscribers: a_sidorin, martong, cfe-commits

Differential Revision: https://reviews.llvm.org/D49235

llvm-svn: 337260

clang/lib/AST/ASTImporter.cpp
clang/unittests/AST/ASTImporterTest.cpp

index 366c2064d4e1e824d7d22c5964c01355bfdbf4a7..980ab478d594ffd8f2f38cc3194bb32b4697e549 100644 (file)
@@ -2539,6 +2539,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
     return ToD;
 
   const FunctionDecl *FoundByLookup = nullptr;
+  FunctionTemplateDecl *FromFT = D->getDescribedFunctionTemplate();
 
   // If this is a function template specialization, then try to find the same
   // existing specialization in the "to" context. The localUncachedLookup
@@ -2565,6 +2566,14 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
       if (!FoundDecl->isInIdentifierNamespace(IDNS))
         continue;
 
+      // If template was found, look at the templated function.
+      if (FromFT) {
+        if (auto *Template = dyn_cast<FunctionTemplateDecl>(FoundDecl))
+          FoundDecl = Template->getTemplatedDecl();
+        else
+          continue;
+      }
+
       if (auto *FoundFunction = dyn_cast<FunctionDecl>(FoundDecl)) {
         if (FoundFunction->hasExternalFormalLinkage() &&
             D->hasExternalFormalLinkage()) {
@@ -2740,6 +2749,11 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
     ToFunction->setType(T);
   }
 
+  // Import the describing template function, if any.
+  if (FromFT)
+    if (!Importer.Import(FromFT))
+      return nullptr;
+
   if (D->doesThisDeclarationHaveABody()) {
     if (Stmt *FromBody = D->getBody()) {
       if (Stmt *ToBody = Importer.Import(FromBody)) {
index cc8ed92faa8668611ecbc61c2d5ea5671ab2ed24..c59c2cd1253ce86a93ce54ee5a249bd0eb4dfb58 100644 (file)
@@ -1185,7 +1185,7 @@ TEST_P(ASTImporterTestBase,
 }
 
 TEST_P(ASTImporterTestBase,
-       DISABLED_ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl) {
+       ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl) {
   Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX);
   auto FromFT = FirstDeclMatcher<FunctionTemplateDecl>().match(
       FromTU, functionTemplateDecl());