зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
9fe871a80d
Коммит
af9b96828f
|
@ -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 ?:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
Загрузка…
Ссылка в новой задаче