diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-09-17 15:51:28 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-09-17 15:51:28 +0000 |
commit | af9b96828f9126d993c3e155b8453be62013b735 (patch) | |
tree | 06349dc38d2396ecb23955fb25e710f6df9addc2 | |
parent | 9fe871a80da9ba96e4731649bd197e3b7e820184 (diff) |
Patch to add IRgen support for Gnu's conditional operator
extension when missing LHS. This patch covers scalar
conditionals only. Others are wip.
(pr7726, radar 8353567).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114182 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Expr.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 36 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 5 | ||||
-rw-r--r-- | test/CodeGenCXX/gnu-conditional-scalar-ext.cpp | 11 |
4 files changed, 37 insertions, 17 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 7a9dd2cde0..f6bd17c521 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -2434,7 +2434,7 @@ public: // getTrueExpr - Return the subexpression representing the value of the ?: // expression if the condition evaluates to true. Expr *getTrueExpr() const { - return cast<Expr>(!Save ? SubExprs[LHS] : SubExprs[COND]); + return cast<Expr>(SubExprs[LHS]); } // getFalseExpr - Return the subexpression representing the value of the ?: diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index d4b1bd940c..68e0ff9497 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -105,6 +105,15 @@ public: // Visitor Methods //===--------------------------------------------------------------------===// + Value *Visit(Expr *E) { + llvm::DenseMap<const Expr *, llvm::Value *>::iterator I = + CGF.ConditionalSaveExprs.find(E); + if (I != CGF.ConditionalSaveExprs.end()) + return I->second; + + return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E); + } + Value *VisitStmt(Stmt *S) { S->dump(CGF.getContext().getSourceManager()); assert(0 && "Stmt can't have complex result type!"); @@ -112,7 +121,9 @@ public: } Value *VisitExpr(Expr *S); - Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); } + Value *VisitParenExpr(ParenExpr *PE) { + return Visit(PE->getSubExpr()); + } // Leaves. Value *VisitIntegerLiteral(const IntegerLiteral *E) { @@ -2133,17 +2144,10 @@ VisitConditionalOperator(const ConditionalOperator *E) { return Builder.CreateSelect(CondV, LHS, RHS, "cond"); } - if (!E->getLHS() && CGF.getContext().getLangOptions().CPlusPlus) { - // Does not support GNU missing condition extension in C++ yet (see #7726) - CGF.ErrorUnsupported(E, "conditional operator with missing LHS"); - return llvm::UndefValue::get(ConvertType(E->getType())); - } - llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); - Value *CondVal = 0; - + // If we don't have the GNU missing condition extension, emit a branch on bool // the normal way. if (E->getLHS()) { @@ -2154,8 +2158,12 @@ VisitConditionalOperator(const ConditionalOperator *E) { // Otherwise, for the ?: extension, evaluate the conditional and then // convert it to bool the hard way. We do this explicitly because we need // the unconverted value for the missing middle value of the ?:. - CondVal = CGF.EmitScalarExpr(E->getCond()); - + Expr *save = E->getSAVE(); + assert(save && "VisitConditionalOperator - save is null"); + // Intentianlly not doing direct assignment to ConditionalSaveExprs[save] !! + Value *SaveVal = CGF.EmitScalarExpr(save); + CGF.ConditionalSaveExprs[save] = SaveVal; + Value *CondVal = Visit(E->getCond()); // In some cases, EmitScalarConversion will delete the "CondVal" expression // if there are no extra uses (an optimization). Inhibit this by making an // extra dead use, because we're going to add a use of CondVal later. We @@ -2174,11 +2182,7 @@ VisitConditionalOperator(const ConditionalOperator *E) { CGF.EmitBlock(LHSBlock); // Handle the GNU extension for missing LHS. - Value *LHS; - if (E->getLHS()) - LHS = Visit(E->getLHS()); - else // Perform promotions, to handle cases like "short ?: int" - LHS = EmitScalarConversion(CondVal, E->getCond()->getType(), E->getType()); + Value *LHS = Visit(E->getTrueExpr()); CGF.EndConditionalBranch(); LHSBlock = Builder.GetInsertBlock(); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index a77044324a..4a5beb4baa 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -511,6 +511,11 @@ public: /// \brief A mapping from NRVO variables to the flags used to indicate /// when the NRVO has been applied to this variable. llvm::DenseMap<const VarDecl *, llvm::Value *> NRVOFlags; + + /// \brief A mapping from 'Save' expression in a conditional expression + /// to the IR for this expression. Used to implement IR gen. for Gnu + /// extension's missing LHS expression in a conditional operator expression. + llvm::DenseMap<const Expr *, llvm::Value *> ConditionalSaveExprs; EHScopeStack EHStack; diff --git a/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp b/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp new file mode 100644 index 0000000000..8c529c30e1 --- /dev/null +++ b/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s +// rdar: // 8353567 +// pr7726 + +extern "C" int printf(...); + +int main(int argc, char **argv) { +// CHECK: phi i8* [ inttoptr (i64 3735928559 to i8*), + printf("%p\n", (void *)0xdeadbeef ? : (void *)0xaaaaaa); + return 0; +} |