diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-03 20:35:03 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-03 20:35:03 +0000 |
commit | 925910d488051cbd4e38f350c1e9d69c473f09a0 (patch) | |
tree | ef5ad452c4a8201a08ec238cb8e65b36cb0f4ec2 | |
parent | af4bad23013532f4c94cdc27887623f45e6f7020 (diff) |
Diagnose the presence of unexpanded parameter packs within class
template partial specialization arguments.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122769 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 8 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 15 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 14 | ||||
-rw-r--r-- | test/CXX/temp/temp.decls/temp.variadic/p5.cpp | 8 |
5 files changed, 42 insertions, 9 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index eb123b9fe9..c8d2678e88 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1836,25 +1836,25 @@ def err_unexpanded_parameter_pack_0 : Error< "%select{expression|base type|declaration type|data member type|bit-field " "size|static assertion|fixed underlying type|enumerator value|" "using declaration|friend declaration|qualifier|initializer|default argument|" - "non-type template parameter type|exception type}0 " + "non-type template parameter type|exception type|partial specialization}0 " "contains an unexpanded parameter pack">; def err_unexpanded_parameter_pack_1 : Error< "%select{expression|base type|declaration type|data member type|bit-field " "size|static assertion|fixed underlying type|enumerator value|" "using declaration|friend declaration|qualifier|initializer|default argument|" - "non-type template parameter type|exception type}0 " + "non-type template parameter type|exception type|partial specialization}0 " "contains unexpanded parameter pack %1">; def err_unexpanded_parameter_pack_2 : Error< "%select{expression|base type|declaration type|data member type|bit-field " "size|static assertion|fixed underlying type|enumerator value|" "using declaration|friend declaration|qualifier|initializer|default argument|" - "non-type template parameter type|exception type}0 " + "non-type template parameter type|exception type|partial specialization}0 " "contains unexpanded parameter packs %1 and %2">; def err_unexpanded_parameter_pack_3_or_more : Error< "%select{expression|base type|declaration type|data member type|bit-field " "size|static assertion|fixed underlying type|enumerator value|" "using declaration|friend declaration|qualifier|initializer|default argument|" - "non-type template parameter type|exception type}0 " + "non-type template parameter type|exception type|partial specialization}0 " "contains unexpanded parameter packs %1, %2, ...">; def err_pack_expansion_without_parameter_packs : Error< diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 05bb1258c1..2d349bc34c 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -3187,7 +3187,10 @@ public: UPPC_NonTypeTemplateParameterType, /// \brief The type of an exception. - UPPC_ExceptionType + UPPC_ExceptionType, + + /// \brief Partial specialization. + UPPC_PartialSpecialization }; /// \brief If the given type contains an unexpanded parameter pack, @@ -3245,6 +3248,16 @@ public: TemplateName Template, UnexpandedParameterPackContext UPPC); + /// \brief If the given template argument contains an unexpanded parameter + /// pack, diagnose the error. + /// + /// \param Arg The template argument that is being checked for unexpanded + /// parameter packs. + /// + /// \returns true if an error ocurred, false otherwise. + bool DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, + UnexpandedParameterPackContext UPPC); + /// \brief Collect the set of unexpanded parameter packs within the given /// template argument. /// diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index ce0132ee81..6384e53e80 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -4126,6 +4126,12 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TemplateArgs.setRAngleLoc(RAngleLoc); translateTemplateArguments(TemplateArgsIn, TemplateArgs); + // Check for unexpanded parameter packs in any of the template arguments. + for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) + if (DiagnoseUnexpandedParameterPack(TemplateArgs[I], + UPPC_PartialSpecialization)) + return true; + // Check that the template argument list is well-formed for this // template. llvm::SmallVector<TemplateArgument, 4> Converted; diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 030a0423f7..828d2a3539 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -263,6 +263,20 @@ bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, return true; } +bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, + UnexpandedParameterPackContext UPPC) { + if (Arg.getArgument().isNull() || + !Arg.getArgument().containsUnexpandedParameterPack()) + return false; + + llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; + CollectUnexpandedParameterPacksVisitor(Unexpanded) + .TraverseTemplateArgumentLoc(Arg); + assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); + DiagnoseUnexpandedParameterPacks(*this, Arg.getLocation(), UPPC, Unexpanded); + return true; +} + void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg, llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { CollectUnexpandedParameterPacksVisitor(Unexpanded) diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp index 47581fee90..d52d9c52a4 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp @@ -211,10 +211,10 @@ struct TestUnexpandedDecls : T{ // FIXME: Test for unexpanded parameter packs in each of the statements. -// FIXME: Once we have template argument deduction, we can test -// unexpanded parameter packs in partial specializations. -// template<typename ...Types> -// struct TestUnexpandedDecls<int, Types>; +// Test unexpanded parameter packs in partial specializations. + +template<typename ...Types> +struct TestUnexpandedDecls<int, Types>; // expected-error{{partial specialization contains unexpanded parameter pack 'Types'}} // Test for diagnostics in the presence of multiple unexpanded // parameter packs. |