diff options
author | Douglas Gregor <dgregor@apple.com> | 2013-01-18 22:27:09 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2013-01-18 22:27:09 +0000 |
commit | caddba9f00d71d8b2986f263a10c4b249d326b57 (patch) | |
tree | cd5cd4c0d8a56803695910182199bc9980d160d6 | |
parent | 9fa426a666ce928ff968a77ac17458f275f6e0ff (diff) | |
download | bcm5719-llvm-caddba9f00d71d8b2986f263a10c4b249d326b57.tar.gz bcm5719-llvm-caddba9f00d71d8b2986f263a10c4b249d326b57.zip |
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
-rw-r--r-- | clang/include/clang/Sema/Template.h | 11 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 10 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp | 21 |
3 files changed, 38 insertions, 4 deletions
diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h index 13c44718582..fd67222f0f8 100644 --- a/clang/include/clang/Sema/Template.h +++ b/clang/include/clang/Sema/Template.h @@ -345,7 +345,16 @@ namespace clang { void SetPartiallySubstitutedPack(NamedDecl *Pack, 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. diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 67ea68928da..00a48e9396b 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -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; } diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp index 36b07002cf3..dcf5a08d906 100644 --- a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp +++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp @@ -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>(); + } +} |