aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-07-18 01:29:05 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-07-18 01:29:05 +0000
commit500d729e85028944355a119f9823ac99fa5ddcab (patch)
tree4c61dbac98164c678af990611d511df3c6915afc /lib/Sema/SemaTemplateInstantiateDecl.cpp
parent5912597f3a01f6b5a6f6c5543317d209dbbb0a87 (diff)
PR13386: When matching up parameters between a function template declaration
and a function template instantiation, if there's a parameter pack in the declaration and one at the same place in the instantiation, don't assume that the pack wasn't expanded -- it may have expanded to nothing. Instead, go ahead and check whether the parameter pack was expandable. We can do this as a side-effect of the work we'd need to do anyway, to find how many parameters were produced. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160416 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp46
1 files changed, 22 insertions, 24 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index a2efa597c2..5a10dfbccd 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2176,35 +2176,31 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D,
TypeLoc NewTL = NewTInfo->getTypeLoc().IgnoreParens();
FunctionProtoTypeLoc *NewProtoLoc = cast<FunctionProtoTypeLoc>(&NewTL);
assert(NewProtoLoc && "Missing prototype?");
- unsigned NewIdx = 0, NumNewParams = NewProtoLoc->getNumArgs();
+ unsigned NewIdx = 0;
for (unsigned OldIdx = 0, NumOldParams = OldProtoLoc->getNumArgs();
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())) {
+ LocalInstantiationScope *Scope = SemaRef.CurrentInstantiationScope;
+
+ llvm::Optional<unsigned> NumArgumentsInExpansion;
+ if (OldParam->isParameterPack())
+ NumArgumentsInExpansion =
+ SemaRef.getNumArgumentsInExpansion(OldParam->getType(),
+ TemplateArgs);
+ if (!NumArgumentsInExpansion) {
// Simple case: normal parameter, or a parameter pack that's
// instantiated to a (still-dependent) parameter pack.
ParmVarDecl *NewParam = NewProtoLoc->getArg(NewIdx++);
Params.push_back(NewParam);
- SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam,
- NewParam);
- continue;
- }
-
- // Parameter pack: make the instantiation an argument pack.
- SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(
- OldParam);
- unsigned NumArgumentsInExpansion
- = SemaRef.getNumArgumentsInExpansion(OldParam->getType(),
- TemplateArgs);
- while (NumArgumentsInExpansion--) {
- ParmVarDecl *NewParam = NewProtoLoc->getArg(NewIdx++);
- Params.push_back(NewParam);
- SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(OldParam,
- NewParam);
+ Scope->InstantiatedLocal(OldParam, NewParam);
+ } else {
+ // Parameter pack expansion: make the instantiation an argument pack.
+ Scope->MakeInstantiatedLocalArgPack(OldParam);
+ for (unsigned I = 0; I != *NumArgumentsInExpansion; ++I) {
+ ParmVarDecl *NewParam = NewProtoLoc->getArg(NewIdx++);
+ Params.push_back(NewParam);
+ Scope->InstantiatedLocalPackArg(OldParam, NewParam);
+ }
}
}
}
@@ -2248,9 +2244,11 @@ static void addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,
// Expand the parameter pack.
Scope.MakeInstantiatedLocalArgPack(PatternParam);
- unsigned NumArgumentsInExpansion
+ llvm::Optional<unsigned> NumArgumentsInExpansion
= S.getNumArgumentsInExpansion(PatternParam->getType(), TemplateArgs);
- for (unsigned Arg = 0; Arg < NumArgumentsInExpansion; ++Arg) {
+ assert(NumArgumentsInExpansion &&
+ "should only be called when all template arguments are known");
+ for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) {
ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
FunctionParam->setDeclName(PatternParam->getDeclName());
Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam);