]> granicus.if.org Git - clang/commitdiff
Centralize and complete the computation of value- and type-dependence for DeclRefExprs
authorDouglas Gregor <dgregor@apple.com>
Mon, 23 Nov 2009 11:41:28 +0000 (11:41 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 23 Nov 2009 11:41:28 +0000 (11:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89649 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
include/clang/AST/ExprCXX.h
lib/AST/DeclTemplate.cpp
lib/AST/Expr.cpp
lib/CodeGen/CGBlocks.cpp
lib/Frontend/RewriteObjC.cpp
lib/Sema/Sema.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaOverload.cpp
lib/Sema/SemaTemplateInstantiate.cpp
lib/Sema/TreeTransform.h

index 47404fa7bfb678e1ddbeaeeaf8e1806230df903d..4b13c556cbf38cbc966d313b93167d61aa52c701 100644 (file)
@@ -429,26 +429,23 @@ class DeclRefExpr : public Expr {
   DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
               NamedDecl *D, SourceLocation NameLoc,
               const TemplateArgumentListInfo *TemplateArgs,
-              QualType T, bool TD, bool VD);
+              QualType T);
   
 protected:
-  // FIXME: Eventually, this constructor will go away and all subclasses
-  // will have to provide the type- and value-dependent flags.
-  DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
-    Expr(SC, t), DecoratedD(d, 0), Loc(l) {}
+  /// \brief Computes the type- and value-dependence flags for this
+  /// declaration reference expression.
+  void computeDependence();
 
-  DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l, bool TD,
-              bool VD) :
-    Expr(SC, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
+  DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
+    Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) {
+    computeDependence();
+  }
 
 public:
-  // FIXME: Eventually, this constructor will go away and all clients
-  // will have to provide the type- and value-dependent flags.
   DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l) :
-    Expr(DeclRefExprClass, t), DecoratedD(d, 0), Loc(l) {}
-
-  DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l, bool TD, bool VD) :
-    Expr(DeclRefExprClass, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
+    Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) {
+    computeDependence();
+  }
 
   /// \brief Construct an empty declaration reference expression.
   explicit DeclRefExpr(EmptyShell Empty)
@@ -459,15 +456,8 @@ public:
                              SourceRange QualifierRange,
                              NamedDecl *D,
                              SourceLocation NameLoc,
-                             QualType T, bool TD, bool VD);
-  
-  static DeclRefExpr *Create(ASTContext &Context,
-                             NestedNameSpecifier *Qualifier,
-                             SourceRange QualifierRange,
-                             NamedDecl *D,
-                             SourceLocation NameLoc,
-                             const TemplateArgumentListInfo *TemplateArgs,
-                             QualType T, bool TD, bool VD);
+                             QualType T,
+                             const TemplateArgumentListInfo *TemplateArgs = 0);
   
   NamedDecl *getDecl() { return DecoratedD.getPointer(); }
   const NamedDecl *getDecl() const { return DecoratedD.getPointer(); }
index 055926f03d746a0ac325487a7e0de1d4922d7dbe..4823c0bca472d74c329b2e1cb1d2828d403d4eea 100644 (file)
@@ -681,10 +681,7 @@ public:
   CXXConditionDeclExpr(SourceLocation startLoc,
                        SourceLocation eqLoc, VarDecl *var)
     : DeclRefExpr(CXXConditionDeclExprClass, var,
-                  var->getType().getNonReferenceType(), startLoc,
-                  var->getType()->isDependentType(),
-                  /*FIXME:integral constant?*/
-                    var->getType()->isDependentType()) {}
+                  var->getType().getNonReferenceType(), startLoc) {}
 
   SourceLocation getStartLoc() const { return getLocation(); }
 
