summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-09-15 16:35:24 +0000
committerAnders Carlsson <andersca@mac.com>2009-09-15 16:35:24 +0000
commit1450adbbf966d7680432611a7780b02ba4c6e87d (patch)
treedc1ae6a67882189e873f8a0f8b998923d7b707f9 /clang
parentbe999390ebc77f1972f6743696f14b5c34798ce5 (diff)
downloadbcm5719-llvm-1450adbbf966d7680432611a7780b02ba4c6e87d.tar.gz
bcm5719-llvm-1450adbbf966d7680432611a7780b02ba4c6e87d.zip
Code generation of Conditional operators that are lvalues (but that aren't bitfields).
llvm-svn: 81867
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp43
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h2
2 files changed, 39 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 6ef004962cb..699d7b16ec3 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -246,7 +246,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
case Expr::CompoundLiteralExprClass:
return EmitCompoundLiteralLValue(cast<CompoundLiteralExpr>(E));
case Expr::ConditionalOperatorClass:
- return EmitConditionalOperator(cast<ConditionalOperator>(E));
+ return EmitConditionalOperatorLValue(cast<ConditionalOperator>(E));
case Expr::ChooseExprClass:
return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr(getContext()));
case Expr::ImplicitCastExprClass:
@@ -1135,10 +1135,44 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr* E){
return Result;
}
-LValue CodeGenFunction::EmitConditionalOperator(const ConditionalOperator* E) {
- if (E->isLvalue(getContext()) == Expr::LV_Valid)
- return EmitUnsupportedLValue(E, "conditional operator");
+LValue
+CodeGenFunction::EmitConditionalOperatorLValue(const ConditionalOperator* E) {
+ if (E->isLvalue(getContext()) == Expr::LV_Valid) {
+ llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
+ llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
+ llvm::BasicBlock *ContBlock = createBasicBlock("cond.end");
+
+ llvm::Value *Cond = EvaluateExprAsBool(E->getCond());
+ Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
+
+ EmitBlock(LHSBlock);
+
+ LValue LHS = EmitLValue(E->getLHS());
+ if (!LHS.isSimple())
+ return EmitUnsupportedLValue(E, "conditional operator");
+
+ llvm::Value *Temp = CreateTempAlloca(LHS.getAddress()->getType(),
+ "condtmp");
+
+ Builder.CreateStore(LHS.getAddress(), Temp);
+ EmitBranch(ContBlock);
+
+ EmitBlock(RHSBlock);
+ LValue RHS = EmitLValue(E->getRHS());
+ if (!RHS.isSimple())
+ return EmitUnsupportedLValue(E, "conditional operator");
+
+ Builder.CreateStore(RHS.getAddress(), Temp);
+ EmitBranch(ContBlock);
+ EmitBlock(ContBlock);
+
+ Temp = Builder.CreateLoad(Temp, "lv");
+ return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers(),
+ getContext().getObjCGCAttrKind(E->getType()),
+ E->getType().getAddressSpace());
+ }
+
// ?: here should be an aggregate.
assert((hasAggregateLLVMType(E->getType()) &&
!E->getType()->isAnyComplexType()) &&
@@ -1150,7 +1184,6 @@ LValue CodeGenFunction::EmitConditionalOperator(const ConditionalOperator* E) {
return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers(),
getContext().getObjCGCAttrKind(E->getType()),
E->getType().getAddressSpace());
-
}
/// EmitCastLValue - Casts are never lvalues. If a cast is needed by the code
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index cc7b0b0455a..8629b6902ea 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -794,7 +794,7 @@ public:
LValue EmitExtVectorElementExpr(const ExtVectorElementExpr *E);
LValue EmitMemberExpr(const MemberExpr *E);
LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E);
- LValue EmitConditionalOperator(const ConditionalOperator *E);
+ LValue EmitConditionalOperatorLValue(const ConditionalOperator *E);
LValue EmitCastLValue(const CastExpr *E);
llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
OpenPOWER on IntegriCloud