Handle instantiation of templates with non-type arguments expressed with an

explicit '&' by introducing an address-of operator prior to checking the
argument's type.

llvm-svn: 94947
This commit is contained in:
Chandler Carruth 2010-01-31 07:09:11 +00:00
parent 7f62def0f9
commit 9b1fa25432
2 changed files with 26 additions and 0 deletions

View File

@ -746,6 +746,22 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
move(RefExpr));
}
}
if (NTTP->getType()->isPointerType() &&
!VD->getType()->isPointerType()) {
// If the template argument is expected to be a pointer and value
// isn't inherently of pointer type, then it is specified with '&...'
// to indicate its address should be used. Build an expression to
// take the address of the argument.
OwningExprResult RefExpr
= SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
E->getLocation());
if (RefExpr.isInvalid())
return SemaRef.ExprError();
return SemaRef.CreateBuiltinUnaryOp(E->getLocation(),
UnaryOperator::AddrOf,
move(RefExpr));
}
return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
E->getLocation());

View File

@ -0,0 +1,10 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
template <const int* p> struct X { };
int i = 42;
int* iptr = &i;
void test() {
X<&i> x1;
X<iptr> x2;
}