diff options
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 23 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-function-2.cpp | 11 |
2 files changed, 31 insertions, 3 deletions
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<FunctionProtoType>(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<FunctionProtoType>(); + 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<int>(); // expected-note{{instantiation of}} } } + +namespace PR9654 { + typedef void ftype(int); + + template<typename T> + ftype f; + + void g() { + f<int>(0); + } +} |