index 2d2851036c1eb566f0ea514d6304711efb2a8c0a..902339e1efcf08456c5bc1e80ff3d8aa4635c5e1 100644 (file)
@@ -214,9 +214,7 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
     } else if (NonTypeTemplateParmDecl *NTTP =
                  dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
       Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
-                                          NTTP->getLocation(),
-                                          NTTP->getType()->isDependentType(),
-                                          /*Value-dependent=*/true);
+                                          NTTP->getLocation());
       TemplateArgs.push_back(TemplateArgument(E));
     } else {
       TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
index 61492694fcb420419c5e1dc8858c461a8f55ea19..7c80f04be261a427e02a2591a5fba85ab855ae2a 100644 (file)
@@ -56,12 +56,64 @@ std::size_t ExplicitTemplateArgumentList::sizeFor(
          sizeof(TemplateArgumentLoc) * Info.size();
 }
 
+void DeclRefExpr::computeDependence() {
+  TypeDependent = false;
+  ValueDependent = false;
+  
+  NamedDecl *D = getDecl();
+
+  // (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:
+
+  //  (TD)  - an identifier that was declared with dependent type
+  //  (VD)  - a name declared with a dependent type,
+  if (getType()->isDependentType()) {
+    TypeDependent = true;
+    ValueDependent = true;
+  }
+  //  (TD)  - a conversion-function-id that specifies a dependent type
+  else if (D->getDeclName().getNameKind() 
+                               == DeclarationName::CXXConversionFunctionName &&
+           D->getDeclName().getCXXNameType()->isDependentType()) {
+    TypeDependent = true;
+    ValueDependent = true;
+  }
+  //  (TD)  - a template-id that is dependent,
+  else if (hasExplicitTemplateArgumentList() && 
+           TemplateSpecializationType::anyDependentTemplateArguments(
+                                                       getTemplateArgs(), 
+                                                       getNumTemplateArgs())) {
+    TypeDependent = true;
+    ValueDependent = true;
+  }
+  //  (VD)  - the name of a non-type template parameter,
+  else if (isa<NonTypeTemplateParmDecl>(D))
+    ValueDependent = true;
+  //  (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() &&
+        Var->getType().getCVRQualifiers() == Qualifiers::Const &&
+        Var->getInit() &&
+        Var->getInit()->isValueDependent())
+    ValueDependent = true;
+  }
+  //  (TD)  - a nested-name-specifier or a qualified-id that names a
+  //          member of an unknown specialization.
+  //        (handled by DependentScopeDeclRefExpr)
+}
+
 DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, 
                          SourceRange QualifierRange,
                          NamedDecl *D, SourceLocation NameLoc,
                          const TemplateArgumentListInfo *TemplateArgs,
-                         QualType T, bool TD, bool VD)
-  : Expr(DeclRefExprClass, T, TD, VD),
+                         QualType T)
+  : Expr(DeclRefExprClass, T, false, false),
     DecoratedD(D,
                (Qualifier? HasQualifierFlag : 0) |
                (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)),
@@ -75,16 +127,8 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
       
   if (TemplateArgs)
     getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
-}
 
-DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
-                                 NestedNameSpecifier *Qualifier,
-                                 SourceRange QualifierRange,
-                                 NamedDecl *D,
-                                 SourceLocation NameLoc,
-                                 QualType T, bool TD, bool VD) {
-  return Create(Context, Qualifier, QualifierRange, D, NameLoc,
-                /*TemplateArgs*/ 0, T, TD, VD);
+  computeDependence();
 }
 
 DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
@@ -92,8 +136,8 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
                                  SourceRange QualifierRange,
                                  NamedDecl *D,
                                  SourceLocation NameLoc,
-                                 const TemplateArgumentListInfo *TemplateArgs,
-                                 QualType T, bool TD, bool VD) {
+                                 QualType T,
+                                 const TemplateArgumentListInfo *TemplateArgs) {
   std::size_t Size = sizeof(DeclRefExpr);
   if (Qualifier != 0)
     Size += sizeof(NameQualifier);
@@ -103,7 +147,7 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
   
   void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
   return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
-                               TemplateArgs, T, TD, VD);
+                               TemplateArgs, T);
 }
 
 SourceRange DeclRefExpr::getSourceRange() const {
index bc9eb67674ff6cc67ca0b7d9d1f09b6c440a0b94..e989e4a9b7791f29db0e8cf4f55203d62a439228 100644 (file)
@@ -297,8 +297,8 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
             continue;
           } else
             E = new (getContext()) DeclRefExpr (cast<NamedDecl>(VD),
-                                                VD->getType(), SourceLocation(),
-                                                false, false);
+                                                VD->getType(), 
+                                                SourceLocation());
         }
         if (BDRE->isByRef()) {
           NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF |
@@ -836,7 +836,7 @@ uint64_t BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) {
                                          0, QualType(PadTy), 0, VarDecl::None);
     Expr *E;
     E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(),
