]> granicus.if.org Git - clang/commitdiff
A DeclRefExpr that refers to a member function or a static data member
authorDouglas Gregor <dgregor@apple.com>
Tue, 11 May 2010 08:41:30 +0000 (08:41 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 11 May 2010 08:41:30 +0000 (08:41 +0000)
of the current instantiation is value-dependent. The C++ standard
fails to enumerate this case and, therefore, we missed it. Chandler
did all of the hard work of reducing the last remaining
Boost.PtrContainer failure (which had to do with static initialization
in the Serialization library) down to this simple little test.

While I'm at it, clean up the dependence rules for template arguments
that are declarations, and implement the dependence rules for template
argument packs.

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

lib/AST/Expr.cpp
lib/AST/Type.cpp
test/SemaTemplate/instantiate-member-pointers.cpp

index 626dbd67f5635e3ef47fb8d770e531c9c913c274..5d0269f702fea3998cbd113ea424be475cc60387 100644 (file)
@@ -156,13 +156,24 @@ void DeclRefExpr::computeDependence() {
   //  (VD) - a constant with integral or enumeration type and is
   //         initialized with an expression that is value-dependent.
   else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
-    if (Var->getType()->isIntegralType() &&
+    if (Var->getType()->isIntegralType() && !Var->isStaticDataMember() &&
         Var->getType().getCVRQualifiers() == Qualifiers::Const) {
       if (const Expr *Init = Var->getAnyInitializer())
         if (Init->isValueDependent())
           ValueDependent = true;
-    }
-  }
+    } 
+    // (VD) - FIXME: Missing from the standard: 
+    //      -  a member function or a static data member of the current 
+    //         instantiation
+    else if (Var->isStaticDataMember() && 
+               Var->getDeclContext()->isDependentContext())
+      ValueDependent = true;
+  } 
+  // (VD) - FIXME: Missing from the standard: 
+  //      -  a member function or a static data member of the current 
+  //         instantiation
+  else if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext())
+    ValueDependent = true;
   //  (TD)  - a nested-name-specifier or a qualified-id that names a
   //          member of an unknown specialization.
   //        (handled by DependentScopeDeclRefExpr)
index 05e7fdc49e3547d2c5d2da007eabd48223085a4a..73f0e91dab54fd5aa0de1f850b2e381b57387cbe 100644 (file)
@@ -975,6 +975,10 @@ static bool isDependent(const TemplateArgument &Arg) {
     return Arg.getAsTemplate().isDependent();
       
   case TemplateArgument::Declaration:
+    if (DeclContext *DC = dyn_cast<DeclContext>(Arg.getAsDecl()))
+      return DC->isDependentContext();
+    return Arg.getAsDecl()->getDeclContext()->isDependentContext();
+
   case TemplateArgument::Integral:
     // Never dependent
     return false;
@@ -984,7 +988,13 @@ static bool isDependent(const TemplateArgument &Arg) {
             Arg.getAsExpr()->isValueDependent());
 
   case TemplateArgument::Pack:
-    assert(0 && "FIXME: Implement!");
+    for (TemplateArgument::pack_iterator P = Arg.pack_begin(), 
+                                      PEnd = Arg.pack_end();
+         P != PEnd; ++P) {
+      if (isDependent(*P))
+        return true;
+    }
+
     return false;
   }
 
index 2308ac541b2e12ec18a57969d376f6bf7e28cd91..dca0f621705496a55a149436519641c5c9af3f2a 100644 (file)
@@ -53,3 +53,15 @@ void accept_X4(X4<Member>);
 void test_accept_X4(X4<&Y::x> x4) {
   accept_X4(x4);
 }
+
+namespace ValueDepMemberPointer {
+  template <void (*)()> struct instantiate_function {};
+  template <typename T> struct S {
+    static void instantiate();
+    typedef instantiate_function<&S::instantiate> x; // expected-note{{instantiation}}
+  };
+  template <typename T> void S<T>::instantiate() {
+    int a[(int)sizeof(T)-42]; // expected-error{{array size is negative}}
+  }
+  S<int> s; 
+}