]> granicus.if.org Git - clang/commitdiff
Improve the instantiation of static data members in
authorDouglas Gregor <dgregor@apple.com>
Fri, 3 Jun 2011 14:28:43 +0000 (14:28 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 3 Jun 2011 14:28:43 +0000 (14:28 +0000)
Sema::RequireCompleteExprType() a bit more, setting the point of
instantiation if needed, and skipping explicit specializations entirely.

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

lib/Sema/SemaType.cpp
test/SemaTemplate/instantiate-init.cpp

index 02bcb2b89e1583e1b7a07377480dc8643f782477..3c4e09ae8690e895582a8fb95140ecd32075f22f 100644 (file)
@@ -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 @@ bool Sema::RequireCompleteExprType(Expr *E, const PartialDiagnostic &PD,
       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
index ce2c1633b141f24c514b07ed15437385e299cfec..f0ca9a5b21e9ebe00ed328086e839d012a48d2ce 100644 (file)
@@ -78,21 +78,32 @@ 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>(); }
+  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'}}
   }
 }