diff options
-rw-r--r-- | include/clang/AST/CharUnits.h | 28 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 50 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 35 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 12 | ||||
-rw-r--r-- | lib/Analysis/MemRegion.cpp | 7 | ||||
-rw-r--r-- | lib/Analysis/Store.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 60 | ||||
-rw-r--r-- | lib/CodeGen/CGBlocks.h | 7 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 14 | ||||
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 16 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 7 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 3 |
15 files changed, 141 insertions, 117 deletions
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index 7b2833c53f..0bb4b769d0 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -36,12 +36,12 @@ namespace clang { /// in character units. class CharUnits { public: - typedef int64_t RawType; + typedef int64_t QuantityType; private: - RawType Quantity; + QuantityType Quantity; - explicit CharUnits(RawType C) : Quantity(C) {} + explicit CharUnits(QuantityType C) : Quantity(C) {} public: @@ -58,8 +58,8 @@ namespace clang { return CharUnits(1); } - /// fromRaw - Construct a CharUnits quantity from a raw integer type. - static CharUnits fromRaw(RawType Quantity) { + /// fromQuantity - Construct a CharUnits quantity from a raw integer type. + static CharUnits fromQuantity(QuantityType Quantity) { return CharUnits(Quantity); } @@ -103,26 +103,26 @@ namespace clang { /// isOne - Test whether the quantity equals one. bool isOne() const { return Quantity == 1; } - /// isPositive - Test whether the quanity is greater than zero. + /// isPositive - Test whether the quantity is greater than zero. bool isPositive() const { return Quantity > 0; } /// isNegative - Test whether the quantity is less than zero. bool isNegative() const { return Quantity < 0; } // Arithmetic operators. - CharUnits operator* (RawType N) const { + CharUnits operator* (QuantityType N) const { return CharUnits(Quantity * N); } - CharUnits operator/ (RawType N) const { + CharUnits operator/ (QuantityType N) const { return CharUnits(Quantity / N); } - RawType operator/ (const CharUnits &Other) const { + QuantityType operator/ (const CharUnits &Other) const { return Quantity / Other.Quantity; } - CharUnits operator% (RawType N) const { + CharUnits operator% (QuantityType N) const { return CharUnits(Quantity % N); } - RawType operator% (const CharUnits &Other) const { + QuantityType operator% (const CharUnits &Other) const { return Quantity % Other.Quantity; } CharUnits operator+ (const CharUnits &Other) const { @@ -134,14 +134,14 @@ namespace clang { // Conversions. - /// getRaw - Get the raw integer representation of this quantity. - RawType getRaw() const { return Quantity; } + /// getQuantity - Get the raw integer representation of this quantity. + QuantityType getQuantity() const { return Quantity; } }; // class CharUnit } // namespace clang -inline clang::CharUnits operator* (clang::CharUnits::RawType Scale, +inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU) { return CU * Scale; } diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index fe96280609..bd5ca93e1c 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -814,10 +814,10 @@ ASTContext::getTypeInfo(const Type *T) { /// getTypeSizeInChars - Return the size of the specified type, in characters. /// This method does not work on incomplete types. CharUnits ASTContext::getTypeSizeInChars(QualType T) { - return CharUnits::fromRaw(getTypeSize(T) / getCharWidth()); + return CharUnits::fromQuantity(getTypeSize(T) / getCharWidth()); } CharUnits ASTContext::getTypeSizeInChars(const Type *T) { - return CharUnits::fromRaw(getTypeSize(T) / getCharWidth()); + return CharUnits::fromQuantity(getTypeSize(T) / getCharWidth()); } /// getPreferredTypeAlign - Return the "preferred" alignment of the specified @@ -3138,15 +3138,20 @@ static bool isTypeTypedefedAsBOOL(QualType T) { /// getObjCEncodingTypeSize returns size of type for objective-c encoding /// purpose. int ASTContext::getObjCEncodingTypeSize(QualType type) { - uint64_t sz = getTypeSize(type); + CharUnits sz = getTypeSizeInChars(type); // Make all integer and enum types at least as large as an int - if (sz > 0 && type->isIntegralType()) - sz = std::max(sz, getTypeSize(IntTy)); + if (sz.isPositive() && type->isIntegralType()) + sz = std::max(sz, getTypeSizeInChars(IntTy)); // Treat arrays as pointers, since that's how they're passed in. else if (type->isArrayType()) - sz = getTypeSize(VoidPtrTy); - return sz / getTypeSize(CharTy); + sz = getTypeSizeInChars(VoidPtrTy); + return sz.getQuantity(); +} + +static inline +std::string charUnitsToString(const CharUnits &CU) { + return llvm::itostr(CU.getQuantity()); } /// getObjCEncodingForBlockDecl - Return the encoded type for this method @@ -3162,17 +3167,17 @@ void ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr, // Start with computing size of a pointer in number of bytes. // FIXME: There might(should) be a better way of doing this computation! SourceLocation Loc; - int PtrSize = getTypeSize(VoidPtrTy) / getTypeSize(CharTy); - int ParmOffset = PtrSize; + CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); + CharUnits ParmOffset = PtrSize; for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(), E = Decl->param_end(); PI != E; ++PI) { QualType PType = (*PI)->getType(); - int sz = getObjCEncodingTypeSize(PType); - assert (sz > 0 && "BlockExpr - Incomplete param type"); + CharUnits sz = CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); + assert (sz.isPositive() && "BlockExpr - Incomplete param type"); ParmOffset += sz; } // Size of the argument frame - S += llvm::utostr(ParmOffset); + S += charUnitsToString(ParmOffset); // Block pointer and offset. S += "@?0"; ParmOffset = PtrSize; @@ -3192,8 +3197,8 @@ void ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr, } else if (PType->isFunctionType()) PType = PVDecl->getType(); getObjCEncodingForType(PType, S); - S += llvm::utostr(ParmOffset); - ParmOffset += getObjCEncodingTypeSize(PType); + S += charUnitsToString(ParmOffset); + ParmOffset += CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); } } @@ -3210,20 +3215,21 @@ void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, // Start with computing size of a pointer in number of bytes. // FIXME: There might(should) be a better way of doing this computation! SourceLocation Loc; - int PtrSize = getTypeSize(VoidPtrTy) / getTypeSize(CharTy); + CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); // The first two arguments (self and _cmd) are pointers; account for // their size. - int ParmOffset = 2 * PtrSize; + CharUnits ParmOffset = 2 * PtrSize; for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(), E = Decl->param_end(); PI != E; ++PI) { QualType PType = (*PI)->getType(); - int sz = getObjCEncodingTypeSize(PType); - assert (sz > 0 && "getObjCEncodingForMethodDecl - Incomplete param type"); + CharUnits sz = CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); + assert (sz.isPositive() && + "getObjCEncodingForMethodDecl - Incomplete param type"); ParmOffset += sz; } - S += llvm::utostr(ParmOffset); + S += charUnitsToString(ParmOffset); S += "@0:"; - S += llvm::utostr(PtrSize); + S += charUnitsToString(PtrSize); // Argument types. ParmOffset = 2 * PtrSize; @@ -3243,8 +3249,8 @@ void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, // 'in', 'inout', etc. getObjCEncodingForTypeQualifier(PVDecl->getObjCDeclQualifier(), S); getObjCEncodingForType(PType, S); - S += llvm::utostr(ParmOffset); - ParmOffset += getObjCEncodingTypeSize(PType); + S += charUnitsToString(ParmOffset); + ParmOffset += CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); } } diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index cc86b24342..c40feb4c28 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -13,6 +13,7 @@ #include "clang/AST/APValue.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/ASTDiagnostic.h" @@ -325,11 +326,11 @@ APValue LValueExprEvaluator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { if (!EvaluateInteger(E->getIdx(), Index, Info)) return APValue(); - uint64_t ElementSize = Info.Ctx.getTypeSize(E->getType()) / 8; + CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(E->getType()); - uint64_t Offset = Index.getSExtValue() * ElementSize; + CharUnits Offset = Index.getSExtValue() * ElementSize; Result.setLValue(Result.getLValueBase(), - Result.getLValueOffset() + Offset); + Result.getLValueOffset() + Offset.getQuantity()); return Result; } @@ -410,22 +411,22 @@ APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { return APValue(); QualType PointeeType = PExp->getType()->getAs<PointerType>()->getPointeeType(); - uint64_t SizeOfPointee; + CharUnits SizeOfPointee; // Explicitly handle GNU void* and function pointer arithmetic extensions. if (PointeeType->isVoidType() || PointeeType->isFunctionType()) - SizeOfPointee = 1; + SizeOfPointee = CharUnits::One(); else - SizeOfPointee = Info.Ctx.getTypeSize(PointeeType) / 8; + SizeOfPointee = Info.Ctx.getTypeSizeInChars(PointeeType); - uint64_t Offset = ResultLValue.getLValueOffset(); + CharUnits Offset = CharUnits::fromQuantity(ResultLValue.getLValueOffset()); if (E->getOpcode() == BinaryOperator::Add) Offset += AdditionalOffset.getLimitedValue() * SizeOfPointee; else Offset -= AdditionalOffset.getLimitedValue() * SizeOfPointee; - return APValue(ResultLValue.getLValueBase(), Offset); + return APValue(ResultLValue.getLValueBase(), Offset.getQuantity()); } APValue PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) { @@ -977,13 +978,14 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { && VD->getType()->isObjectType() && !VD->getType()->isVariablyModifiedType() && !VD->getType()->isDependentType()) { - uint64_t Size = Info.Ctx.getTypeSize(VD->getType()) / 8; - uint64_t Offset = Base.Val.getLValueOffset(); - if (Offset <= Size) - Size -= Base.Val.getLValueOffset(); + CharUnits Size = Info.Ctx.getTypeSizeInChars(VD->getType()); + CharUnits Offset = + CharUnits::fromQuantity(Base.Val.getLValueOffset()); + if (!Offset.isNegative() && Offset <= Size) + Size -= Offset; else - Size = 0; - return Success(Size, E); + Size = CharUnits::Zero(); + return Success(Size.getQuantity(), E); } } } @@ -1175,7 +1177,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset(); if (!ElementType->isVoidType() && !ElementType->isFunctionType()) - D /= Info.Ctx.getTypeSize(ElementType) / 8; + D /= Info.Ctx.getTypeSizeInChars(ElementType).getQuantity(); return Success(D, E); } @@ -1335,8 +1337,7 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { return false; // Get information about the size. - unsigned BitWidth = Info.Ctx.getTypeSize(SrcTy); - return Success(BitWidth / Info.Ctx.Target.getCharWidth(), E); + return Success(Info.Ctx.getTypeSizeInChars(SrcTy).getQuantity(), E); } bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index b9a0ddc623..40c12c9fec 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -17,6 +17,7 @@ #include "clang/Analysis/PathSensitive/GRExprEngine.h" #include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h" #include "clang/Analysis/PathSensitive/Checker.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/ParentMap.h" #include "clang/AST/StmtObjC.h" #include "clang/Basic/Builtins.h" @@ -2421,12 +2422,12 @@ void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex, ExplodedNode* Pred, ExplodedNodeSet& Dst) { QualType T = Ex->getTypeOfArgument(); - uint64_t amt; + CharUnits amt; if (Ex->isSizeOf()) { if (T == getContext().VoidTy) { // sizeof(void) == 1 byte. - amt = 1; + amt = CharUnits::One(); } else if (!T.getTypePtr()->isConstantSizeType()) { // FIXME: Add support for VLAs. @@ -2440,14 +2441,15 @@ void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex, } else { // All other cases. - amt = getContext().getTypeSize(T) / 8; + amt = getContext().getTypeSizeInChars(T); } } else // Get alignment of the type. - amt = getContext().getTypeAlign(T) / 8; + amt = CharUnits::fromQuantity(getContext().getTypeAlign(T) / 8); MakeNode(Dst, Ex, Pred, - GetState(Pred)->BindExpr(Ex, ValMgr.makeIntVal(amt, Ex->getType()))); + GetState(Pred)->BindExpr(Ex, + ValMgr.makeIntVal(amt.getQuantity(), Ex->getType()))); } diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp index c17e4e83ee..87d60d3409 100644 --- a/lib/Analysis/MemRegion.cpp +++ b/lib/Analysis/MemRegion.cpp @@ -17,6 +17,7 @@ #include "clang/Analysis/PathSensitive/MemRegion.h" #include "clang/Analysis/PathSensitive/ValueManager.h" #include "clang/Analysis/PathSensitive/AnalysisContext.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/StmtVisitor.h" using namespace clang; @@ -689,7 +690,7 @@ static bool IsCompleteType(ASTContext &Ctx, QualType Ty) { } RegionRawOffset ElementRegion::getAsRawOffset() const { - int64_t offset = 0; + CharUnits offset = CharUnits::Zero(); const ElementRegion *ER = this; const MemRegion *superR = NULL; ASTContext &C = getContext(); @@ -714,7 +715,7 @@ RegionRawOffset ElementRegion::getAsRawOffset() const { break; } - int64_t size = (int64_t) (C.getTypeSize(elemType) / 8); + CharUnits size = C.getTypeSizeInChars(elemType); offset += (i * size); } @@ -727,7 +728,7 @@ RegionRawOffset ElementRegion::getAsRawOffset() const { } assert(superR && "super region cannot be NULL"); - return RegionRawOffset(superR, offset); + return RegionRawOffset(superR, offset.getQuantity()); } //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp index fd44a80baa..1724a9250c 100644 --- a/lib/Analysis/Store.cpp +++ b/lib/Analysis/Store.cpp @@ -13,6 +13,7 @@ #include "clang/Analysis/PathSensitive/Store.h" #include "clang/Analysis/PathSensitive/GRState.h" +#include "clang/AST/CharUnits.h" using namespace clang; @@ -138,9 +139,9 @@ const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy) if (!baseR) return NULL; - int64_t off = rawOff.getByteOffset(); + CharUnits off = CharUnits::fromQuantity(rawOff.getByteOffset()); - if (off == 0) { + if (off.isZero()) { // Edge case: we are at 0 bytes off the beginning of baseR. We // check to see if type we are casting to is the same as the base // region. If so, just return the base region. @@ -168,7 +169,7 @@ const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy) // We can only compute sizeof(PointeeTy) if it is a complete type. if (IsCompleteType(Ctx, PointeeTy)) { // Compute the size in **bytes**. - int64_t pointeeTySize = (int64_t) (Ctx.getTypeSize(PointeeTy) / 8); + CharUnits pointeeTySize = Ctx.getTypeSizeInChars(PointeeTy); // Is the offset a multiple of the size? If so, we can layer the // ElementRegion (with elementType == PointeeTy) directly on top of @@ -182,7 +183,7 @@ const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy) if (!newSuperR) { // Create an intermediate ElementRegion to represent the raw byte. // This will be the super region of the final ElementRegion. - newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off); + newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off.getQuantity()); } return MakeElementRegion(newSuperR, PointeeTy, newIndex); diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 1bece7fec6..1fa422f29e 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -24,7 +24,7 @@ using namespace clang; using namespace CodeGen; llvm::Constant *CodeGenFunction:: -BuildDescriptorBlockDecl(bool BlockHasCopyDispose, uint64_t Size, +BuildDescriptorBlockDecl(bool BlockHasCopyDispose, CharUnits Size, const llvm::StructType* Ty, std::vector<HelperInfo> *NoteForHelper) { const llvm::Type *UnsignedLongTy @@ -40,7 +40,7 @@ BuildDescriptorBlockDecl(bool BlockHasCopyDispose, uint64_t Size, // FIXME: What is the right way to say this doesn't fit? We should give // a user diagnostic in that case. Better fix would be to change the // API to size_t. - C = llvm::ConstantInt::get(UnsignedLongTy, Size); + C = llvm::ConstantInt::get(UnsignedLongTy, Size.getQuantity()); Elts.push_back(C); if (BlockHasCopyDispose) { @@ -176,7 +176,8 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { // We run this first so that we set BlockHasCopyDispose from the entire // block literal. // __invoke - uint64_t subBlockSize, subBlockAlign; + CharUnits subBlockSize; + uint64_t subBlockAlign; llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls; bool subBlockHasCopyDispose = false; llvm::Function *Fn @@ -321,13 +322,13 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { // compared to gcc by not grabbing the forwarding slot as this must // be done during Block_copy for us, and we can postpone the work // until then. - uint64_t offset = BlockDecls[BDRE->getDecl()]; + CharUnits offset = BlockDecls[BDRE->getDecl()]; llvm::Value *BlockLiteral = LoadBlockStruct(); Loc = Builder.CreateGEP(BlockLiteral, llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - offset), + offset.getQuantity()), "block.literal"); Ty = llvm::PointerType::get(Ty, 0); Loc = Builder.CreateBitCast(Loc, Ty); @@ -513,12 +514,12 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E, return EmitCall(FnInfo, Func, ReturnValue, Args); } -uint64_t CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) { +CharUnits CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) { const ValueDecl *VD = E->getDecl(); - uint64_t &offset = BlockDecls[VD]; + CharUnits &offset = BlockDecls[VD]; // See if we have already allocated an offset for this variable. - if (offset) + if (offset.isPositive()) return offset; // Don't run the expensive check, unless we have to. @@ -535,13 +536,13 @@ uint64_t CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) { llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { const ValueDecl *VD = E->getDecl(); - uint64_t offset = AllocateBlockDecl(E); + CharUnits offset = AllocateBlockDecl(E); llvm::Value *BlockLiteral = LoadBlockStruct(); llvm::Value *V = Builder.CreateGEP(BlockLiteral, llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - offset), + offset.getQuantity()), "block.literal"); if (E->isByRef()) { const llvm::Type *PtrStructTy @@ -594,10 +595,10 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { // Block literal size. For global blocks we just use the size of the generic // block literal struct. - uint64_t BlockLiteralSize = - TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType()) / 8; + CharUnits BlockLiteralSize = CharUnits::fromQuantity( + TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType()) / 8); DescriptorFields[1] = - llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize); + llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize.getQuantity()); llvm::Constant *DescriptorStruct = llvm::ConstantStruct::get(VMContext, &DescriptorFields[0], 2, false); @@ -615,7 +616,8 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { std::vector<llvm::Constant*> LiteralFields(FieldCount); CodeGenFunction::BlockInfo Info(0, n); - uint64_t subBlockSize, subBlockAlign; + CharUnits subBlockSize; + uint64_t subBlockAlign; llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls; bool subBlockHasCopyDispose = false; llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap; @@ -677,7 +679,7 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, const BlockInfo& Info, const Decl *OuterFuncDecl, llvm::DenseMap<const Decl*, llvm::Value*> ldm, - uint64_t &Size, + CharUnits &Size, uint64_t &Align, llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls, bool &subBlockHasCopyDispose) { @@ -698,8 +700,9 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, LocalDeclMap[VD] = i->second; } - BlockOffset = CGM.getTargetData() - .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8; + BlockOffset = CharUnits::fromQuantity( + CGM.getTargetData() + .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8); BlockAlign = getContext().getTypeAlign(getContext().VoidPtrTy) / 8; const FunctionType *BlockFunctionType = BExpr->getFunctionType(); @@ -799,7 +802,8 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, // The runtime needs a minimum alignment of a void *. uint64_t MinAlign = getContext().getTypeAlign(getContext().VoidPtrTy) / 8; - BlockOffset = llvm::RoundUpToAlignment(BlockOffset, MinAlign); + BlockOffset = CharUnits::fromQuantity( + llvm::RoundUpToAlignment(BlockOffset.getQuantity(), MinAlign)); Size = BlockOffset; Align = BlockAlign; @@ -808,30 +812,32 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, return Fn; } -uint64_t BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) { +CharUnits BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) { const ValueDecl *D = dyn_cast<ValueDecl>(BDRE->getDecl()); - uint64_t Size = getContext().getTypeSize(D->getType()) / 8; + CharUnits Size = getContext().getTypeSizeInChars(D->getType()); uint64_t Align = getContext().getDeclAlignInBytes(D); if (BDRE->isByRef()) { - Size = getContext().getTypeSize(getContext().VoidPtrTy) / 8; + Size = getContext().getTypeSizeInChars(getContext().VoidPtrTy); Align = getContext().getTypeAlign(getContext().VoidPtrTy) / 8; } assert ((Align > 0) && "alignment must be 1 byte or more"); - uint64_t OldOffset = BlockOffset; + CharUnits OldOffset = BlockOffset; // Ensure proper alignment, even if it means we have to have a gap - BlockOffset = llvm::RoundUpToAlignment(BlockOffset, Align); + BlockOffset = CharUnits::fromQuantity( + llvm::RoundUpToAlignment(BlockOffset.getQuantity(), Align)); BlockAlign = std::max(Align, BlockAlign); - uint64_t Pad = BlockOffset - OldOffset; - if (Pad) { - llvm::ArrayType::get(llvm::Type::getInt8Ty(VMContext), Pad); + CharUnits Pad = BlockOffset - OldOffset; + if (Pad.isPositive()) { + llvm::ArrayType::get(llvm::Type::getInt8Ty(VMContext), Pad.getQuantity()); QualType PadTy = getContext().getConstantArrayType(getContext().CharTy, - llvm::APInt(32, Pad), + llvm::APInt(32, + Pad.getQuantity()), ArrayType::Normal, 0); ValueDecl *PadDecl = VarDecl::Create(getContext(), 0, SourceLocation(), 0, QualType(PadTy), 0, VarDecl::None); diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h index 38e02a70a4..f42244c52e 100644 --- a/lib/CodeGen/CGBlocks.h +++ b/lib/CodeGen/CGBlocks.h @@ -20,6 +20,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "clang/Basic/TargetInfo.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" @@ -175,13 +176,13 @@ public: /// BlockOffset - The offset in bytes for the next allocation of an /// imported block variable. - uint64_t BlockOffset; + CharUnits BlockOffset; /// BlockAlign - Maximal alignment needed for the Block expressed in bytes. uint64_t BlockAlign; /// getBlockOffset - Allocate an offset for the ValueDecl from a /// BlockDeclRefExpr in a block literal (BlockExpr). - uint64_t getBlockOffset(const BlockDeclRefExpr *E); + CharUnits getBlockOffset(const BlockDeclRefExpr *E); /// BlockHasCopyDispose - True iff the block uses copy/dispose. bool BlockHasCopyDispose; @@ -191,7 +192,7 @@ public: llvm::SmallVector<const Expr *, 8> BlockDeclRefDecls; /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs. - std::map<const Decl*, uint64_t> BlockDecls; + std::map<const Decl*, CharUnits> BlockDecls; ImplicitParamDecl *BlockStructDecl; ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; } diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 19695c8781..89f3820d39 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1379,7 +1379,7 @@ void CGDebugInfo::EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag, else Unit = llvm::DICompileUnit(); - uint64_t offset = CGF->BlockDecls[Decl]; + CharUnits offset = CGF->BlockDecls[Decl]; llvm::SmallVector<llvm::Value *, 9> addr; llvm::LLVMContext &VMContext = CGM.getLLVMContext(); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), @@ -1387,22 +1387,24 @@ void CGDebugInfo::EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag, addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), llvm::DIFactory::OpPlus)); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - offset)); + offset.getQuantity())); if (BDRE->isByRef()) { addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), llvm::DIFactory::OpDeref)); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), llvm::DIFactory::OpPlus)); - offset = CGF->LLVMPointerWidth/8; // offset of __forwarding field + // offset of __forwarding field + offset = CharUnits::fromQuantity(CGF->LLVMPointerWidth/8); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - offset)); + offset.getQuantity())); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), llvm::DIFactory::OpDeref)); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), llvm::DIFactory::OpPlus)); - offset = XOffset/8; // offset of x field + // offset of x field + offset = CharUnits::fromQuantity(XOffset/8); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - offset)); + offset.getQuantity())); } // Create the descriptor for the variable. diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 602cc9efc7..9606a71527 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -473,7 +473,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { llvm::IntegerType::get(VMContext, LLVMPointerWidth); llvm::Value *SizeVal = llvm::ConstantInt::get(IntPtr, - getContext().getTypeSizeInChars(Ty).getRaw()); + getContext().getTypeSizeInChars(Ty).getQuantity()); const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext); if (Loc->getType() != BP) diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 5809d1e70d..2358bb3592 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1273,16 +1273,16 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) { QualType BaseType = getContext().getBaseElementType(VAT); - uint64_t BaseTypeSize = getContext().getTypeSize(BaseType) / 8; + CharUnits BaseTypeSize = getContext().getTypeSizeInChars(BaseType); Idx = Builder.CreateUDiv(Idx, llvm::ConstantInt::get(Idx->getType(), - BaseTypeSize)); + BaseTypeSize.getQuantity())); Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx"); } else if (const ObjCInterfaceType *OIT = dyn_cast<ObjCInterfaceType>(E->getType())) { llvm::Value *InterfaceSize = llvm::ConstantInt::get(Idx->getType(), - getContext().getTypeSize(OIT) / 8); + getContext().getTypeSizeInChars(OIT).getQuantity()); Idx = Builder.CreateMul(Idx, InterfaceSize); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 69ffaf2505..690a7dc2fd 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1310,7 +1310,7 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) { if (const ObjCInterfaceType *OIT = dyn_cast<ObjCInterfaceType>(ElementType)) { llvm::Value *InterfaceSize = llvm::ConstantInt::get(Idx->getType(), - CGF.getContext().getTypeSize(OIT) / 8); + CGF.getContext().getTypeSizeInChars(OIT).getQuantity()); Idx = Builder.CreateMul(Idx, InterfaceSize); const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext); Value *Casted = Builder.CreateBitCast(Ptr, i8Ty); @@ -1374,7 +1374,8 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) { dyn_cast<ObjCInterfaceType>(LHSElementType)) { llvm::Value *InterfaceSize = llvm::ConstantInt::get(Idx->getType(), - CGF.getContext().getTypeSize(OIT) / 8); + CGF.getContext(). + getTypeSizeInChars(OIT).getQuantity()); Idx = Builder.CreateMul(Idx, InterfaceSize); const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext); Value *LHSCasted = Builder.CreateBitCast(Ops.LHS, i8Ty); @@ -1398,14 +1399,14 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) { Value *LHS = Ops.LHS; Value *RHS = Ops.RHS; - uint64_t ElementSize; + CharUnits ElementSize; // Handle GCC extension for pointer arithmetic on void* and function pointer // types. if (LHSElementType->isVoidType() || LHSElementType->isFunctionType()) { - ElementSize = 1; + ElementSize = CharUnits::One(); } else { - ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8; + ElementSize = CGF.getContext().getTypeSizeInChars(LHSElementType); } const llvm::Type *ResultType = ConvertType(Ops.Ty); @@ -1414,13 +1415,14 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) { Value *BytesBetween = Builder.CreateSub(LHS, RHS, "sub.ptr.sub"); // Optimize out the shift for element size of 1. - if (ElementSize == 1) + if (ElementSize.isOne()) return BytesBetween; // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since // pointer difference in C is only defined in the case where both operands // are pointing to elements of an array. - Value *BytesPerElt = llvm::ConstantInt::get(ResultType, ElementSize); + Value *BytesPerElt = + llvm::ConstantInt::get(ResultType, ElementSize.getQuantity()); return Builder.CreateExactSDiv(BytesBetween, BytesPerElt, "sub.ptr.div"); } } diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 7999721e2c..3592c5ca80 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -578,7 +578,7 @@ llvm::Value *CodeGenFunction::EmitVLASize(QualType Ty) { ElemSize = EmitVLASize(ElemTy); else ElemSize = llvm::ConstantInt::get(SizeTy, - getContext().getTypeSize(ElemTy) / 8); + getContext().getTypeSizeInChars(ElemTy).getQuantity()); llvm::Value *NumElements = EmitScalarExpr(VAT->getSizeExpr()); NumElements = Builder.CreateIntCast(NumElements, SizeTy, false, "tmp"); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 8dbfb190df..30ad663771 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -17,6 +17,7 @@ #include "clang/AST/Type.h" #include "clang/AST/ExprCXX.h" #include "clang/A |