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 Parameters; + TypeLoc ToTypeLoc = TInfo->getTypeLoc(); + unsigned I = 0; + for (auto P : D->getTemplatedDecl()->params()) { + ParmVarDecl *ToP = cast_or_null(Importer.Import(P)); + ToP->setScopeInfo(P->getFunctionScopeDepth(), P->getFunctionScopeIndex()); + if (!ToP) + return nullptr; + + Parameters.push_back(ToP); + + if (FunctionProtoTypeLoc ToProtoLoc + = ToTypeLoc.getAs()) { + ToProtoLoc.setParam(I, Parameters[I]); + I++; + } + } + + FunctionDecl *ToFunction; + if (CXXMethodDecl *Method = dyn_cast(D->getTemplatedDecl())) { + ToFunction = CXXMethodDecl::Create(Importer.getToContext(), + cast(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 //---------------------------------------------------------------------------- Index: test/ASTMerge/Inputs/function-template1.cpp =================================================================== --- /dev/null +++ test/ASTMerge/Inputs/function-template1.cpp @@ -0,0 +1,16 @@ +template + T funcTempl(T x, T y) { + return x + y; + } + +template + T cast(V x) { + return (T)x; + } + +class B { + template + C templFun(C arg) { + return arg; + } +}; Index: test/ASTMerge/Inputs/function-template2.cpp =================================================================== --- /dev/null +++ test/ASTMerge/Inputs/function-template2.cpp @@ -0,0 +1,16 @@ +template + T funcTempl(T x, T y) { + return x + y; + } + +template + T cast(V x) { + return (T)x; + } + +class B { + template + C templFun(C arg) { + return arg; + } +}; 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