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 | 1440693c50504e7f387cb1958bac48770a7f37f8 (patch) | |
| tree | 729f813bd97cb8ab7b041c4737029e752032e6e0 /clang | |
| parent | 0db031d532f4e148a5c83c376116d7255d04eac6 (diff) | |
| download | bcm5719-llvm-1440693c50504e7f387cb1958bac48770a7f37f8.tar.gz bcm5719-llvm-1440693c50504e7f387cb1958bac48770a7f37f8.zip | |
Diagnose the presence of unexpanded parameter packs within class
template partial specialization arguments.
llvm-svn: 122769
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 8 | ||||
| -rw-r--r-- | clang/include/clang/Sema/Sema.h | 15 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateVariadic.cpp | 14 | ||||
| -rw-r--r-- | clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp | 8 |
5 files changed, 42 insertions, 9 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index eb123b9fe9f..c8d2678e88d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/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/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 05bb1258c1b..2d349bc34c2 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index ce0132ee814..6384e53e80b 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/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/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 030a0423f74..828d2a3539e 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/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/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp index 47581fee90a..d52d9c52a41 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp +++ b/clang/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. |

