]> granicus.if.org Git - clang/commitdiff
Refactor the dependence computation for DeclRefExpr so that we can
authorDouglas Gregor <dgregor@apple.com>
Wed, 19 Jan 2011 21:52:31 +0000 (21:52 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 19 Jan 2011 21:52:31 +0000 (21:52 +0000)
reuse it for BlockDeclRefExpr. Do so, fixing the dependence calculate
for BlockDeclRefExpr.

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

include/clang/AST/Stmt.h
lib/AST/Expr.cpp
test/SemaObjCXX/blocks.mm

index 48871f5325e438adb31058c8b0dc1e85e7c2391f..f68f78bd449d3b39c2d9a276941e24c0e4dc1c85 100644 (file)
@@ -143,6 +143,7 @@ protected:
     friend class DeclRefExpr; // computeDependence
     friend class InitListExpr; // ctor
     friend class DesignatedInitExpr; // ctor
+    friend class BlockDeclRefExpr; // ctor
     friend class ASTStmtReader; // deserialization
     friend class CXXNewExpr; // ctor
     friend class DependentScopeDeclRefExpr; // ctor
index 9dc790256e78f2445e6d1a49782dcfa7a1b76687..c45fe3497de735ae3c05b32ab607d679d15f5455 100644 (file)
@@ -145,11 +145,14 @@ std::size_t ExplicitTemplateArgumentList::sizeFor(
   return sizeFor(Info.size());
 }
 
-void DeclRefExpr::computeDependence() {
-  ExprBits.TypeDependent = false;
-  ExprBits.ValueDependent = false;
+/// \brief Compute the type- and value-dependence of a declaration reference
+/// based on the declaration being referenced.
+static void computeDeclRefDependence(NamedDecl *D, QualType T,
+                                     bool &TypeDependent,
+                                     bool &ValueDependent) {
+  TypeDependent = false;
+  ValueDependent = false;
   
-  NamedDecl *D = getDecl();
 
   // (TD) C++ [temp.dep.expr]p3:
   //   An id-expression is type-dependent if it contains:
@@ -158,60 +161,84 @@ void DeclRefExpr::computeDependence() {
   //
   // (VD) C++ [temp.dep.constexpr]p2:
   //  An identifier is value-dependent if it is:
-
+  
   //  (TD)  - an identifier that was declared with dependent type
   //  (VD)  - a name declared with a dependent type,
-  if (getType()->isDependentType()) {
-    ExprBits.TypeDependent = true;
-    ExprBits.ValueDependent = true;
+  if (T->isDependentType()) {
+    TypeDependent = true;
+    ValueDependent = true;
+    return;
   }
+  
   //  (TD)  - a conversion-function-id that specifies a dependent type
-  else if (D->getDeclName().getNameKind() 
-                               == DeclarationName::CXXConversionFunctionName &&
+  if (D->getDeclName().getNameKind() 
+           == DeclarationName::CXXConversionFunctionName &&
            D->getDeclName().getCXXNameType()->isDependentType()) {
-    ExprBits.TypeDependent = true;
-    ExprBits.ValueDependent = true;
-  }
-  //  (TD)  - a template-id that is dependent,
-  else if (hasExplicitTemplateArgs() && 
-           TemplateSpecializationType::anyDependentTemplateArguments(
-                                                       getTemplateArgs(), 
-                                                       getNumTemplateArgs())) {
-    ExprBits.TypeDependent = true;
-    ExprBits.ValueDependent = true;
+    TypeDependent = true;
+    ValueDependent = true;
+    return;
   }
   //  (VD)  - the name of a non-type template parameter,
-  else if (isa<NonTypeTemplateParmDecl>(D))
-    ExprBits.ValueDependent = true;
+  if (isa<NonTypeTemplateParmDecl>(D)) {
+    ValueDependent = true;
+    return;
+  }
+  
   //  (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 (VarDecl *Var = dyn_cast<VarDecl>(D)) {
     if (Var->getType()->isIntegralOrEnumerationType() &&
         Var->getType().getCVRQualifiers() == Qualifiers::Const) {
       if (const Expr *Init = Var->getAnyInitializer())
         if (Init->isValueDependent())
-          ExprBits.ValueDependent = true;
+          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())
-      ExprBits.ValueDependent = true;
-  } 
+      ValueDependent = true;
+    
+    return;
+  }
+  
   // (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())
-    ExprBits.ValueDependent = true;
-  //  (TD)  - a nested-name-specifier or a qualified-id that names a
-  //          member of an unknown specialization.
-  //        (handled by DependentScopeDeclRefExpr)
-
-  // Determine whether this expression contains any unexpanded parameter
-  // packs.
+  if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext()) {
+    ValueDependent = true;
+    return;
+  }  
+}
+
+void DeclRefExpr::computeDependence() {
+  bool TypeDependent = false;
+  bool ValueDependent = false;
+  computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent);
+  
+  // (TD) C++ [temp.dep.expr]p3:
+  //   An id-expression is type-dependent if it contains:
+  //
+  // and 
+  //
+  // (VD) C++ [temp.dep.constexpr]p2:
+  //  An identifier is value-dependent if it is:
+  if (!TypeDependent && !ValueDependent &&
+      hasExplicitTemplateArgs() && 
+      TemplateSpecializationType::anyDependentTemplateArguments(
+                                                            getTemplateArgs(), 
+                                                       getNumTemplateArgs())) {
+    TypeDependent = true;
+    ValueDependent = true;
+  }
+  
+  ExprBits.TypeDependent = TypeDependent;
+  ExprBits.ValueDependent = ValueDependent;
+  
   // Is the declaration a parameter pack?
-  if (D->isParameterPack())
+  if (getDecl()->isParameterPack())
     ExprBits.ContainsUnexpandedParameterPack = true;
 }
 
@@ -2935,13 +2962,16 @@ Stmt::child_iterator ObjCMessageExpr::child_end() {
 BlockDeclRefExpr::BlockDeclRefExpr(ValueDecl *d, QualType t, ExprValueKind VK,
                                    SourceLocation l, bool ByRef, 
                                    bool constAdded, Stmt *copyConstructorVal)
-  : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary,
-         (!t.isNull() && t->isDependentType()), false,
+  : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false,
          d->isParameterPack()),
     D(d), Loc(l), IsByRef(ByRef),
     ConstQualAdded(constAdded),  CopyConstructorVal(copyConstructorVal) 
 {
-  // FIXME: Compute type/value dependence.
+  bool TypeDependent = false;
+  bool ValueDependent = false;
+  computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent);
+  ExprBits.TypeDependent = TypeDependent;
+  ExprBits.ValueDependent = ValueDependent;
 }
 
 Stmt::child_iterator BlockExpr::child_begin() { return child_iterator(); }
index d3f4d9823c171589ee53e20aa88490bc38ba0b62..0108ed4f90003855f2191738eab5e4042de24627 100644 (file)
@@ -94,3 +94,13 @@ namespace N2 {
   }
   template void test2<2>();
 }
+
+// Handle value-dependent block declaration references.
+namespace N3 {
+  template<int N> struct X { };
+
+  template<int N>
+  void f() {
+    X<N> xN = ^() { return X<N>(); }();
+  }
+}