diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprComplex.cpp | 130 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 107 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 7 |
5 files changed, 196 insertions, 56 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index e965073c7f6..3d07403b07f 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -51,9 +51,10 @@ llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) { RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc, bool isAggLocVolatile, bool IgnoreResult) { if (!hasAggregateLLVMType(E->getType())) - return RValue::get(EmitScalarExpr(E)); + return RValue::get(EmitScalarExpr(E, IgnoreResult)); else if (E->getType()->isAnyComplexType()) - return RValue::getComplex(EmitComplexExpr(E)); + return RValue::getComplex(EmitComplexExpr(E, false, false, + IgnoreResult, IgnoreResult)); EmitAggExpr(E, AggLoc, isAggLocVolatile, IgnoreResult); return RValue::getAggregate(AggLoc, isAggLocVolatile); diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index d90f701758c..9ff8006e8c2 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -210,7 +210,7 @@ void AggExprEmitter::VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) { } void AggExprEmitter::VisitBinComma(const BinaryOperator *E) { - CGF.EmitAnyExpr(E->getLHS()); + CGF.EmitAnyExpr(E->getLHS(), 0, false, true); CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest); } @@ -311,6 +311,7 @@ void AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) { } void AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) { + // FIXME: Ignore result? // FIXME: Are initializers affected by volatile? if (isa<ImplicitValueInitExpr>(E)) { EmitNullInitializationToLValue(LV, E->getType()); diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 618e446bf1c..6f8dc2c8393 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -33,8 +33,17 @@ class VISIBILITY_HIDDEN ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> { CodeGenFunction &CGF; CGBuilderTy &Builder; + // True is we should ignore the value of a + bool IgnoreReal; + bool IgnoreImag; + // True if we should ignore the value of a=b + bool IgnoreRealAssign; + bool IgnoreImagAssign; public: - ComplexExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) { + ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false, + bool irn=false, bool iin=false) + : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii), + IgnoreRealAssign(irn), IgnoreImagAssign(iin) { } @@ -42,6 +51,27 @@ public: // Utilities //===--------------------------------------------------------------------===// + bool TestAndClearIgnoreReal() { + bool I = IgnoreReal; + IgnoreReal = false; + return I; + } + bool TestAndClearIgnoreImag() { + bool I = IgnoreImag; + IgnoreImag = false; + return I; + } + bool TestAndClearIgnoreRealAssign() { + bool I = IgnoreRealAssign; + IgnoreRealAssign = false; + return I; + } + bool TestAndClearIgnoreImagAssign() { + bool I = IgnoreImagAssign; + IgnoreImagAssign = false; + return I; + } + /// EmitLoadOfLValue - Given an expression with complex type that represents a /// value l-value, this method emits the address of the l-value, then loads /// and returns the result. @@ -111,6 +141,10 @@ public: } ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); } ComplexPairTy VisitUnaryPlus (const UnaryOperator *E) { + TestAndClearIgnoreReal(); + TestAndClearIgnoreImag(); + TestAndClearIgnoreRealAssign(); + TestAndClearIgnoreImagAssign(); return Visit(E->getSubExpr()); } ComplexPairTy VisitUnaryMinus (const UnaryOperator *E); @@ -206,19 +240,25 @@ ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr, llvm::SmallString<64> Name(SrcPtr->getNameStart(), SrcPtr->getNameStart()+SrcPtr->getNameLen()); - Name += ".realp"; - llvm::Value *RealPtr = Builder.CreateStructGEP(SrcPtr, 0, Name.c_str()); + llvm::Value *Real=0, *Imag=0; - Name.pop_back(); // .realp -> .real - llvm::Value *Real = Builder.CreateLoad(RealPtr, isVolatile, Name.c_str()); + if (!IgnoreReal) { + Name += ".realp"; + llvm::Value *RealPtr = Builder.CreateStructGEP(SrcPtr, 0, Name.c_str()); + + Name.pop_back(); // .realp -> .real + Real = Builder.CreateLoad(RealPtr, isVolatile, Name.c_str()); + Name.resize(Name.size()-4); // .real -> .imagp + } - Name.resize(Name.size()-4); // .real -> .imagp - Name += "imagp"; + if (!IgnoreImag) { + Name += "imagp"; - llvm::Value *ImagPtr = Builder.CreateStructGEP(SrcPtr, 1, Name.c_str()); + llvm::Value *ImagPtr = Builder.CreateStructGEP(SrcPtr, 1, Name.c_str()); - Name.pop_back(); // .imagp -> .imag - llvm::Value *Imag = Builder.CreateLoad(ImagPtr, isVolatile, Name.c_str()); + Name.pop_back(); // .imagp -> .imag + Imag = Builder.CreateLoad(ImagPtr, isVolatile, Name.c_str()); + } return ComplexPairTy(Real, Imag); } @@ -331,6 +371,10 @@ ComplexPairTy ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *E, } ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { + TestAndClearIgnoreReal(); + TestAndClearIgnoreImag(); + TestAndClearIgnoreRealAssign(); + TestAndClearIgnoreImagAssign(); ComplexPairTy Op = Visit(E->getSubExpr()); llvm::Value *ResR = Builder.CreateNeg(Op.first, "neg.r"); llvm::Value *ResI = Builder.CreateNeg(Op.second, "neg.i"); @@ -338,6 +382,10 @@ ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { } ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) { + TestAndClearIgnoreReal(); + TestAndClearIgnoreImag(); + TestAndClearIgnoreRealAssign(); + TestAndClearIgnoreImagAssign(); // ~(a+ib) = a + i*-b ComplexPairTy Op = Visit(E->getSubExpr()); llvm::Value *ResI = Builder.CreateNeg(Op.second, "conj.i"); @@ -404,6 +452,10 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { ComplexExprEmitter::BinOpInfo ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) { + TestAndClearIgnoreReal(); + TestAndClearIgnoreImag(); + TestAndClearIgnoreRealAssign(); + TestAndClearIgnoreImagAssign(); BinOpInfo Ops; Ops.LHS = Visit(E->getLHS()); Ops.RHS = Visit(E->getRHS()); @@ -416,21 +468,28 @@ ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) { ComplexPairTy ComplexExprEmitter:: EmitCompoundAssign(const CompoundAssignOperator *E, ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){ + TestAndClearIgnoreReal(); + TestAndClearIgnoreImag(); + bool ignreal = TestAndClearIgnoreRealAssign(); + bool ignimag = TestAndClearIgnoreImagAssign(); QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType(); - - // Load the LHS and RHS operands. - LValue LHSLV = CGF.EmitLValue(E->getLHS()); BinOpInfo OpInfo; + + // Load the RHS and LHS operands. + // __block variables need to have the rhs evaluated first, plus this should + // improve codegen a little. It is possible for the RHS to be complex or + // scalar. OpInfo.Ty = E->getComputationResultType(); + OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty); + + LValue LHSLV = CGF.EmitLValue(E->getLHS()); + // We know the LHS is a complex lvalue. - OpInfo.LHS = EmitLoadOfComplex(LHSLV.getAddress(), LHSLV.isVolatileQualified()); - OpInfo.LHS = EmitComplexToComplexCast(OpInfo.LHS, LHSTy, OpInfo.Ty); + OpInfo.LHS=EmitLoadOfComplex(LHSLV.getAddress(),LHSLV.isVolatileQualified()); + OpInfo.LHS=EmitComplexToComplexCast(OpInfo.LHS, LHSTy, OpInfo.Ty); - // It is possible for the RHS to be complex or scalar. - OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty); - // Expand the binary operator. ComplexPairTy Result = (this->*Func)(OpInfo); @@ -439,10 +498,19 @@ EmitCompoundAssign(const CompoundAssignOperator *E, // Store the result value into the LHS lvalue. EmitStoreOfComplex(Result, LHSLV.getAddress(), LHSLV.isVolatileQualified()); - return Result; + // And now return the LHS + IgnoreReal = ignreal; + IgnoreImag = ignimag; + IgnoreRealAssign = ignreal; + IgnoreImagAssign = ignimag; + return EmitLoadOfComplex(LHSLV.getAddress(), LHSLV.isVolatileQualified()); } ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { + TestAndClearIgnoreReal(); + TestAndClearIgnoreImag(); + bool ignreal = TestAndClearIgnoreRealAssign(); + bool ignimag = TestAndClearIgnoreImagAssign(); assert(CGF.getContext().getCanonicalType(E->getLHS()->getType()) == CGF.getContext().getCanonicalType(E->getRHS()->getType()) && "Invalid assignment"); @@ -454,7 +522,12 @@ ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { // Store into it. EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified()); - return Val; + // And now return the LHS + IgnoreReal = ignreal; + IgnoreImag = ignimag; + IgnoreRealAssign = ignreal; + IgnoreImagAssign = ignimag; + return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified()); } ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { @@ -465,6 +538,10 @@ ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { ComplexPairTy ComplexExprEmitter:: VisitConditionalOperator(const ConditionalOperator *E) { + TestAndClearIgnoreReal(); + TestAndClearIgnoreImag(); + TestAndClearIgnoreRealAssign(); + TestAndClearIgnoreImagAssign(); llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); @@ -509,6 +586,12 @@ ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) { } ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { + bool Ignore = TestAndClearIgnoreReal(); + (void)Ignore; + assert (Ignore == false && "init list ignored"); + Ignore = TestAndClearIgnoreImag(); + (void)Ignore; + assert (Ignore == false && "init list ignored"); if (E->getNumInits()) return Visit(E->getInit(0)); @@ -541,11 +624,14 @@ ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) { /// EmitComplexExpr - Emit the computation of the specified expression of /// complex type, ignoring the result. -ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E) { +ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal, + bool IgnoreImag, bool IgnoreRealAssign, bool IgnoreImagAssign) { assert(E && E->getType()->isAnyComplexType() && "Invalid complex expression to emit"); - return ComplexExprEmitter(*this).Visit(const_cast<Expr*>(E)); + return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag, IgnoreRealAssign, + IgnoreImagAssign) + .Visit(const_cast<Expr*>(E)); } /// EmitComplexExprIntoAddr - Emit the computation of the specified expression diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index e14d40c3b6d..958aa9361cc 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -48,17 +48,22 @@ class VISIBILITY_HIDDEN ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, Value*> { CodeGenFunction &CGF; CGBuilderTy &Builder; + bool IgnoreResultAssign; public: - ScalarExprEmitter(CodeGenFunction &cgf) : CGF(cgf), - Builder(CGF.Builder) { + ScalarExprEmitter(CodeGenFunction &cgf, bool ira=false) + : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira) { } //===--------------------------------------------------------------------===// // Utilities //===--------------------------------------------------------------------===// + bool TestAndClearIgnoreResultAssign() { + bool I = IgnoreResultAssign; IgnoreResultAssign = false; + return I; } + const llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); } LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); } @@ -172,6 +177,9 @@ public: Value *VisitPredefinedExpr(Expr *E) { return EmitLValue(E).getAddress(); } Value *VisitInitListExpr(InitListExpr *E) { + bool Ignore = TestAndClearIgnoreResultAssign(); + (void)Ignore; + assert (Ignore == false && "init list ignored"); unsigned NumInitElements = E->getNumInits(); if (E->hadArrayRangeDesignator()) { @@ -252,6 +260,8 @@ public: } Value *VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); } Value *VisitUnaryPlus(const UnaryOperator *E) { + // This differs from gcc, though, most likely due to a bug in gcc. + TestAndClearIgnoreResultAssign(); return Visit(E->getSubExpr()); } Value *VisitUnaryMinus (const UnaryOperator *E); @@ -543,6 +553,8 @@ Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { } Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { + TestAndClearIgnoreResultAssign(); + // Emit subscript expressions in rvalue context's. For most cases, this just // loads the lvalue formed by the subscript expr. However, we have to be // careful, because the base of a vector subscript is occasionally an rvalue, @@ -603,6 +615,9 @@ Value *ScalarExprEmitter::VisitImplicitCastExpr(const ImplicitCastExpr *E) { // have to handle a more broad range of conversions than explicit casts, as they // handle things like function to ptr-to-function decay etc. Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy) { + if (!DestTy->isVoidType()) + TestAndClearIgnoreResultAssign(); + // Handle cases where the source is an non-complex type. if (!CGF.hasAggregateLLVMType(E->getType())) { @@ -614,13 +629,25 @@ Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy) { if (E->getType()->isAnyComplexType()) { // Handle cases where the source is a complex type. - return EmitComplexToScalarConversion(CGF.EmitComplexExpr(E), E->getType(), - DestTy); + bool IgnoreImag = true; + bool IgnoreImagAssign = true; + bool IgnoreReal = IgnoreResultAssign; + bool IgnoreRealAssign = IgnoreResultAssign; + if (DestTy->isBooleanType()) + IgnoreImagAssign = IgnoreImag = false; + else if (DestTy->isVoidType()) { + IgnoreReal = IgnoreImag = false; + IgnoreRealAssign = IgnoreImagAssign = true; + } + CodeGenFunction::ComplexPairTy V + = CGF.EmitComplexExpr(E, IgnoreReal, IgnoreImag, IgnoreRealAssign, + IgnoreImagAssign); + return EmitComplexToScalarConversion(V, E->getType(), DestTy); } // Okay, this is a cast from an aggregate. It must be a cast to void. Just // evaluate the result and return. - CGF.EmitAggExpr(E, 0, false); + CGF.EmitAggExpr(E, 0, false, true); return 0; } @@ -704,11 +731,13 @@ Value *ScalarExprEmitter::VisitPrePostIncDec(const UnaryOperator *E, Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { + TestAndClearIgnoreResultAssign(); Value *Op = Visit(E->getSubExpr()); return Builder.CreateNeg(Op, "neg"); } Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) { + TestAndClearIgnoreResultAssign(); Value *Op = Visit(E->getSubExpr()); return Builder.CreateNot(Op, "neg"); } @@ -757,17 +786,20 @@ ScalarExprEmitter::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) { Expr *Op = E->getSubExpr(); if (Op->getType()->isAnyComplexType()) - return CGF.EmitComplexExpr(Op).first; + return CGF.EmitComplexExpr(Op, false, true, false, true).first; return Visit(Op); } Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) { Expr *Op = E->getSubExpr(); if (Op->getType()->isAnyComplexType()) - return CGF.EmitComplexExpr(Op).second; + return CGF.EmitComplexExpr(Op, true, false, true, false).second; - // __imag on a scalar returns zero. Emit it the subexpr to ensure side - // effects are evaluated. - CGF.EmitScalarExpr(Op); + // __imag on a scalar returns zero. Emit the subexpr to ensure side + // effects are evaluated, but not the actual value. + if (E->isLvalue(CGF.getContext()) == Expr::LV_Valid) + CGF.EmitLValue(Op); + else + CGF.EmitScalarExpr(Op, true); return llvm::Constant::getNullValue(ConvertType(E->getType())); } @@ -783,6 +815,7 @@ Value *ScalarExprEmitter::VisitUnaryOffsetOf(const UnaryOperator *E) //===----------------------------------------------------------------------===// BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) { + TestAndClearIgnoreResultAssign(); BinOpInfo Result; Result.LHS = Visit(E->getLHS()); Result.RHS = Visit(E->getRHS()); @@ -793,6 +826,7 @@ BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) { Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E, Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) { + bool Ignore = TestAndClearIgnoreResultAssign(); QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType(); BinOpInfo OpInfo; @@ -827,13 +861,18 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E, // handled specially because the result is altered by the store, // i.e., [C99 6.5.16p1] 'An assignment expression has the value of // the left operand after the assignment...'. - if (LHSLV.isBitfield()) - CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, LHSTy, - &Result); - else + if (LHSLV.isBitfield()) { + if (!LHSLV.isVolatileQualified()) { + CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, LHSTy, + &Result); + return Result; + } else + CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, LHSTy); + } else CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV, LHSTy); - - return Result; + if (Ignore) + return 0; + return EmitLoadOfLValue(LHSLV, E->getType()); } @@ -1125,6 +1164,7 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) { Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc, unsigned SICmpOpc, unsigned FCmpOpc) { + TestAndClearIgnoreResultAssign(); Value *Result; QualType LHSTy = E->getLHS()->getType(); if (!LHSTy->isAnyComplexType() && !LHSTy->isVectorType()) { @@ -1193,8 +1233,10 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc, } Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) { - // __block variables need to have the rhs evaluated first, plus - // this should improve codegen just a little. + bool Ignore = TestAndClearIgnoreResultAssign(); + + // __block variables need to have the rhs evaluated first, plus this should + // improve codegen just a little. Value *RHS = Visit(E->getRHS()); LValue LHS = EmitLValue(E->getLHS()); @@ -1202,14 +1244,18 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) { // because the result is altered by the store, i.e., [C99 6.5.16p1] // 'An assignment expression has the value of the left operand after // the assignment...'. - if (LHS.isBitfield()) - CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, E->getType(), - &RHS); - else + if (LHS.isBitfield()) { + if (!LHS.isVolatileQualified()) { + CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, E->getType(), + &RHS); + return RHS; + } else + CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, E->getType()); + } else CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS, E->getType()); - - // Return the RHS. - return RHS; + if (Ignore) + return 0; + return EmitLoadOfLValue(LHS, E->getType()); } Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { @@ -1339,6 +1385,7 @@ static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E) { Value *ScalarExprEmitter:: VisitConditionalOperator(const ConditionalOperator *E) { + TestAndClearIgnoreResultAssign(); // If the condition constant folds and can be elided, try to avoid emitting // the condition and the dead arm. if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getCond())){ @@ -1443,6 +1490,7 @@ Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) { if (!ArgPtr) return Builder.CreateVAArg(ArgValue, ConvertType(VE->getType())); + // FIXME Volatility. return Builder.CreateLoad(ArgPtr); } @@ -1454,13 +1502,14 @@ Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *BE) { // Entry Point into this File //===----------------------------------------------------------------------===// -/// EmitComplexExpr - Emit the computation of the specified expression of -/// complex type, ignoring the result. -Value *CodeGenFunction::EmitScalarExpr(const Expr *E) { +/// EmitScalarExpr - Emit the computation of the specified expression of +/// scalar type, ignoring the result. +Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) { assert(E && !hasAggregateLLVMType(E->getType()) && "Invalid scalar expression to emit"); - return ScalarExprEmitter(*this).Visit(const_cast<Expr*>(E)); + return ScalarExprEmitter(*this, IgnoreResultAssign) + .Visit(const_cast<Expr*>(E)); } /// EmitScalarConversion - Emit a conversion from the specified type to the diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 7d13071ece2..7c54a4da04a 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -727,7 +727,7 @@ public: /// EmitScalarExpr - Emit the computation of the specified expression of LLVM /// scalar type, returning the result. - llvm::Value *EmitScalarExpr(const Expr *E); + llvm::Value *EmitScalarExpr(const Expr *E , bool IgnoreResultAssign=false); /// EmitScalarConversion - Emit a conversion from the specified type to the /// specified destination type, both of which are LLVM scalar types. @@ -749,7 +749,10 @@ public: /// EmitComplexExpr - Emit the computation of the specified expression of /// complex type, returning the result. - ComplexPairTy EmitComplexExpr(const Expr *E); + ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal = false, + bool IgnoreImag = false, + bool IgnoreRealAssign = false, + bool IgnoreImagAssign = false); /// EmitComplexExprIntoAddr - Emit the computation of the specified expression /// of complex type, storing into the specified Value*. |