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:
parent
7f62def0f9
commit
9b1fa25432
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue