[cfe-commits] r132530 - in /cfe/trunk: lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/SemaType.cpp test/SemaTemplate/instantiate-init.cpp

Douglas Gregor dgregor at apple.com
Thu Jun 2 20:35:07 PDT 2011


Author: dgregor
Date: Thu Jun  2 22:35:07 2011
New Revision: 132530

URL: http://llvm.org/viewvc/llvm-project?rev=132530&view=rev
Log:
When performing template argument deduction given a function argument
of incomplete array type, attempt to complete the array type. This was
made much easier by Chandler's addition of RequireCompleteExprType(),
which I've tweaked (slightly) to improve the consistency of the
DeclRefExpr. Fixes PR7985.

Modified:
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaTemplate/instantiate-init.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=132530&r1=132529&r2=132530&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Jun  2 22:35:07 2011
@@ -2500,6 +2500,12 @@
   if (ParamRefType) {
     QualType PointeeType = ParamRefType->getPointeeType();
 
+    // If the argument has incomplete array type, try to complete it's type.
+    if (ArgType->isIncompleteArrayType() &&
+        !S.RequireCompleteExprType(Arg, S.PDiag(), 
+                                   std::make_pair(SourceLocation(), S.PDiag())))
+      ArgType = Arg->getType();
+
     //   [C++0x] If P is an rvalue reference to a cv-unqualified
     //   template parameter and the argument is an lvalue, the type
     //   "lvalue reference to A" is used in place of A for type

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=132530&r1=132529&r2=132530&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Jun  2 22:35:07 2011
@@ -2555,6 +2555,10 @@
         == TSK_ExplicitInstantiationDeclaration)
     return;
 
+  // If we already have a definition, we're done.
+  if (Var->getDefinition())
+    return;
+
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Var);
   if (Inst)
     return;

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=132530&r1=132529&r2=132530&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Jun  2 22:35:07 2011
@@ -3280,9 +3280,13 @@
           InstantiateStaticDataMemberDefinition(E->getExprLoc(), Var);
           // Update the type to the newly instantiated definition's type both
           // here and within the expression.
-          T = Var->getDefinition()->getType();
-          E->setType(T);
-
+          if (VarDecl *Def = Var->getDefinition()) {
+            DRE->setDecl(Def);
+            T = Def->getType();
+            DRE->setType(T);
+            E->setType(T);
+          }
+          
           // We still go on to try to complete the type independently, as it
           // may also require instantiations or diagnostics if it remains
           // incomplete.

Modified: cfe/trunk/test/SemaTemplate/instantiate-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-init.cpp?rev=132530&r1=132529&r2=132530&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-init.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-init.cpp Thu Jun  2 22:35:07 2011
@@ -73,3 +73,26 @@
 
   int x = S<int>::f();
 }
+
+namespace PR7985 {
+  template<int N> struct integral_c { };
+
+  template <typename T, int N>
+  integral_c<N> array_lengthof(T (&x)[N]) { return integral_c<N>(); }
+
+  struct Data {
+    int x;
+  };
+
+  template<typename T>
+  struct Description {
+    static const Data data[];
+  };
+
+  template<typename T>
+  const Data Description<T>::data[] = {{ 0 }};
+
+  void test() {
+    integral_c<1> ic1 = array_lengthof(Description<int>::data);
+  }
+}





More information about the cfe-commits mailing list