Remove BlockDeclRefExpr and introduce a bit on DeclRefExpr to
track whether the referenced declaration comes from an enclosing
local context.  I'm amenable to suggestions about the exact meaning
of this bit.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152491 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 1b35fa0..8e280e6 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -753,16 +753,12 @@
 
       // We use one of these or the other depending on whether the
       // reference is nested.
-      DeclRefExpr notNested(const_cast<VarDecl*>(variable), type, VK_LValue,
-                            SourceLocation());
-      BlockDeclRefExpr nested(const_cast<VarDecl*>(variable), type,
-                              VK_LValue, SourceLocation(), /*byref*/ false);
-
-      Expr *declRef = 
-        (ci->isNested() ? static_cast<Expr*>(&nested) : &notNested);
+      DeclRefExpr declRef(const_cast<VarDecl*>(variable),
+                          /*refersToEnclosing*/ ci->isNested(), type,
+                          VK_LValue, SourceLocation());
 
       ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,
-                           declRef, VK_RValue);
+                           &declRef, VK_RValue);
       EmitExprAsInit(&l2r, &blockFieldPseudoVar,
                      MakeAddrLValue(blockField, type,
                                     getContext().getDeclAlign(variable)),
@@ -1107,7 +1103,7 @@
     LocalDeclMap[variable] = alloca;
   }
 
-  // Save a spot to insert the debug information for all the BlockDeclRefDecls.
+  // Save a spot to insert the debug information for all the DeclRefExprs.
   llvm::BasicBlock *entry = Builder.GetInsertBlock();
   llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
   --entry_ptr;
@@ -1124,7 +1120,7 @@
   ++entry_ptr;
   Builder.SetInsertPoint(entry, entry_ptr);
 
