aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-09-17 15:51:28 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-09-17 15:51:28 +0000
commitaf9b96828f9126d993c3e155b8453be62013b735 (patch)
tree06349dc38d2396ecb23955fb25e710f6df9addc2
parent9fe871a80da9ba96e4731649bd197e3b7e820184 (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.h2
-rw-r--r--lib/CodeGen/CGExprScalar.cpp36
-rw-r--r--lib/CodeGen/CodeGenFunction.h5
-rw-r--r--test/CodeGenCXX/gnu-conditional-scalar-ext.cpp11
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;
+}