Unify the BlockDeclRefExpr and DeclRefExpr paths so that

we correctly emit loads of BlockDeclRefExprs even when they
don't qualify as ODR-uses.  I think I'm adequately convinced
that BlockDeclRefExpr can die.

llvm-svn: 152479
This commit is contained in:
John McCall
2012-03-10 03:05:10 +00:00
parent b785a6691b
commit 7133505936
6 changed files with 285 additions and 52 deletions

View File

@@ -109,7 +109,28 @@ public:
}
// l-values.
void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); }
void emitDeclRef(ValueDecl *VD, Expr *refExpr) {
// 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 (CodeGenFunction::ConstantEmission result
= CGF.tryEmitAsConstant(VD, refExpr)) {
EmitFinalDestCopy(refExpr, result.getReferenceLValue(CGF, refExpr));
return;
}
}
EmitAggLoadOfLValue(refExpr);
}
void VisitDeclRefExpr(DeclRefExpr *E) { emitDeclRef(E->getDecl(), E); }
void VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
emitDeclRef(E->getDecl(), E);
}
void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
@@ -117,9 +138,6 @@ public:
void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
EmitAggLoadOfLValue(E);
}
void VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) {
EmitAggLoadOfLValue(E);
}
void VisitPredefinedExpr(const PredefinedExpr *E) {
EmitAggLoadOfLValue(E);
}