-  // Emit debug information for all the BlockDeclRefDecls.
+  // Emit debug information for all the DeclRefExprs.
   // FIXME: also for 'this'
   if (CGDebugInfo *DI = getDebugInfo()) {
     for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 06a3343..a3437f7 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -394,8 +394,8 @@
     void Emit(CodeGenFunction &CGF, Flags flags) {
       // Compute the address of the local variable, in case it's a
       // byref or something.
-      DeclRefExpr DRE(const_cast<VarDecl*>(&Var), Var.getType(), VK_LValue,
-                      SourceLocation());
+      DeclRefExpr DRE(const_cast<VarDecl*>(&Var), false,
+                      Var.getType(), VK_LValue, SourceLocation());
       llvm::Value *value = CGF.EmitLoadOfScalar(CGF.EmitDeclRefLValue(&DRE));
       CGF.EmitExtendGCLifetime(value);
     }
@@ -411,8 +411,8 @@
       : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
 
     void Emit(CodeGenFunction &CGF, Flags flags) {
-      DeclRefExpr DRE(const_cast<VarDecl*>(&Var), Var.getType(), VK_LValue,
-                      SourceLocation());
+      DeclRefExpr DRE(const_cast<VarDecl*>(&Var), false,
+                      Var.getType(), VK_LValue, SourceLocation());
       // Compute the address of the local variable, in case it's a byref
       // or something.
       llvm::Value *Addr = CGF.EmitDeclRefLValue(&DRE).getAddress();
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 3275327..80233b5 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -679,9 +679,6 @@
            "Only single-element init list can be lvalue.");
     return EmitLValue(cast<InitListExpr>(E)->getInit(0));
 
-  case Expr::BlockDeclRefExprClass:
-    return EmitBlockDeclRefLValue(cast<BlockDeclRefExpr>(E));
-
   case Expr::CXXTemporaryObjectExprClass:
   case Expr::CXXConstructExprClass:
     return EmitCXXConstructLValue(cast<CXXConstructExpr>(E));
@@ -796,7 +793,9 @@
 /// in a block or lambda, which means const int variables or constexpr
 /// literals or similar.
 CodeGenFunction::ConstantEmission
-CodeGenFunction::tryEmitAsConstant(ValueDecl *value, Expr *refExpr) {
+CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
+  ValueDecl *value = refExpr->getDecl();
+
   // The value needs to be an enum constant or a constant variable.
   ConstantEmissionKind CEK;
   if (isa<ParmVarDecl>(value)) {
@@ -810,25 +809,19 @@
   }
   if (CEK == CEK_None) return ConstantEmission();
 
-  // We evaluate use an on-stack DeclRefExpr because the constant
-  // evaluator (quite reasonably) ignores BlockDeclRefExprs.
-  DeclRefExpr stackRef(value, refExpr->getType(), refExpr->getValueKind(),
-                       refExpr->getExprLoc());
-
-  // If it's okay to evaluate as a 
   Expr::EvalResult result;
   bool resultIsReference;
   QualType resultType;
 
   // It's best to evaluate all the way as an r-value if that's permitted.
   if (CEK != CEK_AsReferenceOnly &&
-      stackRef.EvaluateAsRValue(result, getContext())) {
+      refExpr->EvaluateAsRValue(result, getContext())) {
     resultIsReference = false;
     resultType = refExpr->getType();
 
   // Otherwise, try to evaluate as an l-value.
   } else if (CEK != CEK_AsValueOnly &&
-             stackRef.EvaluateAsLValue(result, getContext())) {
+             refExpr->EvaluateAsLValue(result, getContext())) {
     resultIsReference = true;
     resultType = value->getType();
 
@@ -848,10 +841,10 @@
   // This should probably fire even for 
   if (isa<VarDecl>(value)) {
     if (!getContext().DeclMustBeEmitted(cast<VarDecl>(value)))
-      EmitDeclRefExprDbgValue(&stackRef, C);
+      EmitDeclRefExprDbgValue(refExpr, C);
   } else {
     assert(isa<EnumConstantDecl>(value));
-    EmitDeclRefExprDbgValue(&stackRef, C);
+    EmitDeclRefExprDbgValue(refExpr, C);
   }
 
   // If we emitted a reference constant, we need to dereference that.
@@ -1499,27 +1492,34 @@
   }
 
   if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
-    
     // Check if this is a global variable.
     if (VD->hasExternalStorage() || VD->isFileVarDecl()) 
       return EmitGlobalVarDeclLValue(*this, E, VD);
 
+    bool isBlockVariable = VD->hasAttr<BlocksAttr>();
+
     bool NonGCable = VD->hasLocalStorage() &&
                      !VD->getType()->isReferenceType() &&
-                     !VD->hasAttr<BlocksAttr>();
+                     !isBlockVariable;
 
     llvm::Value *V = LocalDeclMap[VD];
     if (!V && VD->isStaticLocal()) 
       V = CGM.getStaticLocalDeclAddress(VD);
 
     // Use special handling for lambdas.
-    if (!V)
+    if (!V) {
       if (FieldDecl *FD = LambdaCaptureFields.lookup(VD))
         return EmitLValueForField(CXXABIThisValue, FD, 0);
 
+      assert(isa<BlockDecl>(CurCodeDecl) && E->refersToEnclosingLocal());
+      CharUnits alignment = getContext().getDeclAlign(VD);
+      return MakeAddrLValue(GetAddrOfBlockDecl(VD, isBlockVariable),
+                            E->getType(), alignment);
+    }
+
     assert(V && "DeclRefExpr not entered in LocalDeclMap?");
 
-    if (VD->hasAttr<BlocksAttr>())
+    if (isBlockVariable)
       V = BuildBlockByrefAddress(V, VD);
 
     LValue LV;
@@ -1546,11 +1546,6 @@
   llvm_unreachable("Unhandled DeclRefExpr");
 }
 
-LValue CodeGenFunction::EmitBlockDeclRefLValue(const BlockDeclRefExpr *E) {
-  CharUnits Alignment = getContext().getDeclAlign(E->getDecl());
-  return MakeAddrLValue(GetAddrOfBlockDecl(E), E->getType(), Alignment);
-}
-
 LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
   // __extension__ doesn't affect lvalue-ness.
   if (E->getOpcode() == UO_Extension)
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index f7c640a..3e8ae06 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -109,26 +109,22 @@
   }
 
   // l-values.
-  void emitDeclRef(ValueDecl *VD, Expr *refExpr) {
+  void VisitDeclRefExpr(DeclRefExpr *E) {
     // For aggregates, we should always be able to emit the variable
     // as an l-value unless it's a reference.  This is due to the fact
     // that we can't actually ever see a normal l2r conversion on an
     // aggregate in C++, and in C there's no language standard
     // actively preventing us from listing variables in the captures
     // list of a block.
-    if (VD->getType()->isReferenceType()) {
+    if (E->getDecl()->getType()->isReferenceType()) {
       if (CodeGenFunction::ConstantEmission result
-            = CGF.tryEmitAsConstant(VD, refExpr)) {
-        EmitFinalDestCopy(refExpr, result.getReferenceLValue(CGF, refExpr));
+            = CGF.tryEmitAsConstant(E)) {
+        EmitFinalDestCopy(E, result.getReferenceLValue(CGF, E));
         return;
       }
     }
 
-    EmitAggLoadOfLValue(refExpr);
-  }
-  void VisitDeclRefExpr(DeclRefExpr *E) { emitDeclRef(E->getDecl(), E); }
-  void VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
-    emitDeclRef(E->getDecl(), E);
+    EmitAggLoadOfLValue(E);
   }
 
   void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp
index 7be8844..c5b705f 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -111,23 +111,16 @@
   }
 
   // l-values.