-                                       SourceLocation(), false, false);
+                                       SourceLocation());
     BlockDeclRefDecls.push_back(E);
   }
   BlockDeclRefDecls.push_back(BDRE);
index 06955e5c30b6b3b2e2040c6859c833d8d794de98..710fa55b69bfdbffb8bfe950c6aa30672f8d59ff 100644 (file)
@@ -2627,7 +2627,7 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
   std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
   IdentifierInfo *ID = &Context->Idents.get(Name);
   VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
-                          ID, QualType()/*UNUSED*/, 0, VarDecl::Extern);
+                                ID, getProtocolType(), 0, VarDecl::Extern);
   DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation());
   Expr *DerefExpr = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
                              Context->getPointerType(DRE->getType()),
index 472efc48cb9e096d3e396dba0f5ce2ece0ed4566..cff346b9dfc91799dce42f3a832ced5639d59f8b 100644 (file)
@@ -1391,8 +1391,7 @@ public:
                                              bool IsAddressOfOperand);
   
   OwningExprResult BuildDeclRefExpr(NamedDecl *D, QualType Ty,
-                                    SourceLocation Loc, bool TypeDependent,
-                                    bool ValueDependent,
+                                    SourceLocation Loc,
                                     const CXXScopeSpec *SS = 0);
   VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
                                     llvm::SmallVectorImpl<FieldDecl *> &Path);
index 42b49c5d0b5ee16864c5546abacc76d687f44f6b..1506fbaf6067cebaa940075f9fd2968e01c3e7de 100644 (file)
@@ -415,7 +415,6 @@ static bool ShouldSnapshotBlockValueReference(BlockSemaInfo *CurBlock,
 /// BuildDeclRefExpr - Build a DeclRefExpr.
 Sema::OwningExprResult
 Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
-                       bool TypeDependent, bool ValueDependent,
                        const CXXScopeSpec *SS) {
   assert(!isa<OverloadedFunctionDecl>(D));
 
@@ -445,8 +444,7 @@ Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
   return Owned(DeclRefExpr::Create(Context, 
                               SS? (NestedNameSpecifier *)SS->getScopeRep() : 0, 
                                    SS? SS->getRange() : SourceRange(), 
-                                   D, Loc, 
-                                   Ty, TypeDependent, ValueDependent));
+                                   D, Loc, Ty));
 }
 
 /// getObjectForAnonymousRecordDecl - Retrieve the (unnamed) field or
@@ -842,7 +840,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
       QualType NoProtoType = T;
       if (const FunctionProtoType *Proto = T->getAs<FunctionProtoType>())
         NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
-      return BuildDeclRefExpr(Func, NoProtoType, Loc, false, false, SS);
+      return BuildDeclRefExpr(Func, NoProtoType, Loc, SS);
     }
   }
 
@@ -1139,56 +1137,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
   // If this reference is not in a block or if the referenced variable is
   // within the block, create a normal DeclRefExpr.
 
