forked from OSchip/llvm-project
When checking for equality of template parameter lists, a template
type parameter pack is distinct from a template type parameter. llvm-svn: 105464
This commit is contained in:
parent
b1cd7dac3d
commit
2e87ca218f
|
@ -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<
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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}}
|
Loading…
Reference in New Issue