-  ComplexPairTy emitDeclRef(ValueDecl *VD, Expr *refExpr) {
-    if (CodeGenFunction::ConstantEmission result
-          = CGF.tryEmitAsConstant(VD, refExpr)) {
+  ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) {
+    if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {
       if (result.isReference())
-        return EmitLoadOfLValue(result.getReferenceLValue(CGF, refExpr));
+        return EmitLoadOfLValue(result.getReferenceLValue(CGF, E));
 
       llvm::ConstantStruct *pair =
         cast<llvm::ConstantStruct>(result.getValue());
       return ComplexPairTy(pair->getOperand(0), pair->getOperand(1));
     }
-    return EmitLoadOfLValue(refExpr);
-  }
-  ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) {
-    return emitDeclRef(E->getDecl(), E);
-  }
-  ComplexPairTy VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
-    return emitDeclRef(E->getDecl(), E);
+    return EmitLoadOfLValue(E);
   }
   ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
     return EmitLoadOfLValue(E);
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index a6ba798..d3cbf00 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -213,20 +213,13 @@
   }
 
   // l-values.
-  Value *emitDeclRef(ValueDecl *VD, Expr *refExpr) {
-    if (CodeGenFunction::ConstantEmission result
-          = CGF.tryEmitAsConstant(VD, refExpr)) {
+  Value *VisitDeclRefExpr(DeclRefExpr *E) {
+    if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {
       if (result.isReference())
-        return EmitLoadOfLValue(result.getReferenceLValue(CGF, refExpr));
+        return EmitLoadOfLValue(result.getReferenceLValue(CGF, E));
       return result.getValue();
     }
-    return EmitLoadOfLValue(refExpr);
-  }
-  Value *VisitDeclRefExpr(DeclRefExpr *E) {
-    return emitDeclRef(E->getDecl(), E);
-  }
-  Value *VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
-    return emitDeclRef(E->getDecl(), E);
+    return EmitLoadOfLValue(E);
   }
 
   Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 6ece9e8..05926014 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -931,7 +931,7 @@
 
   // The second argument is the address of the parameter variable.
   ParmVarDecl *argVar = *OMD->param_begin();
-  DeclRefExpr argRef(argVar, argVar->getType().getNonReferenceType(), 
+  DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(), 
                      VK_LValue, SourceLocation());
   llvm::Value *argAddr = CGF.EmitLValue(&argRef).getAddress();
   argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
@@ -976,7 +976,7 @@
   
   // The second argument is the address of the parameter variable.
   ParmVarDecl *argVar = *OMD->param_begin();
-  DeclRefExpr argRef(argVar, argVar->getType().getNonReferenceType(), 
+  DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(), 
                      VK_LValue, SourceLocation());
   llvm::Value *argAddr = CGF.EmitLValue(&argRef).getAddress();
   argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
@@ -1163,7 +1163,8 @@
 
   // Otherwise, fake up some ASTs and emit a normal assignment.
   ValueDecl *selfDecl = setterMethod->getSelfDecl();
-  DeclRefExpr self(selfDecl, selfDecl->getType(), VK_LValue, SourceLocation());
+  DeclRefExpr self(selfDecl, false, selfDecl->getType(),
+                   VK_LValue, SourceLocation());
   ImplicitCastExpr selfLoad(ImplicitCastExpr::OnStack,
                             selfDecl->getType(), CK_LValueToRValue, &self,
                             VK_RValue);
@@ -1172,7 +1173,7 @@
 
   ParmVarDecl *argDecl = *setterMethod->param_begin();
   QualType argType = argDecl->getType().getNonReferenceType();
-  DeclRefExpr arg(argDecl, argType, VK_LValue, SourceLocation());
+  DeclRefExpr arg(argDecl, false, argType, VK_LValue, SourceLocation());
   ImplicitCastExpr argLoad(ImplicitCastExpr::OnStack,
                            argType.getUnqualifiedType(), CK_LValueToRValue,
                            &arg, VK_RValue);
@@ -1525,7 +1526,7 @@
     EmitAutoVarInit(variable);
 
     const VarDecl* D = cast<VarDecl>(SD->getSingleDecl());
-    DeclRefExpr tempDRE(const_cast<VarDecl*>(D), D->getType(),
+    DeclRefExpr tempDRE(const_cast<VarDecl*>(D), false, D->getType(),
                         VK_LValue, SourceLocation());
     elementLValue = EmitLValue(&tempDRE);
     elementType = D->getType();
@@ -2817,28 +2818,23 @@
   
   StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
   
-  DeclRefExpr *DstExpr = 
-    new (C) DeclRefExpr(&dstDecl, DestTy,
-                              VK_RValue, SourceLocation());
+  DeclRefExpr DstExpr(&dstDecl, false, DestTy,
+                      VK_RValue, SourceLocation());
+  UnaryOperator DST(&DstExpr, UO_Deref, DestTy->getPointeeType(),
+                    VK_LValue, OK_Ordinary, SourceLocation());
   
-  Expr* DST = new (C) UnaryOperator(DstExpr, UO_Deref, DestTy->getPointeeType(),
-                                    VK_LValue, OK_Ordinary, SourceLocation());
+  DeclRefExpr SrcExpr(&srcDecl, false, SrcTy,
+                      VK_RValue, SourceLocation());
+  UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(),
+                    VK_LValue, OK_Ordinary, SourceLocation());
   
-  DeclRefExpr *SrcExpr = 
-    new (C) DeclRefExpr(&srcDecl, SrcTy,
-                        VK_RValue, SourceLocation());
-  
-  Expr* SRC = new (C) UnaryOperator(SrcExpr, UO_Deref, SrcTy->getPointeeType(),
-                                    VK_LValue, OK_Ordinary, SourceLocation());
-  
-  Expr *Args[2] = { DST, SRC };
+  Expr *Args[2] = { &DST, &SRC };
   CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment());