-  bool TypeDependent = false;
-  bool ValueDependent = false;
-  if (getLangOptions().CPlusPlus) {
-    // C++ [temp.dep.expr]p3:
-    //   An id-expression is type-dependent if it contains:
-    //     - an identifier that was declared with a dependent type,
-    if (VD->getType()->isDependentType())
-      TypeDependent = true;
-    //     - FIXME: a template-id that is dependent,
-    //     - a conversion-function-id that specifies a dependent type,
-    else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
-             Name.getCXXNameType()->isDependentType())
-      TypeDependent = true;
-    //     - a nested-name-specifier that contains a class-name that
-    //       names a dependent type.
-    else {
-      for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) {
-        // FIXME: could stop early at namespace scope.
-        if (DC->isRecord()) {
-          CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
-          if (Context.getTypeDeclType(Record)->isDependentType()) {
-            TypeDependent = true;
-            break;
-          }
-        }
-      }
-    }
-
-    // C++ [temp.dep.constexpr]p2:
-    //
-    //   An identifier is value-dependent if it is:
-    //     - a name declared with a dependent type,
-    if (TypeDependent)
-      ValueDependent = true;
-    //     - the name of a non-type template parameter,
-    else if (isa<NonTypeTemplateParmDecl>(VD))
-      ValueDependent = true;
-    //    - a constant with integral or enumeration type and is
-    //      initialized with an expression that is value-dependent
-    else if (const VarDecl *Dcl = dyn_cast<VarDecl>(VD)) {
-      if (Context.getCanonicalType(Dcl->getType()).getCVRQualifiers()
-          == Qualifiers::Const &&
-          Dcl->getInit()) {
-        ValueDependent = Dcl->getInit()->isValueDependent();
-      }
-    }
-  }
-
-  return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc,
-                          TypeDependent, ValueDependent, SS);
+  return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, SS);
 }
 
 Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
index 591144d81d797dac4ea08f83fd276e220b3711c7..8a009e57f6de64d4c5d0cfd7ac62102b13f6c03b 100644 (file)
@@ -5647,11 +5647,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
                                DRE->getQualifierRange(),
                                Fn,
                                DRE->getLocation(),
-                               (DRE->hasExplicitTemplateArgumentList()
-                                 ? &TemplateArgs : 0),
                                Fn->getType(),
-                               DRE->isTypeDependent(),
-                               DRE->isValueDependent());
+                               (DRE->hasExplicitTemplateArgumentList()
+                                  ? &TemplateArgs : 0));
   } 
 
   if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
@@ -5660,9 +5658,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
                                ULE->getQualifierRange(),
                                Fn,
                                ULE->getNameLoc(),
-                               Fn->getType(),
-                               Fn->getType()->isDependentType(),
-                               false);
+                               Fn->getType());
   }
 
   
@@ -5699,9 +5695,8 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
     return DeclRefExpr::Create(Context, 
                                TID->getQualifier(), TID->getQualifierRange(),
                                Fn, TID->getTemplateNameLoc(), 
-                               &TemplateArgs,
-                               Fn->getType(), 
-                               /*FIXME?*/false, /*FIXME?*/false);    
+                               Fn->getType(),
+                               &TemplateArgs);
   } 
   
   assert(false && "Invalid reference to overloaded function");
index 3c5c239739b4fc63a9aa21074fca2d4ac92d67eb..502c151f4ef4a651e8fe04a68bf8aad5b4d3f192 100644 (file)
@@ -790,7 +790,6 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E,
               = SemaRef.BuildDeclRefExpr(VD, 
                                          VD->getType().getNonReferenceType(), 
                                          E->getLocation(), 
-                                         /*FIXME:*/false, /*FIXME:*/false,
                                          &SS);
             if (RefExpr.isInvalid())
               return SemaRef.ExprError();
@@ -802,8 +801,7 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E,
         }
 
         return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
-                                        E->getLocation(),
-                                        /*FIXME:*/false, /*FIXME:*/false);
+                                        E->getLocation());
       }
 
       assert(Arg.getKind() == TemplateArgument::Integral);
index dcc0d184a1411a2c233ae80c0ce386651deadd0a..ecac31a3e7acab520d3748d9fe07494877673f46 100644 (file)
@@ -1643,7 +1643,7 @@ public:
     FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
     Expr *Callee
       = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
-                                          BuiltinLoc, false, false);
+                                          BuiltinLoc);
     SemaRef.UsualUnaryConversions(Callee);
 
     // Build the CallExpr