summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-11 00:44:29 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-11 00:44:29 +0000
commita9faa44162a5ccc922113e2efc8dc2ae86021835 (patch)
tree7db1a9001b1212dd0665b921345571c0ad18c147 /clang/lib/Sema/SemaTemplate.cpp
parent081e354f11aecedf97d4841070f1411b7fc8e45f (diff)
downloadbcm5719-llvm-a9faa44162a5ccc922113e2efc8dc2ae86021835.tar.gz
bcm5719-llvm-a9faa44162a5ccc922113e2efc8dc2ae86021835.zip
Semantic checking for template arguments that correspond to non-type
template parameters that have reference type. Effectively, we're doing a very limited form of reference binding here. llvm-svn: 64270
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp43
1 files changed, 40 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index c78d8876dae..d4ba0c5edba 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -897,10 +897,10 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
}
if (const PointerType *ParamPtrType = ParamType->getAsPointerType()) {
- // -- for a non-type template-parameter of type pointer to
- // object, qualification conversions (4.4) and the
- // array-to-pointer conversion (4.2) are applied.
if (ParamPtrType->getPointeeType()->isObjectType()) {
+ // -- for a non-type template-parameter of type pointer to
+ // object, qualification conversions (4.4) and the
+ // array-to-pointer conversion (4.2) are applied.
if (ArgType->isArrayType()) {
ArgType = Context.getArrayDecayedType(ArgType);
ImpCastExprToType(Arg, ArgType);
@@ -960,6 +960,43 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
return false;
}
+ if (const ReferenceType *ParamRefType = ParamType->getAsReferenceType()) {
+ if (ParamRefType->getPointeeType()->isObjectType()) {
+ // -- For a non-type template-parameter of type reference to
+ // object, no conversions apply. The type referred to by the
+ // reference may be more cv-qualified than the (otherwise
+ // identical) type of the template-argument. The
+ // template-parameter is bound directly to the
+ // template-argument, which must be an lvalue.
+ if (!hasSameUnqualifiedType(ParamRefType->getPointeeType(), ArgType)) {
+ Diag(Arg->getSourceRange().getBegin(),
+ diag::err_template_arg_no_ref_bind)
+ << Param->getType() << Arg->getType()
+ << Arg->getSourceRange();
+ Diag(Param->getLocation(), diag::note_template_param_here);
+ return true;
+ }
+
+ unsigned ParamQuals
+ = Context.getCanonicalType(ParamType).getCVRQualifiers();
+ unsigned ArgQuals = Context.getCanonicalType(ArgType).getCVRQualifiers();
+
+ if ((ParamQuals | ArgQuals) != ParamQuals) {
+ Diag(Arg->getSourceRange().getBegin(),
+ diag::err_template_arg_ref_bind_ignores_quals)
+ << Param->getType() << Arg->getType()
+ << Arg->getSourceRange();
+ Diag(Param->getLocation(), diag::note_template_param_here);
+ return true;
+ }
+
+ // FIXME: Check the restrictions in p1!
+ // CheckAddressConstantExpression(Lvalue) can be modified to do
+ // this.
+ return false;
+ }
+ }
+
// FIXME: p5 has a lot more checks to perform!
return false;
OpenPOWER on IntegriCloud