diff options
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 97 |
1 files changed, 4 insertions, 93 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index d26f4b802e..69ffaf2505 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -208,7 +208,10 @@ public: Value *VisitBlockDeclRefExpr(const BlockDeclRefExpr *E); // Unary Operators. - Value *VisitPrePostIncDec(const UnaryOperator *E, bool isInc, bool isPre); + Value *VisitPrePostIncDec(const UnaryOperator *E, bool isInc, bool isPre) { + LValue LV = EmitLValue(E->getSubExpr()); + return CGF.EmitScalarPrePostIncDec(E, LV, isInc, isPre); + } Value *VisitUnaryPostDec(const UnaryOperator *E) { return VisitPrePostIncDec(E, false, false); } @@ -1003,98 +1006,6 @@ Value *ScalarExprEmitter::VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) { // Unary Operators //===----------------------------------------------------------------------===// -Value *ScalarExprEmitter::VisitPrePostIncDec(const UnaryOperator *E, - bool isInc, bool isPre) { - LValue LV = EmitLValue(E->getSubExpr()); - QualType ValTy = E->getSubExpr()->getType(); - Value *InVal = CGF.EmitLoadOfLValue(LV, ValTy).getScalarVal(); - - llvm::LLVMContext &VMContext = CGF.getLLVMContext(); - - int AmountVal = isInc ? 1 : -1; - - if (ValTy->isPointerType() && - ValTy->getAs<PointerType>()->isVariableArrayType()) { - // The amount of the addition/subtraction needs to account for the VLA size - CGF.ErrorUnsupported(E, "VLA pointer inc/dec"); - } - - Value *NextVal; - if (const llvm::PointerType *PT = - dyn_cast<llvm::PointerType>(InVal->getType())) { - llvm::Constant *Inc = - llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), AmountVal); - if (!isa<llvm::FunctionType>(PT->getElementType())) { - QualType PTEE = ValTy->getPointeeType(); - if (const ObjCInterfaceType *OIT = - dyn_cast<ObjCInterfaceType>(PTEE)) { - // Handle interface types, which are not represented with a concrete type. - int size = CGF.getContext().getTypeSize(OIT) / 8; - if (!isInc) - size = -size; - Inc = llvm::ConstantInt::get(Inc->getType(), size); - const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext); - InVal = Builder.CreateBitCast(InVal, i8Ty); - NextVal = Builder.CreateGEP(InVal, Inc, "add.ptr"); - llvm::Value *lhs = LV.getAddress(); - lhs = Builder.CreateBitCast(lhs, llvm::PointerType::getUnqual(i8Ty)); - LV = LValue::MakeAddr(lhs, CGF.MakeQualifiers(ValTy)); - } else - NextVal = Builder.CreateInBoundsGEP(InVal, Inc, "ptrincdec"); - } else { - const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext); - NextVal = Builder.CreateBitCast(InVal, i8Ty, "tmp"); - NextVal = Builder.CreateGEP(NextVal, Inc, "ptrincdec"); - NextVal = Builder.CreateBitCast(NextVal, InVal->getType()); - } - } else if (InVal->getType() == llvm::Type::getInt1Ty(VMContext) && isInc) { - // Bool++ is an interesting case, due to promotion rules, we get: - // Bool++ -> Bool = Bool+1 -> Bool = (int)Bool+1 -> - // Bool = ((int)Bool+1) != 0 - // An interesting aspect of this is that increment is always true. - // Decrement does not have this property. - NextVal = llvm::ConstantInt::getTrue(VMContext); - } else if (isa<llvm::IntegerType>(InVal->getType())) { - NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal); - - // Signed integer overflow is undefined behavior. - if (ValTy->isSignedIntegerType()) - NextVal = Builder.CreateNSWAdd(InVal, NextVal, isInc ? "inc" : "dec"); - else - NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec"); - } else { - // Add the inc/dec to the real part. - if (InVal->getType()->isFloatTy()) - NextVal = - llvm::ConstantFP::get(VMContext, - llvm::APFloat(static_cast<float>(AmountVal))); - else if (InVal->getType()->isDoubleTy()) - NextVal = - llvm::ConstantFP::get(VMContext, - llvm::APFloat(static_cast<double>(AmountVal))); - else { - llvm::APFloat F(static_cast<float>(AmountVal)); - bool ignored; - F.convert(CGF.Target.getLongDoubleFormat(), llvm::APFloat::rmTowardZero, - &ignored); - NextVal = llvm::ConstantFP::get(VMContext, F); - } - NextVal = Builder.CreateFAdd(InVal, NextVal, isInc ? "inc" : "dec"); - } - - // Store the updated result through the lvalue. - if (LV.isBitfield()) - CGF.EmitStoreThroughBitfieldLValue(RValue::get(NextVal), LV, ValTy, - &NextVal); - else - CGF.EmitStoreThroughLValue(RValue::get(NextVal), LV, ValTy); - - // If this is a postinc, return the value read from memory, otherwise use the - // updated value. - return isPre ? NextVal : InVal; -} - - Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { TestAndClearIgnoreResultAssign(); Value *Op = Visit(E->getSubExpr()); |