Once we've collected the template arguments for a

partially-substituted parameter pack in a template, forget about the
partially-substituted parameter pack: it is now completed. Fixes
<rdar://problem/12176336>.

llvm-svn: 172859
This commit is contained in:
Douglas Gregor 2013-01-18 22:27:09 +00:00
parent 9fa426a666
commit caddba9f00
3 changed files with 38 additions and 4 deletions

View File

@ -346,6 +346,15 @@ namespace clang {
const TemplateArgument *ExplicitArgs,
unsigned NumExplicitArgs);
/// \brief Reset the partially-substituted pack when it is no longer of
/// interest.
void ResetPartiallySubstitutedPack() {
assert(PartiallySubstitutedPack && "No partially-substituted pack");
PartiallySubstitutedPack = 0;
ArgsInPartiallySubstitutedPack = 0;
NumArgsInPartiallySubstitutedPack = 0;
}
/// \brief Retrieve the partially-substitued template parameter pack.
///
/// If there is no partially-substituted parameter pack, returns NULL.

View File

@ -2647,11 +2647,15 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
if (CurrentInstantiationScope &&
CurrentInstantiationScope->getPartiallySubstitutedPack(&ExplicitArgs,
&NumExplicitArgs)
== Param)
== Param) {
Builder.push_back(TemplateArgument(ExplicitArgs, NumExplicitArgs));
else
Builder.push_back(TemplateArgument::getEmptyPack());
// Forget the partially-substituted pack; it's substitution is now
// complete.
CurrentInstantiationScope->ResetPartiallySubstitutedPack();
} else {
Builder.push_back(TemplateArgument::getEmptyPack());
}
continue;
}

View File

@ -26,3 +26,24 @@ namespace ParameterPacksWithFunctions {
unsigned_c<2> uc2 = f<float, double>();
}
}
namespace rdar12176336 {
typedef void (*vararg_func)(...);
struct method {
vararg_func implementation;
method(vararg_func implementation) : implementation(implementation) {}
template<typename TReturnType, typename... TArguments, typename TFunctionType = TReturnType (*)(TArguments...)>
auto getImplementation() const -> TFunctionType
{
return reinterpret_cast<TFunctionType>(implementation);
}
};
void f() {
method m(nullptr);
auto imp = m.getImplementation<int, int, int>();
}
}