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) : ¬Nested);
+ 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);