aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp41
1 files changed, 18 insertions, 23 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 3275327..80233b5 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -679,9 +679,6 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
"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 @@ static ConstantEmissionKind checkVarTypeForConstantEmission(QualType type) {
/// 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 @@ CodeGenFunction::tryEmitAsConstant(ValueDecl *value, Expr *refExpr) {
}
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 @@ CodeGenFunction::tryEmitAsConstant(ValueDecl *value, Expr *refExpr) {
// 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 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
}
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 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
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)