-  CXXOperatorCallExpr *TheCall =
-    new (C) CXXOperatorCallExpr(C, OO_Equal, CalleeExp->getCallee(),
-                                Args, 2, DestTy->getPointeeType(), 
-                                VK_LValue, SourceLocation());
-
-  EmitStmt(TheCall);
+  CXXOperatorCallExpr TheCall(C, OO_Equal, CalleeExp->getCallee(),
+                              Args, 2, DestTy->getPointeeType(), 
+                              VK_LValue, SourceLocation());
+  
+  EmitStmt(&TheCall);
 
   FinishFunction();
   HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
@@ -2907,18 +2903,17 @@
   
   StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
   
-  DeclRefExpr *SrcExpr = 
-  new (C) DeclRefExpr(&srcDecl, SrcTy,
+  DeclRefExpr SrcExpr(&srcDecl, false, SrcTy,
                       VK_RValue, SourceLocation());
   
-  Expr* SRC = new (C) UnaryOperator(SrcExpr, UO_Deref, SrcTy->getPointeeType(),
-                                    VK_LValue, OK_Ordinary, SourceLocation());
+  UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(),
+                    VK_LValue, OK_Ordinary, SourceLocation());
   
   CXXConstructExpr *CXXConstExpr = 
     cast<CXXConstructExpr>(PID->getGetterCXXConstructor());
   
   SmallVector<Expr*, 4> ConstructorArgs;
-  ConstructorArgs.push_back(SRC);
+  ConstructorArgs.push_back(&SRC);
   CXXConstructExpr::arg_iterator A = CXXConstExpr->arg_begin();
   ++A;
   
@@ -2936,11 +2931,10 @@
                              CXXConstExpr->requiresZeroInitialization(),
                              CXXConstExpr->getConstructionKind(), SourceRange());
   
-  DeclRefExpr *DstExpr = 
-    new (C) DeclRefExpr(&dstDecl, DestTy,
-                        VK_RValue, SourceLocation());
+  DeclRefExpr DstExpr(&dstDecl, false, DestTy,
+                      VK_RValue, SourceLocation());
   
-  RValue DV = EmitAnyExpr(DstExpr);
+  RValue DV = EmitAnyExpr(&DstExpr);
   CharUnits Alignment = getContext().getTypeAlignInChars(TheCXXConstructExpr->getType());
   EmitAggExpr(TheCXXConstructExpr, 
               AggValueSlot::forAddr(DV.getScalarVal(), Alignment, Qualifiers(),
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index aeeb18c..4be5beb 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -1359,10 +1359,7 @@
   }
 
   void AllocateBlockCXXThisPointer(const CXXThisExpr *E);
-  void AllocateBlockDecl(const BlockDeclRefExpr *E);
-  llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
-    return GetAddrOfBlockDecl(E->getDecl(), E->isByRef());
-  }
+  void AllocateBlockDecl(const DeclRefExpr *E);
   llvm::Value *GetAddrOfBlockDecl(const VarDecl *var, bool ByRef);
   llvm::Type *BuildByRefType(const VarDecl *var);
 
@@ -2135,7 +2132,7 @@
     }
   };
 
-  ConstantEmission tryEmitAsConstant(ValueDecl *VD, Expr *refExpr);
+  ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr);
 
   RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e,
                                 AggValueSlot slot = AggValueSlot::ignored());
@@ -2163,8 +2160,6 @@
   LValue EmitLValueForBitfield(llvm::Value* Base, const FieldDecl* Field,
                                 unsigned CVRQualifiers);
 
-  LValue EmitBlockDeclRefLValue(const BlockDeclRefExpr *E);
-
   LValue EmitCXXConstructLValue(const CXXConstructExpr *E);
   LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E);
   LValue EmitLambdaLValue(const LambdaExpr *E);