forked from OSchip/llvm-project
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:
parent
9fa426a666
commit
caddba9f00
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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>();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue