From: Douglas Gregor Date: Wed, 22 Jun 2011 18:16:25 +0000 (+0000) Subject: When instantiating a function template declaration that was expressed X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d441ee69aaf3b3afa4521d05df934c5c7ea5f62;p=clang When instantiating a function template declaration that was expressed via a typedef of a function, make sure to synthesize parameter declarations. Fixes PR9654 / . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133628 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index cc66ec6759..196e847728 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1090,9 +1090,26 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Function->setLexicalDeclContext(LexicalDC); // Attach the parameters - for (unsigned P = 0; P < Params.size(); ++P) - if (Params[P]) - Params[P]->setOwningFunction(Function); + if (isa(Function->getType())) { + // Adopt the already-instantiated parameters into our own context. + for (unsigned P = 0; P < Params.size(); ++P) + if (Params[P]) + Params[P]->setOwningFunction(Function); + } else { + // Since we were instantiated via a typedef of a function type, create + // new parameters. + const FunctionProtoType *Proto + = Function->getType()->getAs(); + assert(Proto && "No function prototype in template instantiation?"); + for (FunctionProtoType::arg_type_iterator AI = Proto->arg_type_begin(), + AE = Proto->arg_type_end(); AI != AE; ++AI) { + ParmVarDecl *Param + = SemaRef.BuildParmVarDeclForTypedef(Function, Function->getLocation(), + *AI); + Param->setScopeInfo(0, Params.size()); + Params.push_back(Param); + } + } Function->setParams(Params.data(), Params.size()); SourceLocation InstantiateAtPOI; diff --git a/test/SemaTemplate/instantiate-function-2.cpp b/test/SemaTemplate/instantiate-function-2.cpp index ebc0ef3a9f..b4c0d9d639 100644 --- a/test/SemaTemplate/instantiate-function-2.cpp +++ b/test/SemaTemplate/instantiate-function-2.cpp @@ -31,3 +31,14 @@ namespace UsedAttr { foo(); // expected-note{{instantiation of}} } } + +namespace PR9654 { + typedef void ftype(int); + + template + ftype f; + + void g() { + f(0); + } +}