diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h --- a/clang/lib/CodeGen/Address.h +++ b/clang/lib/CodeGen/Address.h @@ -23,18 +23,28 @@ /// An aligned address. class Address { llvm::Value *Pointer; + llvm::Type *ElementType; CharUnits Alignment; protected: - Address(std::nullptr_t) : Pointer(nullptr) {} + Address(std::nullptr_t) : Pointer(nullptr), ElementType(nullptr) {} public: - Address(llvm::Value *pointer, CharUnits alignment) - : Pointer(pointer), Alignment(alignment) { + Address(llvm::Value *pointer, llvm::Type *elementType, CharUnits alignment) + : Pointer(pointer), ElementType(elementType), Alignment(alignment) { assert(pointer != nullptr && "Pointer cannot be null"); + assert(elementType != nullptr && "Element type cannot be null"); + assert(llvm::cast(pointer->getType()) + ->isOpaqueOrPointeeTypeMatches(elementType) && + "Incorrect pointer element type"); assert(!alignment.isZero() && "Alignment cannot be zero"); } + // Deprecated: Use constructor with explicit element type instead. + Address(llvm::Value *Pointer, CharUnits Alignment) + : Address(Pointer, Pointer->getType()->getPointerElementType(), + Alignment) {} + static Address invalid() { return Address(nullptr); } bool isValid() const { return Pointer != nullptr; } @@ -49,11 +59,9 @@ } /// Return the type of the values stored in this address. - /// - /// When IR pointer types lose their element type, we should simply - /// store it in Address instead for the convenience of writing code. llvm::Type *getElementType() const { - return getType()->getElementType(); + assert(isValid()); + return ElementType; } /// Return the address space that this address resides in. @@ -79,8 +87,13 @@ ConstantAddress(std::nullptr_t) : Address(nullptr) {} public: + ConstantAddress(llvm::Constant *pointer, llvm::Type *elementType, + CharUnits alignment) + : Address(pointer, elementType, alignment) {} + + // Deprecated: Use constructor with explicit element type instead. ConstantAddress(llvm::Constant *pointer, CharUnits alignment) - : Address(pointer, alignment) {} + : Address(pointer, alignment) {} static ConstantAddress invalid() { return ConstantAddress(nullptr); @@ -90,13 +103,10 @@ return llvm::cast(Address::getPointer()); } - ConstantAddress getBitCast(llvm::Type *ty) const { - return ConstantAddress(llvm::ConstantExpr::getBitCast(getPointer(), ty), - getAlignment()); - } - - ConstantAddress getElementBitCast(llvm::Type *ty) const { - return getBitCast(ty->getPointerTo(getAddressSpace())); + ConstantAddress getElementBitCast(llvm::Type *ElemTy) const { + llvm::Constant *BitCast = llvm::ConstantExpr::getBitCast( + getPointer(), ElemTy->getPointerTo(getAddressSpace())); + return ConstantAddress(BitCast, ElemTy, getAlignment()); } static bool isaImpl(Address addr) { @@ -104,7 +114,7 @@ } static ConstantAddress castImpl(Address addr) { return ConstantAddress(llvm::cast(addr.getPointer()), - addr.getAlignment()); + addr.getElementType(), addr.getAlignment()); } }; diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2610,7 +2610,7 @@ llvm::Value *Ptr = llvm::MetadataAsValue::get(CGM.getLLVMContext(), M->getOperand(0)); - return LValue::MakeGlobalReg(Address(Ptr, Alignment), VD->getType()); + return LValue::MakeGlobalReg(Ptr, Alignment, VD->getType()); } /// Determine whether we can emit a reference to \p VD from the current diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h --- a/clang/lib/CodeGen/CGValue.h +++ b/clang/lib/CodeGen/CGValue.h @@ -441,11 +441,12 @@ return R; } - static LValue MakeGlobalReg(Address Reg, QualType type) { + static LValue MakeGlobalReg(llvm::Value *V, CharUnits alignment, + QualType type) { LValue R; R.LVType = GlobalReg; - R.V = Reg.getPointer(); - R.Initialize(type, type.getQualifiers(), Reg.getAlignment(), + R.V = V; + R.Initialize(type, type.getQualifiers(), alignment, LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo()); return R; }