diff options
| author | Anders Carlsson <andersca@mac.com> | 2009-09-15 16:35:24 +0000 |
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2009-09-15 16:35:24 +0000 |
| commit | 1450adbbf966d7680432611a7780b02ba4c6e87d (patch) | |
| tree | dc1ae6a67882189e873f8a0f8b998923d7b707f9 /clang | |
| parent | be999390ebc77f1972f6743696f14b5c34798ce5 (diff) | |
| download | bcm5719-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.cpp | 43 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 2 |
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, |

