diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-13 06:56:52 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-13 06:56:52 +0000 |
commit | 9479a2e35eb316515df78d5f5499803643f3894d (patch) | |
tree | c8ce81c9fbf881d3a6af8da0951fd9c2ad37ec8b /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 8b5f7c5aa20f8d98d0d580605074b75a903994f2 (diff) | |
download | bcm5719-llvm-9479a2e35eb316515df78d5f5499803643f3894d.tar.gz bcm5719-llvm-9479a2e35eb316515df78d5f5499803643f3894d.zip |
PR11850 + duplicates: don't assume that a function parameter pack expansion is
at the end of the parameter list.
llvm-svn: 152618
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index f10670c47a6..d7da736fe62 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2115,6 +2115,8 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, OldIdx != NumOldParams; ++OldIdx) { ParmVarDecl *OldParam = OldProtoLoc->getArg(OldIdx); if (!OldParam->isParameterPack() || + // FIXME: Is this right? OldParam could expand to an empty parameter + // pack and the next parameter could be an unexpanded parameter pack (NewIdx < NumNewParams && NewProtoLoc->getArg(NewIdx)->isParameterPack())) { // Simple case: normal parameter, or a parameter pack that's @@ -2458,6 +2460,13 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, LocalInstantiationScope Scope(*this, MergeWithParentScope); + // Enter the scope of this instantiation. We don't use + // PushDeclContext because we don't have a scope. + Sema::ContextRAII savedContext(*this, Function); + + MultiLevelTemplateArgumentList TemplateArgs = + getTemplateInstantiationArgs(Function, 0, false, PatternDecl); + // Introduce the instantiated function parameters into the local // instantiation scope, and set the parameter names to those used // in the template. @@ -2467,7 +2476,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (!PatternParam->isParameterPack()) { // Simple case: not a parameter pack. assert(FParamIdx < Function->getNumParams()); - ParmVarDecl *FunctionParam = Function->getParamDecl(I); + ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); FunctionParam->setDeclName(PatternParam->getDeclName()); Scope.InstantiatedLocal(PatternParam, FunctionParam); ++FParamIdx; @@ -2476,22 +2485,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, // Expand the parameter pack. Scope.MakeInstantiatedLocalArgPack(PatternParam); - for (unsigned NumFParams = Function->getNumParams(); - FParamIdx < NumFParams; - ++FParamIdx) { + unsigned NumArgumentsInExpansion + = getNumArgumentsInExpansion(PatternParam->getType(), TemplateArgs); + for (unsigned Arg = 0; Arg < NumArgumentsInExpansion; ++Arg) { ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); FunctionParam->setDeclName(PatternParam->getDeclName()); Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam); + ++FParamIdx; } } - // Enter the scope of this instantiation. We don't use - // PushDeclContext because we don't have a scope. - Sema::ContextRAII savedContext(*this, Function); - - MultiLevelTemplateArgumentList TemplateArgs = - getTemplateInstantiationArgs(Function, 0, false, PatternDecl); - if (PatternDecl->isDefaulted()) { ActOnFinishFunctionBody(Function, 0, /*IsInstantiation=*/true); |