]> granicus.if.org Git - clang/commitdiff
Handle instantiation of templates with non-type arguments expressed with an
authorChandler Carruth <chandlerc@gmail.com>
Sun, 31 Jan 2010 07:09:11 +0000 (07:09 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sun, 31 Jan 2010 07:09:11 +0000 (07:09 +0000)
explicit '&' by introducing an address-of operator prior to checking the
argument's type.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94947 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiate.cpp
test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp [new file with mode: 0644]

index 2db0deb5098b63f7e09f874a379d916bff2409d2..3efb52e91bf70b38052d1cd9a0357d8c3e49d779 100644 (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());
diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
new file mode 100644 (file)
index 0000000..f9834df
--- /dev/null
@@ -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;
+}