diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 0316116631a..8103506c2f4 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -690,7 +690,25 @@ Value *ScalarExprEmitter::VisitPrePostIncDec(const UnaryOperator *E, llvm::Constant *Inc = VMContext.getConstantInt(llvm::Type::Int32Ty, AmountVal); if (!isa<llvm::FunctionType>(PT->getElementType())) { - NextVal = Builder.CreateGEP(InVal, Inc, "ptrincdec"); + 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 = VMContext.getConstantInt(Inc->getType(), size); + const llvm::Type *i8Ty = + VMContext.getPointerTypeUnqual(llvm::Type::Int8Ty); + InVal = Builder.CreateBitCast(InVal, i8Ty); + NextVal = Builder.CreateGEP(InVal, Inc, "add.ptr"); + llvm::Value *lhs = LV.getAddress(); + lhs = Builder.CreateBitCast(lhs, VMContext.getPointerTypeUnqual(i8Ty)); + LV = LValue::MakeAddr(lhs, ValTy.getCVRQualifiers(), + CGF.getContext().getObjCGCAttrKind(ValTy)); + } + else + NextVal = Builder.CreateGEP(InVal, Inc, "ptrincdec"); } else { const llvm::Type *i8Ty = VMContext.getPointerTypeUnqual(llvm::Type::Int8Ty); |