diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-01-04 23:13:47 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-01-04 23:13:47 +0000 |
commit | 65639284118d54ddf2e51a05d2ffccda567fe246 (patch) | |
tree | 66b7a7ae4545db073ada0549d8af683c5c2b4231 /lib/CodeGen/CGExprConstant.cpp | |
parent | 08f7760eb2bc25ba3335169be83f7ba492860135 (diff) |
Add an APValue representation for the difference between two address-of-label expressions. Add support to Evaluate and CGExprConstant for generating/handling them. Remove the special-case for such differences in Expr::isConstantInitializer.
With that done, remove a bunch of buggy code from CGExprConstant for handling scalar expressions which is no longer necessary.
Fixes PR11705.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147561 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprConstant.cpp')
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 94 |
1 files changed, 26 insertions, 68 deletions
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 1bd94295d3..2c151328c7 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -500,27 +500,6 @@ public: return 0; } - llvm::Constant *VisitBinSub(BinaryOperator *E) { - // This must be a pointer/pointer subtraction. This only happens for - // address of label. - if (!isa<AddrLabelExpr>(E->getLHS()->IgnoreParenNoopCasts(CGM.getContext())) || - !isa<AddrLabelExpr>(E->getRHS()->IgnoreParenNoopCasts(CGM.getContext()))) - return 0; - - llvm::Constant *LHS = CGM.EmitConstantExpr(E->getLHS(), - E->getLHS()->getType(), CGF); - llvm::Constant *RHS = CGM.EmitConstantExpr(E->getRHS(), - E->getRHS()->getType(), CGF); - - llvm::Type *ResultType = ConvertType(E->getType()); - LHS = llvm::ConstantExpr::getPtrToInt(LHS, ResultType); - RHS = llvm::ConstantExpr::getPtrToInt(RHS, ResultType); - - // No need to divide by element size, since addr of label is always void*, - // which has size 1 in GNUish. - return llvm::ConstantExpr::getSub(LHS, RHS); - } - llvm::Constant *VisitCastExpr(CastExpr* E) { Expr *subExpr = E->getSubExpr(); llvm::Constant *C = CGM.EmitConstantExpr(subExpr, subExpr->getType(), CGF); @@ -570,13 +549,6 @@ public: case CK_NoOp: return C; - case CK_CPointerToObjCPointerCast: - case CK_BlockPointerToObjCPointerCast: - case CK_AnyPointerToBlockPointerCast: - case CK_BitCast: - if (C->getType() == destType) return C; - return llvm::ConstantExpr::getBitCast(C, destType); - case CK_Dependent: llvm_unreachable("saw dependent cast!"); // These will never be supported. @@ -595,7 +567,12 @@ public: case CK_ConstructorConversion: return 0; - // These should eventually be supported. + // These don't need to be handled here because Evaluate knows how to + // evaluate all scalar expressions which can be constant-evaluated. + case CK_CPointerToObjCPointerCast: + case CK_BlockPointerToObjCPointerCast: + case CK_AnyPointerToBlockPointerCast: + case CK_BitCast: case CK_ArrayToPointerDecay: case CK_FunctionToPointerDecay: case CK_BaseToDerived: @@ -613,53 +590,17 @@ public: case CK_IntegralComplexToBoolean: case CK_IntegralComplexCast: case CK_IntegralComplexToFloatingComplex: - return 0; - case CK_PointerToIntegral: - if (!E->getType()->isBooleanType()) - return llvm::ConstantExpr::getPtrToInt(C, destType); - // fallthrough - case CK_PointerToBoolean: - return llvm::ConstantExpr::getICmp(llvm::CmpInst::ICMP_EQ, C, - llvm::ConstantPointerNull::get(cast<llvm::PointerType>(C->getType()))); - case CK_NullToPointer: - return llvm::ConstantPointerNull::get(cast<llvm::PointerType>(destType)); - - case CK_IntegralCast: { - bool isSigned = subExpr->getType()->isSignedIntegerOrEnumerationType(); - return llvm::ConstantExpr::getIntegerCast(C, destType, isSigned); - } - - case CK_IntegralToPointer: { - bool isSigned = subExpr->getType()->isSignedIntegerOrEnumerationType(); - C = llvm::ConstantExpr::getIntegerCast(C, CGM.IntPtrTy, isSigned); - return llvm::ConstantExpr::getIntToPtr(C, destType); - } - + case CK_IntegralCast: + case CK_IntegralToPointer: case CK_IntegralToBoolean: - return llvm::ConstantExpr::getICmp(llvm::CmpInst::ICMP_EQ, C, - llvm::Constant::getNullValue(C->getType())); - case CK_IntegralToFloating: - if (subExpr->getType()->isSignedIntegerOrEnumerationType()) - return llvm::ConstantExpr::getSIToFP(C, destType); - else - return llvm::ConstantExpr::getUIToFP(C, destType); - case CK_FloatingToIntegral: - if (E->getType()->isSignedIntegerOrEnumerationType()) - return llvm::ConstantExpr::getFPToSI(C, destType); - else - return llvm::ConstantExpr::getFPToUI(C, destType); - case CK_FloatingToBoolean: - return llvm::ConstantExpr::getFCmp(llvm::CmpInst::FCMP_UNE, C, - llvm::Constant::getNullValue(C->getType())); - case CK_FloatingCast: - return llvm::ConstantExpr::getFPCast(C, destType); + return 0; } llvm_unreachable("Invalid CastKind"); } @@ -1081,6 +1022,23 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E, } return llvm::ConstantVector::get(Inits); } + case APValue::AddrLabelDiff: { + const AddrLabelExpr *LHSExpr = Result.Val.getAddrLabelDiffLHS(); + const AddrLabelExpr *RHSExpr = Result.Val.getAddrLabelDiffRHS(); + llvm::Constant *LHS = EmitConstantExpr(LHSExpr, LHSExpr->getType(), CGF); + llvm::Constant *RHS = EmitConstantExpr(RHSExpr, RHSExpr->getType(), CGF); + + // Compute difference + llvm::Type *ResultType = getTypes().ConvertType(E->getType()); + LHS = llvm::ConstantExpr::getPtrToInt(LHS, IntPtrTy); + RHS = llvm::ConstantExpr::getPtrToInt(RHS, IntPtrTy); + llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS); + + // LLVM os a bit sensitive about the exact format of the + // address-of-label difference; make sure to truncate after + // the subtraction. + return llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType); + } case APValue::Array: case APValue::Struct: case APValue::Union: |