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