[cfe-commits] r64305 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/SemaTemplate/temp_arg.cpp test/SemaTemplate/temp_arg_nontype.cpp test/SemaTemplate/temp_arg_template.cpp test/SemaTemplate/temp_arg_type.cpp
Douglas Gregor
dgregor at apple.com
Wed Feb 11 08:16:59 PST 2009
Author: dgregor
Date: Wed Feb 11 10:16:59 2009
New Revision: 64305
URL: http://llvm.org/viewvc/llvm-project?rev=64305&view=rev
Log:
Implement semantic checking for template arguments that correspond to
pointer-to-member-data non-type template parameters. Also, get
consistent about what it means to returned a bool from
CheckTemplateArgument.
Modified:
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/temp_arg.cpp
cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp
cfe/trunk/test/SemaTemplate/temp_arg_template.cpp
cfe/trunk/test/SemaTemplate/temp_arg_type.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=64305&r1=64304&r2=64305&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Feb 11 10:16:59 2009
@@ -655,8 +655,8 @@
// Check that the template argument list is well-formed for this
// template.
- if (!CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc,
- TemplateArgs, TemplateArgLocs, RAngleLoc))
+ if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc,
+ TemplateArgs, TemplateArgLocs, RAngleLoc))
return 0;
// Yes, all class template specializations are just silly sugar for
@@ -730,7 +730,7 @@
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
// Check template type parameters.
if (!ArgType.isNull()) {
- if (!CheckTemplateArgument(TTP, ArgType, ArgLoc))
+ if (CheckTemplateArgument(TTP, ArgType, ArgLoc))
Invalid = true;
continue;
}
@@ -749,7 +749,7 @@
= dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
// Check non-type template parameters.
if (ArgExpr) {
- if (!CheckTemplateArgument(NTTP, ArgExpr))
+ if (CheckTemplateArgument(NTTP, ArgExpr))
Invalid = true;
continue;
}
@@ -778,7 +778,7 @@
if (ArgExpr && isa<DeclRefExpr>(ArgExpr) &&
isa<TemplateDecl>(cast<DeclRefExpr>(ArgExpr)->getDecl())) {
- if (!CheckTemplateArgument(TempParm, cast<DeclRefExpr>(ArgExpr)))
+ if (CheckTemplateArgument(TempParm, cast<DeclRefExpr>(ArgExpr)))
Invalid = true;
continue;
}
@@ -1014,7 +1014,25 @@
// this.
return false;
}
- // FIXME: p5 has a lot more checks to perform!
+
+ // -- For a non-type template-parameter of type pointer to data
+ // member, qualification conversions (4.4) are applied.
+ assert(ParamType->isMemberPointerType() && "Only pointers to members remain");
+
+ if (hasSameUnqualifiedType(ParamType, ArgType)) {
+ // Types match exactly: nothing more to do here.
+ } else if (IsQualificationConversion(ArgType, ParamType)) {
+ ImpCastExprToType(Arg, ParamType);
+ } else {
+ // We can't perform this conversion.
+ Diag(Arg->getSourceRange().getBegin(),
+ diag::err_template_arg_not_convertible)
+ << Arg->getType() << Param->getType() << Arg->getSourceRange();
+ Diag(Param->getLocation(), diag::note_template_param_here);
+ return true;
+ }
+
+ // FIXME: Check the restrictions in p1.
return false;
}
Modified: cfe/trunk/test/SemaTemplate/temp_arg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg.cpp?rev=64305&r1=64304&r2=64305&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_arg.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_arg.cpp Wed Feb 11 10:16:59 2009
@@ -8,6 +8,7 @@
A<int, 0, X> * a1;
-A<float, 1, X, double> *a2; // expected-error{{too many template arguments for class template 'A'}}
-
-A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}}
+A<float, 1, X, double> *a2; // expected-error{{too many template arguments for class template 'A'}} \
+ // expected-error{{unqualified-id}}
+A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}} \
+ // expected-error{{unqualified-id}}
Modified: cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp?rev=64305&r1=64304&r2=64305&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp Wed Feb 11 10:16:59 2009
@@ -3,9 +3,11 @@
A<0> *a0;
-A<int()> *a1; // expected-error{{template argument for non-type template parameter is treated as type 'int (void)'}}
+A<int()> *a1; // expected-error{{template argument for non-type template parameter is treated as type 'int (void)'}} \
+ // FIXME: expected-error{{unqualified-id}}
-A<int> *a2; // expected-error{{template argument for non-type template parameter must be an expression}}
+A<int> *a2; // expected-error{{template argument for non-type template parameter must be an expression}} \
+ // FIXME: expected-error{{unqualified-id}}
A<1 >> 2> *a3;
@@ -15,8 +17,8 @@
// FIXME: expected-error{{expected unqualified-id}}
enum E { Enumerator = 17 };
-A<E> *a5; // expected-error{{template argument for non-type template parameter must be an expression}}
-
+A<E> *a5; // expected-error{{template argument for non-type template parameter must be an expression}} \
+ // FIXME: expected-error{{unqualified-id}}
template<E Value> struct A1; // expected-note{{template parameter is declared here}}
A1<Enumerator> *a6; // okay
A1<17> *a7; // expected-error{{non-type template argument of type 'int' cannot be converted to a value of type 'enum E'}} \
@@ -96,9 +98,20 @@
float bar(float);
int bar(int);
double baz(double);
+
+ int int_member;
+ float float_member;
};
template<int (Z::*pmf)(int)> struct A6; // expected-note{{template parameter is declared here}}
A6<&Z::foo> *a17_1;
A6<&Z::bar> *a17_2;
A6<&Z::baz> *a17_3; // expected-error{{non-type template argument of type 'double (struct Z::*)(double)' cannot be converted to a value of type 'int (struct Z::*)(int)'}} \
// FIXME: expected-error{{expected unqualified-id}}
+
+
+template<int Z::*pm> struct A7; // expected-note{{template parameter is declared here}}
+template<int Z::*pm> struct A7c;
+A7<&Z::int_member> *a18_1;
+A7c<&Z::int_member> *a18_2;
+A7<&Z::float_member> *a18_3; // expected-error{{non-type template argument of type 'float struct Z::*' cannot be converted to a value of type 'int struct Z::*'}} \
+ // FIXME: expected-error{{unqualified-id}}
Modified: cfe/trunk/test/SemaTemplate/temp_arg_template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_template.cpp?rev=64305&r1=64304&r2=64305&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_arg_template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_arg_template.cpp Wed Feb 11 10:16:59 2009
@@ -35,7 +35,8 @@
// FIXME: we're right to provide an error message, but it should say
// that we need a class template. We won't get this right until name
// lookup of 'f' returns a TemplateDecl.
-A<f> *a9; // expected-error{{template argument for template template parameter must be a template}}
+A<f> *a9; // expected-error{{template argument for template template parameter must be a template}} \
+ // expected-error{{unqualified-id}}
// FIXME: The code below is ill-formed, because of the evil digraph '<:'.
// We should provide a much better error message than we currently do.
Modified: cfe/trunk/test/SemaTemplate/temp_arg_type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_type.cpp?rev=64305&r1=64304&r2=64305&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_arg_type.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_arg_type.cpp Wed Feb 11 10:16:59 2009
@@ -2,9 +2,11 @@
template<typename T> class A; // expected-note 2 {{template parameter is declared here}}
// [temp.arg.type]p1
-A<0> *a1; // expected-error{{template argument for template type parameter must be a type}}
+A<0> *a1; // expected-error{{template argument for template type parameter must be a type}} \
+ // expected-error{{unqualified-id}}
-A<A> *a2; // expected-error{{template argument for template type parameter must be a type}}
+A<A> *a2; // expected-error{{template argument for template type parameter must be a type}} \
+ // expected-error{{unqualified-id}}
A<int> *a3;
A<int()> *a4;
More information about the cfe-commits
mailing list