diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-06-04 08:34:32 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-06-04 08:34:32 +0000 |
| commit | 2e87ca218f5d11b72a00e820cfd43a472247fe68 (patch) | |
| tree | ae130867cb87addca03132113ee906069683adcb /clang | |
| parent | b1cd7dac3d77fa20853254f7d9794f396ee98272 (diff) | |
| download | bcm5719-llvm-2e87ca218f5d11b72a00e820cfd43a472247fe68.tar.gz bcm5719-llvm-2e87ca218f5d11b72a00e820cfd43a472247fe68.zip | |
When checking for equality of template parameter lists, a template
type parameter pack is distinct from a template type parameter.
llvm-svn: 105464
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 13 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 29 | ||||
| -rw-r--r-- | clang/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp | 21 |
3 files changed, 60 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 0ba31aee2ff..207b081cf7a 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1234,6 +1234,7 @@ def err_template_param_different_kind : Error< "%select{|template parameter }0redeclaration">; def note_template_param_different_kind : Note< "template parameter has a different kind in template argument">; + def err_template_nontype_parm_different_type : Error< "template non-type parameter has a different type %0 in template " "%select{|template parameter }1redeclaration">; @@ -1606,6 +1607,18 @@ def err_template_param_pack_default_arg : Error< def err_template_param_pack_must_be_last_template_parameter : Error< "template parameter pack must be the last template parameter">; +def err_template_parameter_pack_non_pack : Error< + "template %select{type|non-type|template}0 parameter%select{| pack}1 " + "conflicts with previous template %select{type|non-type|template}0 " + "parameter%select{ pack|}1">; +def note_template_parameter_pack_non_pack : Note< + "template %select{type|non-type|template}0 parameter%select{| pack}1 " + "does not match template %select{type|non-type|template}0 " + "parameter%select{ pack|}1 in template argument">; +def note_template_parameter_pack_here : Note< + "previous template %select{type|non-type|template}0 " + "parameter%select{| pack}1 declared here">; + def err_unexpected_typedef : Error< "unexpected type name %0: expected expression">; def err_unexpected_namespace : Error< diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 40bbb152690..b02fc05892a 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3237,9 +3237,32 @@ Sema::TemplateParameterListsAreEqual(TemplateParameterList *New, return false; } - if (isa<TemplateTypeParmDecl>(*OldParm)) { - // Okay; all template type parameters are equivalent (since we - // know we're at the same index). + if (TemplateTypeParmDecl *OldTTP + = dyn_cast<TemplateTypeParmDecl>(*OldParm)) { + // Template type parameters are equivalent if either both are template + // type parameter packs or neither are (since we know we're at the same + // index). + TemplateTypeParmDecl *NewTTP = cast<TemplateTypeParmDecl>(*NewParm); + if (OldTTP->isParameterPack() != NewTTP->isParameterPack()) { + // FIXME: Implement the rules in C++0x [temp.arg.template]p5 that + // allow one to match a template parameter pack in the template + // parameter list of a template template parameter to one or more + // template parameters in the template parameter list of the + // corresponding template template argument. + if (Complain) { + unsigned NextDiag = diag::err_template_parameter_pack_non_pack; + if (TemplateArgLoc.isValid()) { + Diag(TemplateArgLoc, + diag::err_template_arg_template_params_mismatch); + NextDiag = diag::note_template_parameter_pack_non_pack; + } + Diag(NewTTP->getLocation(), NextDiag) + << 0 << NewTTP->isParameterPack(); + Diag(OldTTP->getLocation(), diag::note_template_parameter_pack_here) + << 0 << OldTTP->isParameterPack(); + } + return false; + } } else if (NonTypeTemplateParmDecl *OldNTTP = dyn_cast<NonTypeTemplateParmDecl>(*OldParm)) { // The types of non-type template parameters must agree. diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp new file mode 100644 index 00000000000..7352be2d72f --- /dev/null +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +// Check for template type parameter pack (mis-)matches with template +// type parameters. +template<typename ...T> struct X0t; +template<typename ...T> struct X0t; + +template<typename ...T> struct X1t; // expected-note{{previous template type parameter pack declared here}} +template<typename T> struct X1t; // expected-error{{template type parameter conflicts with previous template type parameter pack}} + +template<typename T> struct X2t; // expected-note{{previous template type parameter declared here}} +template<typename ...T> struct X2t; // expected-error{{template type parameter pack conflicts with previous template type parameter}} + +template<template<typename ...T> class> struct X0tt; +template<template<typename ...T> class> struct X0tt; + +template<template<typename ...T> class> struct X1tt; // expected-note{{previous template type parameter pack declared here}} +template<template<typename T> class> struct X1tt; // expected-error{{template type parameter conflicts with previous template type parameter pack}} + +template<template<typename T> class> struct X2tt; // expected-note{{previous template type parameter declared here}} +template<template<typename ...T> class> struct X2tt; // expected-error{{template type parameter pack conflicts with previous template type parameter}} |

