esakella created this revision.
esakella added reviewers: rsmith, klimek, bkramer, spyffe.
esakella added subscribers: karies, cfe-commits.
Herald added a subscriber: aemerson.

Implemented the VisitFunctionTemplateDecl function for the import of template 
function definitions. 

Note that this function needs the VisitTemplateTypeParmType function to be also 
implemented in order to work,  therefore it is dependent on the Differential 
D17029. It also needs the change in Differential D17026 in the Diagnostics 
Engine of the ASTImporter in order for this test to catch any error emitted. 

http://reviews.llvm.org/D17136

Files:
  lib/AST/ASTImporter.cpp
  test/ASTMerge/Inputs/function-template1.cpp
  test/ASTMerge/Inputs/function-template2.cpp
  test/ASTMerge/function-template.cpp

Index: test/ASTMerge/function-template.cpp
===================================================================
--- /dev/null
+++ test/ASTMerge/function-template.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/function-template1.cpp
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/function-template2.cpp
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s
+// expected-no-diagnostics
Index: test/ASTMerge/Inputs/function-template2.cpp
===================================================================
--- /dev/null
+++ test/ASTMerge/Inputs/function-template2.cpp
@@ -0,0 +1,16 @@
+template<typename T>
+  T funcTempl(T x, T y) {
+    return x + y;
+  }
+
+template <class T, class V>
+  T cast(V x) {
+    return (T)x;
+  }
+
+class B {
+ template<class C>
+  C templFun(C arg) {
+   return arg;
+  }
+};
Index: test/ASTMerge/Inputs/function-template1.cpp
===================================================================
--- /dev/null
+++ test/ASTMerge/Inputs/function-template1.cpp
@@ -0,0 +1,16 @@
+template<typename T>
+  T funcTempl(T x, T y) {
+    return x + y;
+  }
+
+template <class T, class V>
+  T cast(V x) {
+    return (T)x;
+  }
+
+class B {
+ template<class C>
+  C templFun(C arg) {
+   return arg;
+  }
+};
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -169,6 +169,7 @@
                                             ClassTemplateSpecializationDecl *D);
     Decl *VisitVarTemplateDecl(VarTemplateDecl *D);
     Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
+    Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
 
     // Importing statements
     DeclGroupRef ImportDeclGroup(DeclGroupRef DG);
@@ -4576,6 +4577,93 @@
   return D2;
 }
 
+Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+  // Import the major distinguishing characteristics of this function.
+  DeclContext *DC, *LexicalDC;
+  DeclarationName Name;
+  SourceLocation Loc;
+  NamedDecl *ToD;
+  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return nullptr;
+
+  DeclarationNameInfo NameInfo(Name, Loc);
+
+  QualType FromTy = D->getTemplatedDecl()->getType();
+
+  // Import the type.
+  QualType T = Importer.Import(FromTy);
+  if (T.isNull())
+    return nullptr;
+
+  TypeSourceInfo *TInfo
+    = Importer.Import(D->getTemplatedDecl()->getTypeSourceInfo());
+
+  // Import the function parameters.
+  SmallVector<ParmVarDecl *, 8> Parameters;
+  TypeLoc ToTypeLoc = TInfo->getTypeLoc();
+  unsigned I = 0;
+  for (auto P : D->getTemplatedDecl()->params()) {
+    ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(P));
+    ToP->setScopeInfo(P->getFunctionScopeDepth(), P->getFunctionScopeIndex());
+    if (!ToP)
+      return nullptr;
+
+    Parameters.push_back(ToP);
+
+    if (FunctionProtoTypeLoc ToProtoLoc
+          = ToTypeLoc.getAs<FunctionProtoTypeLoc>()) {
+      ToProtoLoc.setParam(I, Parameters[I]);
+      I++;
+    }
+  }
+
+  FunctionDecl *ToFunction;
+  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D->getTemplatedDecl())) {
+    ToFunction = CXXMethodDecl::Create(Importer.getToContext(),
+                                       cast<CXXRecordDecl>(DC),
+                                       D->getTemplatedDecl()->getInnerLocStart(),
+                                       NameInfo, T, TInfo,
+                                       Method->getStorageClass(),
+                                       Method->isInlineSpecified(),
+                                       D->getTemplatedDecl()->isConstexpr(),
+                                       Importer.Import(D->getLocEnd()));
+  } else {
+    ToFunction = FunctionDecl::Create(Importer.getToContext(), DC,
+                                      D->getTemplatedDecl()->getInnerLocStart(),
+                                      NameInfo, T, TInfo,
+                                      D->getTemplatedDecl()->getStorageClass(),
+                                      D->getTemplatedDecl()->isInlineSpecified(),
+                                      D->getTemplatedDecl()->hasWrittenPrototype(),
+                                      D->getTemplatedDecl()->isConstexpr());
+  }
+
+  // Import the qualifier, if any.
+  ToFunction->setQualifierInfo(Importer.Import(
+    D->getTemplatedDecl()->getQualifierLoc()));
+  ToFunction->setAccess(D->getTemplatedDecl()->getAccess());
+  ToFunction->setLexicalDeclContext(LexicalDC);
+  Importer.Imported(D, ToFunction);
+
+  // Set the parameters.
+  for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
+    Parameters[I]->setOwningFunction(ToFunction);
+    ToFunction->addDeclInternal(Parameters[I]);
+  }
+  ToFunction->setParams(Parameters);
+
+  FunctionTemplateDecl *ToFunctionTemplate
+    = FunctionTemplateDecl::Create(Importer.getToContext(), DC,
+                                   Loc, Name,
+                                   D->getTemplateParameters(),
+                                   ToFunction);
+
+  ToFunctionTemplate->setAccess(D->getAccess());
+  ToFunction->setDescribedFunctionTemplate(ToFunctionTemplate);
+
+  LexicalDC->addDeclInternal(ToFunctionTemplate);
+  return ToFunctionTemplate;
+}
+
 //----------------------------------------------------------------------------
 // Import Statements
 //----------------------------------------------------------------------------
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to