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

Douglas Gregor dgregor at apple.com
Fri Jun 3 07:28:43 PDT 2011


Author: dgregor
Date: Fri Jun  3 09:28:43 2011
New Revision: 132547

URL: http://llvm.org/viewvc/llvm-project?rev=132547&view=rev
Log:
Improve the instantiation of static data members in
Sema::RequireCompleteExprType() a bit more, setting the point of
instantiation if needed, and skipping explicit specializations entirely.

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

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=132547&r1=132546&r2=132547&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Jun  3 09:28:43 2011
@@ -15,6 +15,7 @@
 #include "clang/Sema/Template.h"
 #include "clang/Basic/OpenCL.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -3277,14 +3278,31 @@
       if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
         if (Var->isStaticDataMember() &&
             Var->getInstantiatedFromStaticDataMember()) {
-          InstantiateStaticDataMemberDefinition(E->getExprLoc(), Var);
-          // Update the type to the newly instantiated definition's type both
-          // here and within the expression.
-          if (VarDecl *Def = Var->getDefinition()) {
-            DRE->setDecl(Def);
-            T = Def->getType();
-            DRE->setType(T);
-            E->setType(T);
+          
+          MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
+          assert(MSInfo && "Missing member specialization information?");
+          if (MSInfo->getTemplateSpecializationKind()
+                != TSK_ExplicitSpecialization) {
+            // If we don't already have a point of instantiation, this is it.
+            if (MSInfo->getPointOfInstantiation().isInvalid()) {
+              MSInfo->setPointOfInstantiation(E->getLocStart());
+              
+              // This is a modification of an existing AST node. Notify 
+              // listeners.
+              if (ASTMutationListener *L = getASTMutationListener())
+                L->StaticDataMemberInstantiated(Var);
+            }
+            
+            InstantiateStaticDataMemberDefinition(E->getExprLoc(), Var);
+            
+            // Update the type to the newly instantiated definition's type both
+            // here and within the expression.
+            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

Modified: cfe/trunk/test/SemaTemplate/instantiate-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-init.cpp?rev=132547&r1=132546&r2=132547&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-init.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-init.cpp Fri Jun  3 09:28:43 2011
@@ -78,21 +78,32 @@
   template<int N> struct integral_c { };
 
   template <typename T, int N>
-  integral_c<N> array_lengthof(T (&x)[N]) { return integral_c<N>(); }
+  integral_c<N> array_lengthof(T (&x)[N]) { return integral_c<N>(); } // expected-note 2{{candidate template ignored: failed template argument deduction}}
 
+  template<typename T>
   struct Data {
-    int x;
+    T x;
   };
 
   template<typename T>
   struct Description {
-    static const Data data[];
+    static const Data<T> data[];
   };
 
   template<typename T>
-  const Data Description<T>::data[] = {{ 0 }};
+  const Data<T> Description<T>::data[] = {{ 1 }}; // expected-error{{cannot initialize a member subobject of type 'int *' with an rvalue of type 'int'}}
+
+  template<>
+  Data<float*> Description<float*>::data[];
 
   void test() {
     integral_c<1> ic1 = array_lengthof(Description<int>::data);
+    (void)sizeof(array_lengthof(Description<float>::data));
+
+    sizeof(array_lengthof( // expected-error{{no matching function for call to 'array_lengthof'}}
+                          Description<int*>::data // expected-note{{in instantiation of static data member 'PR7985::Description<int *>::data' requested here}}
+                          ));
+
+    array_lengthof(Description<float*>::data); // expected-error{{no matching function for call to 'array_lengthof'}}
   }
 }





More information about the cfe-commits mailing list