diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 7cb52597d9a00..da1b428c424bd 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -834,8 +834,8 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) { auto *ISATy = DBuilder.createPointerType(ClassTy, Size); ObjTy = DBuilder.createStructType(TheCU, "objc_object", TheCU->getFile(), 0, - 0, 0, llvm::DINode::FlagZero, nullptr, - llvm::DINodeArray()); + (uint64_t)0, 0, llvm::DINode::FlagZero, + nullptr, llvm::DINodeArray()); DBuilder.replaceArrays( ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType( diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index ebfe41dd59afb..10dac91b4da9a 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -371,6 +371,22 @@ namespace llvm { uint32_t VBPtrOffset, DINode::DIFlags Flags); + /// Create debugging information entry for a member. + /// \param Scope Member scope. + /// \param Name Member name. + /// \param File File where this member is defined. + /// \param LineNo Line number. + /// \param SizeInBits Member size. + /// \param AlignInBits Member alignment. + /// \param OffsetInBits Member offset. + /// \param Flags Flags to encode member attribute, e.g. private + /// \param Ty Parent type. + /// \param Annotations Member annotations. + LLVM_ABI DIDerivedType *createMemberType( + DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, + Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits, + DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations = nullptr); + /// Create debugging information entry for a member. /// \param Scope Member scope. /// \param Name Member name. @@ -423,6 +439,23 @@ namespace llvm { Constant *Discriminant, DIType *Ty); + /// Create debugging information entry for a bit field member. + /// \param Scope Member scope. + /// \param Name Member name. + /// \param File File where this member is defined. + /// \param LineNo Line number. + /// \param SizeInBits Member size. + /// \param OffsetInBits Member offset. + /// \param StorageOffsetInBits Member storage offset. + /// \param Flags Flags to encode member attribute. + /// \param Ty Parent type. + /// \param Annotations Member annotations. + LLVM_ABI DIDerivedType *createBitFieldMemberType( + DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, + Metadata *SizeInBits, Metadata *OffsetInBits, + uint64_t StorageOffsetInBits, DINode::DIFlags Flags, DIType *Ty, + DINodeArray Annotations = nullptr); + /// Create debugging information entry for a bit field member. /// \param Scope Member scope. /// \param Name Member name. @@ -514,6 +547,29 @@ namespace llvm { unsigned RunTimeLang = 0, DIType *VTableHolder = nullptr, MDNode *TemplateParms = nullptr, StringRef UniqueIdentifier = ""); + /// Create debugging information entry for a struct. + /// \param Scope Scope in which this struct is defined. + /// \param Name Struct name. + /// \param File File where this member is defined. + /// \param LineNumber Line number. + /// \param SizeInBits Member size. + /// \param AlignInBits Member alignment. + /// \param Flags Flags to encode member attribute, e.g. private + /// \param Elements Struct elements. + /// \param RunTimeLang Optional parameter, Objective-C runtime version. + /// \param UniqueIdentifier A unique identifier for the struct. + /// \param Specification The type that this type completes. This is used by + /// Swift to represent generic types. + /// \param NumExtraInhabitants The number of extra inhabitants of the type. + /// An extra inhabitant is a bit pattern that does not represent a valid + /// value for instances of a given type. This is used by the Swift language. + LLVM_ABI DICompositeType *createStructType( + DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, + Metadata *SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags, + DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0, + DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "", + DIType *Specification = nullptr, uint32_t NumExtraInhabitants = 0); + /// Create debugging information entry for a struct. /// \param Scope Scope in which this struct is defined. /// \param Name Struct name. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 02f0a9f677db3..b0a9e2a321a08 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -717,40 +717,33 @@ std::optional DIScope::getSource() const { class DIType : public DIScope { unsigned Line; DIFlags Flags; - uint64_t SizeInBits; - uint64_t OffsetInBits; uint32_t NumExtraInhabitants; protected: + static constexpr unsigned N_OPERANDS = 5; + DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, - unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, uint32_t NumExtraInhabitants, DIFlags Flags, - ArrayRef Ops) + unsigned Line, uint32_t AlignInBits, uint32_t NumExtraInhabitants, + DIFlags Flags, ArrayRef Ops) : DIScope(C, ID, Storage, Tag, Ops) { - init(Line, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, - Flags); + init(Line, AlignInBits, NumExtraInhabitants, Flags); } ~DIType() = default; - void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, uint32_t NumExtraInhabitants, + void init(unsigned Line, uint32_t AlignInBits, uint32_t NumExtraInhabitants, DIFlags Flags) { this->Line = Line; this->Flags = Flags; - this->SizeInBits = SizeInBits; this->SubclassData32 = AlignInBits; - this->OffsetInBits = OffsetInBits; this->NumExtraInhabitants = NumExtraInhabitants; } /// Change fields in place. - void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, + void mutate(unsigned Tag, unsigned Line, uint32_t AlignInBits, uint32_t NumExtraInhabitants, DIFlags Flags) { assert(isDistinct() && "Only distinct nodes can mutate"); setTag(Tag); - init(Line, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, - Flags); + init(Line, AlignInBits, NumExtraInhabitants, Flags); } public: @@ -759,10 +752,8 @@ class DIType : public DIScope { } unsigned getLine() const { return Line; } - uint64_t getSizeInBits() const { return SizeInBits; } LLVM_ABI uint32_t getAlignInBits() const; uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; } - uint64_t getOffsetInBits() const { return OffsetInBits; } uint32_t getNumExtraInhabitants() const { return NumExtraInhabitants; } DIFlags getFlags() const { return Flags; } @@ -772,6 +763,26 @@ class DIType : public DIScope { Metadata *getRawScope() const { return getOperand(1); } MDString *getRawName() const { return getOperandAs(2); } + Metadata *getRawSizeInBits() const { return getOperand(3); } + uint64_t getSizeInBits() const { + if (auto *MD = dyn_cast_or_null(getRawSizeInBits())) { + if (ConstantInt *CI = dyn_cast_or_null(MD->getValue())) { + return CI->getZExtValue(); + } + } + return 0; + } + + Metadata *getRawOffsetInBits() const { return getOperand(4); } + uint64_t getOffsetInBits() const { + if (auto *MD = dyn_cast_or_null(getRawOffsetInBits())) { + if (ConstantInt *CI = dyn_cast_or_null(MD->getValue())) { + return CI->getZExtValue(); + } + } + return 0; + } + /// Returns a new temporary DIType with updated Flags TempDIType cloneWithFlags(DIFlags NewFlags) const { auto NewTy = clone(); @@ -837,18 +848,18 @@ class DIBasicType : public DIType { protected: DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag, - uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, + uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, DIFlags Flags, ArrayRef Ops) - : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0, + : DIType(C, DIBasicTypeKind, Storage, Tag, 0, AlignInBits, NumExtraInhabitants, Flags, Ops), Encoding(Encoding) {} DIBasicType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, - uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, + uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, DIFlags Flags, ArrayRef Ops) - : DIType(C, ID, Storage, Tag, 0, SizeInBits, AlignInBits, 0, - NumExtraInhabitants, Flags, Ops), + : DIType(C, ID, Storage, Tag, 0, AlignInBits, NumExtraInhabitants, Flags, + Ops), Encoding(Encoding) {} ~DIBasicType() = default; @@ -866,11 +877,21 @@ class DIBasicType : public DIType { uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, DIFlags Flags, StorageType Storage, - bool ShouldCreate = true); + bool ShouldCreate = true) { + auto *SizeInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), SizeInBits)); + return getImpl(Context, Tag, Name, SizeInBitsNode, AlignInBits, Encoding, + NumExtraInhabitants, Flags, Storage, ShouldCreate); + } + static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag, + MDString *Name, Metadata *SizeInBits, + uint32_t AlignInBits, unsigned Encoding, + uint32_t NumExtraInhabitants, DIFlags Flags, + StorageType Storage, bool ShouldCreate = true); TempDIBasicType cloneImpl() const { - return getTemporary(getContext(), getTag(), getName(), getSizeInBits(), - getAlignInBits(), getEncoding(), + return getTemporary(getContext(), getTag(), getRawName(), + getRawSizeInBits(), getAlignInBits(), getEncoding(), getNumExtraInhabitants(), getFlags()); } @@ -903,6 +924,12 @@ class DIBasicType : public DIType { uint32_t NumExtraInhabitants, DIFlags Flags), (Tag, Name, SizeInBits, AlignInBits, Encoding, NumExtraInhabitants, Flags)) + DEFINE_MDNODE_GET(DIBasicType, + (unsigned Tag, MDString *Name, Metadata *SizeInBits, + uint32_t AlignInBits, unsigned Encoding, + uint32_t NumExtraInhabitants, DIFlags Flags), + (Tag, Name, SizeInBits, AlignInBits, Encoding, + NumExtraInhabitants, Flags)) TempDIBasicType clone() const { return cloneImpl(); } @@ -934,29 +961,28 @@ class DIFixedPointType : public DIBasicType { APInt Denominator; DIFixedPointType(LLVMContext &C, StorageType Storage, unsigned Tag, - uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, unsigned Kind, int Factor, - ArrayRef Ops) - : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, SizeInBits, - AlignInBits, Encoding, 0, Flags, Ops), + uint32_t AlignInBits, unsigned Encoding, DIFlags Flags, + unsigned Kind, int Factor, ArrayRef Ops) + : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, AlignInBits, + Encoding, 0, Flags, Ops), Kind(Kind), Factor(Factor) { assert(Kind == FixedPointBinary || Kind == FixedPointDecimal); } DIFixedPointType(LLVMContext &C, StorageType Storage, unsigned Tag, - uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, unsigned Kind, APInt Numerator, - APInt Denominator, ArrayRef Ops) - : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, SizeInBits, - AlignInBits, Encoding, 0, Flags, Ops), + uint32_t AlignInBits, unsigned Encoding, DIFlags Flags, + unsigned Kind, APInt Numerator, APInt Denominator, + ArrayRef Ops) + : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, AlignInBits, + Encoding, 0, Flags, Ops), Kind(Kind), Factor(0), Numerator(Numerator), Denominator(Denominator) { assert(Kind == FixedPointRational); } DIFixedPointType(LLVMContext &C, StorageType Storage, unsigned Tag, - uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, unsigned Kind, int Factor, APInt Numerator, + uint32_t AlignInBits, unsigned Encoding, DIFlags Flags, + unsigned Kind, int Factor, APInt Numerator, APInt Denominator, ArrayRef Ops) - : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, SizeInBits, - AlignInBits, Encoding, 0, Flags, Ops), + : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, AlignInBits, + Encoding, 0, Flags, Ops), Kind(Kind), Factor(Factor), Numerator(Numerator), Denominator(Denominator) {} ~DIFixedPointType() = default; @@ -966,6 +992,17 @@ class DIFixedPointType : public DIBasicType { uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, DIFlags Flags, unsigned Kind, int Factor, APInt Numerator, APInt Denominator, StorageType Storage, bool ShouldCreate = true) { + auto *SizeInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), SizeInBits)); + return getImpl(Context, Tag, getCanonicalMDString(Context, Name), + SizeInBitsNode, AlignInBits, Encoding, Flags, Kind, Factor, + Numerator, Denominator, Storage, ShouldCreate); + } + static DIFixedPointType * + getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, + Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding, + DIFlags Flags, unsigned Kind, int Factor, APInt Numerator, + APInt Denominator, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), SizeInBits, AlignInBits, Encoding, Flags, Kind, Factor, Numerator, Denominator, Storage, ShouldCreate); @@ -974,12 +1011,23 @@ class DIFixedPointType : public DIBasicType { getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, DIFlags Flags, unsigned Kind, int Factor, APInt Numerator, + APInt Denominator, StorageType Storage, bool ShouldCreate = true) { + auto *SizeInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), SizeInBits)); + return getImpl(Context, Tag, Name, SizeInBitsNode, AlignInBits, Encoding, + Flags, Kind, Factor, Numerator, Denominator, Storage, + ShouldCreate); + } + static DIFixedPointType * + getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, + Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding, + DIFlags Flags, unsigned Kind, int Factor, APInt Numerator, APInt Denominator, StorageType Storage, bool ShouldCreate = true); TempDIFixedPointType cloneImpl() const { - return getTemporary(getContext(), getTag(), getName(), getSizeInBits(), - getAlignInBits(), getEncoding(), getFlags(), Kind, - Factor, Numerator, Denominator); + return getTemporary(getContext(), getTag(), getRawName(), + getRawSizeInBits(), getAlignInBits(), getEncoding(), + getFlags(), Kind, Factor, Numerator, Denominator); } public: @@ -1011,6 +1059,13 @@ class DIFixedPointType : public DIBasicType { APInt Denominator), (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags, Kind, Factor, Numerator, Denominator)) + DEFINE_MDNODE_GET(DIFixedPointType, + (unsigned Tag, MDString *Name, Metadata *SizeInBits, + uint32_t AlignInBits, unsigned Encoding, DIFlags Flags, + unsigned Kind, int Factor, APInt Numerator, + APInt Denominator), + (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags, Kind, + Factor, Numerator, Denominator)) TempDIFixedPointType clone() const { return cloneImpl(); } @@ -1050,13 +1105,15 @@ class DIStringType : public DIType { friend class LLVMContextImpl; friend class MDNode; + static constexpr unsigned MY_FIRST_OPERAND = DIType::N_OPERANDS; + unsigned Encoding; DIStringType(LLVMContext &C, StorageType Storage, unsigned Tag, - uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, + uint32_t AlignInBits, unsigned Encoding, ArrayRef Ops) - : DIType(C, DIStringTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0, - 0, FlagZero, Ops), + : DIType(C, DIStringTypeKind, Storage, Tag, 0, AlignInBits, 0, FlagZero, + Ops), Encoding(Encoding) {} ~DIStringType() = default; @@ -1066,20 +1123,34 @@ class DIStringType : public DIType { uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, StorageType Storage, bool ShouldCreate = true) { + auto *SizeInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), SizeInBits)); return getImpl(Context, Tag, getCanonicalMDString(Context, Name), - StringLength, StrLenExp, StrLocationExp, SizeInBits, + StringLength, StrLenExp, StrLocationExp, SizeInBitsNode, AlignInBits, Encoding, Storage, ShouldCreate); } LLVM_ABI static DIStringType * getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *StringLength, Metadata *StrLenExp, Metadata *StrLocationExp, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - StorageType Storage, bool ShouldCreate = true); + StorageType Storage, bool ShouldCreate = true) { + auto *SizeInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), SizeInBits)); + return getImpl(Context, Tag, Name, StringLength, StrLenExp, StrLocationExp, + SizeInBitsNode, AlignInBits, Encoding, Storage, + ShouldCreate); + } + static DIStringType *getImpl(LLVMContext &Context, unsigned Tag, + MDString *Name, Metadata *StringLength, + Metadata *StrLenExp, Metadata *StrLocationExp, + Metadata *SizeInBits, uint32_t AlignInBits, + unsigned Encoding, StorageType Storage, + bool ShouldCreate = true); TempDIStringType cloneImpl() const { return getTemporary(getContext(), getTag(), getRawName(), getRawStringLength(), getRawStringLengthExp(), - getRawStringLocationExp(), getSizeInBits(), + getRawStringLocationExp(), getRawSizeInBits(), getAlignInBits(), getEncoding()); } @@ -1103,6 +1174,13 @@ class DIStringType : public DIType { unsigned Encoding), (Tag, Name, StringLength, StringLengthExp, StringLocationExp, SizeInBits, AlignInBits, Encoding)) + DEFINE_MDNODE_GET(DIStringType, + (unsigned Tag, MDString *Name, Metadata *StringLength, + Metadata *StringLengthExp, Metadata *StringLocationExp, + Metadata *SizeInBits, uint32_t AlignInBits, + unsigned Encoding), + (Tag, Name, StringLength, StringLengthExp, + StringLocationExp, SizeInBits, AlignInBits, Encoding)) TempDIStringType clone() const { return cloneImpl(); } @@ -1124,11 +1202,15 @@ class DIStringType : public DIType { unsigned getEncoding() const { return Encoding; } - Metadata *getRawStringLength() const { return getOperand(3); } + Metadata *getRawStringLength() const { return getOperand(MY_FIRST_OPERAND); } - Metadata *getRawStringLengthExp() const { return getOperand(4); } + Metadata *getRawStringLengthExp() const { + return getOperand(MY_FIRST_OPERAND + 1); + } - Metadata *getRawStringLocationExp() const { return getOperand(5); } + Metadata *getRawStringLocationExp() const { + return getOperand(MY_FIRST_OPERAND + 2); + } }; /// Derived types. @@ -1170,18 +1252,19 @@ class DIDerivedType : public DIType { friend class LLVMContextImpl; friend class MDNode; + static constexpr unsigned MY_FIRST_OPERAND = DIType::N_OPERANDS; + /// The DWARF address space of the memory pointed to or referenced by a /// pointer or reference type respectively. std::optional DWARFAddressSpace; DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag, - unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, + unsigned Line, uint32_t AlignInBits, std::optional DWARFAddressSpace, std::optional PtrAuthData, DIFlags Flags, ArrayRef Ops) - : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits, - AlignInBits, OffsetInBits, 0, Flags, Ops), + : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, AlignInBits, 0, Flags, + Ops), DWARFAddressSpace(DWARFAddressSpace) { if (PtrAuthData) SubclassData32 = PtrAuthData->RawData; @@ -1195,6 +1278,40 @@ class DIDerivedType : public DIType { std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData, DINodeArray Annotations, StorageType Storage, bool ShouldCreate = true) { + auto *SizeInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), SizeInBits)); + auto *OffsetInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), OffsetInBits)); + return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, + Line, Scope, BaseType, SizeInBitsNode, AlignInBits, + OffsetInBitsNode, DWARFAddressSpace, PtrAuthData, Flags, + ExtraData, Annotations.get(), Storage, ShouldCreate); + } + static DIDerivedType * + getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, DIFile *File, + unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, + Metadata *ExtraData, DINodeArray Annotations, StorageType Storage, + bool ShouldCreate = true) { + auto *SizeInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), SizeInBits)); + auto *OffsetInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), OffsetInBits)); + return getImpl(Context, Tag, Name, File, Line, Scope, BaseType, + SizeInBitsNode, AlignInBits, OffsetInBitsNode, + DWARFAddressSpace, PtrAuthData, Flags, ExtraData, + Annotations.get(), Storage, ShouldCreate); + } + static DIDerivedType * + getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File, + unsigned Line, DIScope *Scope, DIType *BaseType, Metadata *SizeInBits, + uint32_t AlignInBits, Metadata *OffsetInBits, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, + Metadata *ExtraData, DINodeArray Annotations, StorageType Storage, + bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData, Flags, ExtraData, @@ -1203,26 +1320,26 @@ class DIDerivedType : public DIType { LLVM_ABI static DIDerivedType * getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, - uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, + Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits, std::optional DWARFAddressSpace, std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData, Metadata *Annotations, StorageType Storage, bool ShouldCreate = true); TempDIDerivedType cloneImpl() const { - return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(), - getScope(), getBaseType(), getSizeInBits(), - getAlignInBits(), getOffsetInBits(), - getDWARFAddressSpace(), getPtrAuthData(), getFlags(), - getExtraData(), getAnnotations()); + return getTemporary( + getContext(), getTag(), getRawName(), getFile(), getLine(), getScope(), + getBaseType(), getRawSizeInBits(), getAlignInBits(), + getRawOffsetInBits(), getDWARFAddressSpace(), getPtrAuthData(), + getFlags(), getExtraData(), getRawAnnotations()); } public: DEFINE_MDNODE_GET(DIDerivedType, (unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, - uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, + Metadata *SizeInBits, uint32_t AlignInBits, + Metadata *OffsetInBits, std::optional DWARFAddressSpace, std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData = nullptr, @@ -1230,6 +1347,28 @@ class DIDerivedType : public DIType { (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData, Flags, ExtraData, Annotations)) + DEFINE_MDNODE_GET(DIDerivedType, + (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, + DIScope *Scope, DIType *BaseType, Metadata *SizeInBits, + uint32_t AlignInBits, Metadata *OffsetInBits, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, + Metadata *ExtraData = nullptr, + DINodeArray Annotations = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, + AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData, + Flags, ExtraData, Annotations)) + DEFINE_MDNODE_GET(DIDerivedType, + (unsigned Tag, MDString *Name, DIFile *File, unsigned Line, + DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, + Metadata *ExtraData = nullptr, + DINodeArray Annotations = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, + AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData, + Flags, ExtraData, Annotations)) DEFINE_MDNODE_GET(DIDerivedType, (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, @@ -1246,7 +1385,7 @@ class DIDerivedType : public DIType { /// Get the base type this is derived from. DIType *getBaseType() const { return cast_or_null(getRawBaseType()); } - Metadata *getRawBaseType() const { return getOperand(3); } + Metadata *getRawBaseType() const { return getOperand(MY_FIRST_OPERAND); } /// \returns The DWARF address space of the memory pointed to or referenced by /// a pointer or reference type respectively. @@ -1266,7 +1405,7 @@ class DIDerivedType : public DIType { /// TODO: Separate out types that need this extra operand: pointer-to-member /// types and member fields (static members and ivars). Metadata *getExtraData() const { return getRawExtraData(); } - Metadata *getRawExtraData() const { return getOperand(4); } + Metadata *getRawExtraData() const { return getOperand(MY_FIRST_OPERAND + 1); } /// Get the template parameters from a template alias. DITemplateParameterArray getTemplateParams() const { @@ -1277,7 +1416,9 @@ class DIDerivedType : public DIType { DINodeArray getAnnotations() const { return cast_or_null(getRawAnnotations()); } - Metadata *getRawAnnotations() const { return getOperand(5); } + Metadata *getRawAnnotations() const { + return getOperand(MY_FIRST_OPERAND + 2); + } /// Get casted version of extra data. /// @{ @@ -1321,9 +1462,10 @@ class DISubrangeType : public DIType { friend class LLVMContextImpl; friend class MDNode; + static constexpr unsigned MY_FIRST_OPERAND = DIType::N_OPERANDS; + DISubrangeType(LLVMContext &C, StorageType Storage, unsigned Line, - uint64_t SizeInBits, uint32_t AlignInBits, DIFlags Flags, - ArrayRef Ops); + uint32_t AlignInBits, DIFlags Flags, ArrayRef Ops); ~DISubrangeType() = default; @@ -1333,21 +1475,23 @@ class DISubrangeType : public DIType { DIFlags Flags, DIType *BaseType, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride, Metadata *Bias, StorageType Storage, bool ShouldCreate = true) { + auto *SizeInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), SizeInBits)); return getImpl(Context, getCanonicalMDString(Context, Name), File, Line, - Scope, SizeInBits, AlignInBits, Flags, BaseType, LowerBound, - UpperBound, Stride, Bias, Storage, ShouldCreate); + Scope, SizeInBitsNode, AlignInBits, Flags, BaseType, + LowerBound, UpperBound, Stride, Bias, Storage, ShouldCreate); } LLVM_ABI static DISubrangeType * getImpl(LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line, - Metadata *Scope, uint64_t SizeInBits, uint32_t AlignInBits, + Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits, DIFlags Flags, Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride, Metadata *Bias, StorageType Storage, bool ShouldCreate = true); TempDISubrangeType cloneImpl() const { - return getTemporary(getContext(), getName(), getFile(), getLine(), - getScope(), getSizeInBits(), getAlignInBits(), + return getTemporary(getContext(), getRawName(), getFile(), getLine(), + getScope(), getRawSizeInBits(), getAlignInBits(), getFlags(), getBaseType(), getRawLowerBound(), getRawUpperBound(), getRawStride(), getRawBias()); } @@ -1357,9 +1501,10 @@ class DISubrangeType : public DIType { public: DEFINE_MDNODE_GET(DISubrangeType, (MDString * Name, Metadata *File, unsigned Line, - Metadata *Scope, uint64_t SizeInBits, uint32_t AlignInBits, - DIFlags Flags, Metadata *BaseType, Metadata *LowerBound, - Metadata *UpperBound, Metadata *Stride, Metadata *Bias), + Metadata *Scope, Metadata *SizeInBits, + uint32_t AlignInBits, DIFlags Flags, Metadata *BaseType, + Metadata *LowerBound, Metadata *UpperBound, + Metadata *Stride, Metadata *Bias), (Name, File, Line, Scope, SizeInBits, AlignInBits, Flags, BaseType, LowerBound, UpperBound, Stride, Bias)) DEFINE_MDNODE_GET(DISubrangeType, @@ -1374,15 +1519,23 @@ class DISubrangeType : public DIType { /// Get the base type this is derived from. DIType *getBaseType() const { return cast_or_null(getRawBaseType()); } - Metadata *getRawBaseType() const { return getOperand(3); } + Metadata *getRawBaseType() const { return getOperand(MY_FIRST_OPERAND); } - Metadata *getRawLowerBound() const { return getOperand(4).get(); } + Metadata *getRawLowerBound() const { + return getOperand(MY_FIRST_OPERAND + 1).get(); + } - Metadata *getRawUpperBound() const { return getOperand(5).get(); } + Metadata *getRawUpperBound() const { + return getOperand(MY_FIRST_OPERAND + 2).get(); + } - Metadata *getRawStride() const { return getOperand(6).get(); } + Metadata *getRawStride() const { + return getOperand(MY_FIRST_OPERAND + 3).get(); + } - Metadata *getRawBias() const { return getOperand(7).get(); } + Metadata *getRawBias() const { + return getOperand(MY_FIRST_OPERAND + 4).get(); + } BoundType getLowerBound() const { return convertRawToBound(getRawLowerBound()); @@ -1409,31 +1562,30 @@ class DICompositeType : public DIType { friend class LLVMContextImpl; friend class MDNode; + static constexpr unsigned MY_FIRST_OPERAND = DIType::N_OPERANDS; + unsigned RuntimeLang; std::optional EnumKind; DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag, - unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, + unsigned Line, unsigned RuntimeLang, uint32_t AlignInBits, uint32_t NumExtraInhabitants, std::optional EnumKind, DIFlags Flags, ArrayRef Ops) - : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits, - AlignInBits, OffsetInBits, NumExtraInhabitants, Flags, Ops), + : DIType(C, DICompositeTypeKind, Storage, Tag, Line, AlignInBits, + NumExtraInhabitants, Flags, Ops), RuntimeLang(RuntimeLang), EnumKind(EnumKind) {} ~DICompositeType() = default; /// Change fields in place. void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang, - uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - uint32_t NumExtraInhabitants, std::optional EnumKind, - DIFlags Flags) { + uint32_t AlignInBits, uint32_t NumExtraInhabitants, + std::optional EnumKind, DIFlags Flags) { assert(isDistinct() && "Only distinct nodes can mutate"); assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate"); this->RuntimeLang = RuntimeLang; this->EnumKind = EnumKind; - DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, - NumExtraInhabitants, Flags); + DIType::mutate(Tag, Line, AlignInBits, NumExtraInhabitants, Flags); } static DICompositeType * @@ -1447,6 +1599,52 @@ class DICompositeType : public DIType { Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, DINodeArray Annotations, Metadata *BitStride, StorageType Storage, bool ShouldCreate = true) { + auto *SizeInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), SizeInBits)); + auto *OffsetInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), OffsetInBits)); + return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, + Line, Scope, BaseType, SizeInBitsNode, AlignInBits, + OffsetInBitsNode, Flags, Elements.get(), RuntimeLang, + EnumKind, VTableHolder, TemplateParams.get(), + getCanonicalMDString(Context, Identifier), Discriminator, + DataLocation, Associated, Allocated, Rank, Annotations.get(), + Specification, NumExtraInhabitants, BitStride, Storage, + ShouldCreate); + } + static DICompositeType * + getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, + unsigned Line, Metadata *Scope, Metadata *BaseType, + uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, + DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, + std::optional EnumKind, Metadata *VTableHolder, + Metadata *TemplateParams, MDString *Identifier, + Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, + Metadata *Allocated, Metadata *Rank, Metadata *Annotations, + Metadata *Specification, uint32_t NumExtraInhabitants, + Metadata *BitStride, StorageType Storage, bool ShouldCreate = true) { + auto *SizeInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), SizeInBits)); + auto *OffsetInBitsNode = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), OffsetInBits)); + return getImpl(Context, Tag, Name, File, Line, Scope, BaseType, + SizeInBitsNode, AlignInBits, OffsetInBitsNode, Flags, + Elements, RuntimeLang, EnumKind, VTableHolder, + TemplateParams, Identifier, Discriminator, DataLocation, + Associated, Allocated, Rank, Annotations, Specification, + NumExtraInhabitants, BitStride, Storage, ShouldCreate); + } + static DICompositeType * + getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File, + unsigned Line, DIScope *Scope, DIType *BaseType, Metadata *SizeInBits, + uint32_t AlignInBits, Metadata *OffsetInBits, DIType *Specification, + uint32_t NumExtraInhabitants, DIFlags Flags, DINodeArray Elements, + unsigned RuntimeLang, std::optional EnumKind, + DIType *VTableHolder, DITemplateParameterArray TemplateParams, + StringRef Identifier, DIDerivedType *Discriminator, + Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, + Metadata *Rank, DINodeArray Annotations, Metadata *BitStride, + StorageType Storage, bool ShouldCreate = true) { return getImpl( Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(), @@ -1458,7 +1656,7 @@ class DICompositeType : public DIType { LLVM_ABI static DICompositeType * getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, - uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, + Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, std::optional EnumKind, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, @@ -1469,13 +1667,14 @@ class DICompositeType : public DIType { TempDICompositeType cloneImpl() const { return getTemporary( - getContext(), getTag(), getName(), getFile(), getLine(), getScope(), - getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(), - getFlags(), getElements(), getRuntimeLang(), getEnumKind(), - getVTableHolder(), getTemplateParams(), getIdentifier(), - getDiscriminator(), getRawDataLocation(), getRawAssociated(), - getRawAllocated(), getRawRank(), getAnnotations(), getSpecification(), - getNumExtraInhabitants(), getRawBitStride()); + getContext(), getTag(), getRawName(), getFile(), getLine(), getScope(), + getBaseType(), getRawSizeInBits(), getAlignInBits(), + getRawOffsetInBits(), getFlags(), getRawElements(), getRuntimeLang(), + getEnumKind(), getVTableHolder(), getRawTemplateParams(), + getRawIdentifier(), getDiscriminator(), getRawDataLocation(), + getRawAssociated(), getRawAllocated(), getRawRank(), + getRawAnnotations(), getSpecification(), getNumExtraInhabitants(), + getRawBitStride()); } public: @@ -1515,6 +1714,42 @@ class DICompositeType : public DIType { TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, Annotations, Specification, NumExtraInhabitants, BitStride)) + DEFINE_MDNODE_GET( + DICompositeType, + (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, + DIScope *Scope, DIType *BaseType, Metadata *SizeInBits, + uint32_t AlignInBits, Metadata *OffsetInBits, DIFlags Flags, + DINodeArray Elements, unsigned RuntimeLang, + std::optional EnumKind, DIType *VTableHolder, + DITemplateParameterArray TemplateParams = nullptr, + StringRef Identifier = "", DIDerivedType *Discriminator = nullptr, + Metadata *DataLocation = nullptr, Metadata *Associated = nullptr, + Metadata *Allocated = nullptr, Metadata *Rank = nullptr, + DINodeArray Annotations = nullptr, DIType *Specification = nullptr, + uint32_t NumExtraInhabitants = 0, Metadata *BitStride = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, + OffsetInBits, Specification, NumExtraInhabitants, Flags, Elements, + RuntimeLang, EnumKind, VTableHolder, TemplateParams, Identifier, + Discriminator, DataLocation, Associated, Allocated, Rank, Annotations, + BitStride)) + DEFINE_MDNODE_GET( + DICompositeType, + (unsigned Tag, MDString *Name, Metadata *File, unsigned Line, + Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits, + uint32_t AlignInBits, Metadata *OffsetInBits, DIFlags Flags, + Metadata *Elements, unsigned RuntimeLang, + std::optional EnumKind, Metadata *VTableHolder, + Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr, + Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr, + Metadata *Associated = nullptr, Metadata *Allocated = nullptr, + Metadata *Rank = nullptr, Metadata *Annotations = nullptr, + Metadata *Specification = nullptr, uint32_t NumExtraInhabitants = 0, + Metadata *BitStride = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, + OffsetInBits, Flags, Elements, RuntimeLang, EnumKind, VTableHolder, + TemplateParams, Identifier, Discriminator, DataLocation, Associated, + Allocated, Rank, Annotations, Specification, NumExtraInhabitants, + BitStride)) TempDICompositeType clone() const { return cloneImpl(); } @@ -1528,8 +1763,8 @@ class DICompositeType : public DIType { LLVM_ABI static DICompositeType * getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, - Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, Metadata *Specification, + Metadata *BaseType, Metadata *SizeInBits, uint32_t AlignInBits, + Metadata *OffsetInBits, Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, std::optional EnumKind, Metadata *VTableHolder, Metadata *TemplateParams, @@ -1551,8 +1786,8 @@ class DICompositeType : public DIType { LLVM_ABI static DICompositeType * buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, - Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, Metadata *Specification, + Metadata *BaseType, Metadata *SizeInBits, uint32_t AlignInBits, + Metadata *OffsetInBits, Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, std::optional EnumKind, Metadata *VTableHolder, Metadata *TemplateParams, @@ -1570,41 +1805,55 @@ class DICompositeType : public DIType { DITemplateParameterArray getTemplateParams() const { return cast_or_null(getRawTemplateParams()); } - StringRef getIdentifier() const { return getStringOperand(7); } + StringRef getIdentifier() const { + return getStringOperand(MY_FIRST_OPERAND + 4); + } unsigned getRuntimeLang() const { return RuntimeLang; } std::optional getEnumKind() const { return EnumKind; } - Metadata *getRawBaseType() const { return getOperand(3); } - Metadata *getRawElements() const { return getOperand(4); } - Metadata *getRawVTableHolder() const { return getOperand(5); } - Metadata *getRawTemplateParams() const { return getOperand(6); } - MDString *getRawIdentifier() const { return getOperandAs(7); } - Metadata *getRawDiscriminator() const { return getOperand(8); } + Metadata *getRawBaseType() const { return getOperand(MY_FIRST_OPERAND); } + Metadata *getRawElements() const { return getOperand(MY_FIRST_OPERAND + 1); } + Metadata *getRawVTableHolder() const { + return getOperand(MY_FIRST_OPERAND + 2); + } + Metadata *getRawTemplateParams() const { + return getOperand(MY_FIRST_OPERAND + 3); + } + MDString *getRawIdentifier() const { + return getOperandAs(MY_FIRST_OPERAND + 4); + } + Metadata *getRawDiscriminator() const { + return getOperand(MY_FIRST_OPERAND + 5); + } DIDerivedType *getDiscriminator() const { - return getOperandAs(8); + return getOperandAs(MY_FIRST_OPERAND + 5); + } + Metadata *getRawDataLocation() const { + return getOperand(MY_FIRST_OPERAND + 6); } - Metadata *getRawDataLocation() const { return getOperand(9); } DIVariable *getDataLocation() const { return dyn_cast_or_null(getRawDataLocation()); } DIExpression *getDataLocationExp() const { return dyn_cast_or_null(getRawDataLocation()); } - Metadata *getRawAssociated() const { return getOperand(10); } + Metadata *getRawAssociated() const { + return getOperand(MY_FIRST_OPERAND + 7); + } DIVariable *getAssociated() const { return dyn_cast_or_null(getRawAssociated()); } DIExpression *getAssociatedExp() const { return dyn_cast_or_null(getRawAssociated()); } - Metadata *getRawAllocated() const { return getOperand(11); } + Metadata *getRawAllocated() const { return getOperand(MY_FIRST_OPERAND + 8); } DIVariable *getAllocated() const { return dyn_cast_or_null(getRawAllocated()); } DIExpression *getAllocatedExp() const { return dyn_cast_or_null(getRawAllocated()); } - Metadata *getRawRank() const { return getOperand(12); } + Metadata *getRawRank() const { return getOperand(MY_FIRST_OPERAND + 9); } ConstantInt *getRankConst() const { if (auto *MD = dyn_cast_or_null(getRawRank())) return dyn_cast_or_null(MD->getValue()); @@ -1614,17 +1863,23 @@ class DICompositeType : public DIType { return dyn_cast_or_null(getRawRank()); } - Metadata *getRawAnnotations() const { return getOperand(13); } + Metadata *getRawAnnotations() const { + return getOperand(MY_FIRST_OPERAND + 10); + } DINodeArray getAnnotations() const { return cast_or_null(getRawAnnotations()); } - Metadata *getRawSpecification() const { return getOperand(14); } + Metadata *getRawSpecification() const { + return getOperand(MY_FIRST_OPERAND + 11); + } DIType *getSpecification() const { return cast_or_null(getRawSpecification()); } - Metadata *getRawBitStride() const { return getOperand(15); } + Metadata *getRawBitStride() const { + return getOperand(MY_FIRST_OPERAND + 12); + } ConstantInt *getBitStrideConst() const { if (auto *MD = dyn_cast_or_null(getRawBitStride())) return dyn_cast_or_null(MD->getValue()); @@ -1643,15 +1898,15 @@ class DICompositeType : public DIType { assert(is_contained(Elements->operands(), Op) && "Lost a member during member list replacement"); #endif - replaceOperandWith(4, Elements.get()); + replaceOperandWith(MY_FIRST_OPERAND + 1, Elements.get()); } void replaceVTableHolder(DIType *VTableHolder) { - replaceOperandWith(5, VTableHolder); + replaceOperandWith(MY_FIRST_OPERAND + 2, VTableHolder); } void replaceTemplateParams(DITemplateParameterArray TemplateParams) { - replaceOperandWith(6, TemplateParams.get()); + replaceOperandWith(MY_FIRST_OPERAND + 3, TemplateParams.get()); } /// @} @@ -1667,6 +1922,8 @@ class DISubroutineType : public DIType { friend class LLVMContextImpl; friend class MDNode; + static constexpr unsigned MY_FIRST_OPERAND = DIType::N_OPERANDS; + /// The calling convention used with DW_AT_calling_convention. Actually of /// type dwarf::CallingConvention. uint8_t CC; @@ -1712,7 +1969,7 @@ class DISubroutineType : public DIType { return cast_or_null(getRawTypeArray()); } - Metadata *getRawTypeArray() const { return getOperand(3); } + Metadata *getRawTypeArray() const { return getOperand(MY_FIRST_OPERAND); } static bool classof(const Metadata *MD) { return MD->getMetadataID() == DISubroutineTypeKind; diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 23db009654f4f..4148c0f2baf71 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4822,6 +4822,35 @@ struct MDSignedOrMDField : MDEitherFieldImpl { } }; +struct MDUnsignedOrMDField : MDEitherFieldImpl { + MDUnsignedOrMDField(uint64_t Default = 0, bool AllowNull = true) + : ImplTy(MDUnsignedField(Default), MDField(AllowNull)) {} + + MDUnsignedOrMDField(uint64_t Default, uint64_t Max, bool AllowNull = true) + : ImplTy(MDUnsignedField(Default, Max), MDField(AllowNull)) {} + + bool isMDUnsignedField() const { return WhatIs == IsTypeA; } + bool isMDField() const { return WhatIs == IsTypeB; } + uint64_t getMDUnsignedValue() const { + assert(isMDUnsignedField() && "Wrong field type"); + return A.Val; + } + Metadata *getMDFieldValue() const { + assert(isMDField() && "Wrong field type"); + return B.Val; + } + + Metadata *getValueAsMetadata(LLVMContext &Context) const { + if (isMDUnsignedField()) { + return ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), getMDUnsignedValue())); + } else if (isMDField()) { + return getMDFieldValue(); + } + return nullptr; + } +}; + } // end anonymous namespace namespace llvm { @@ -5205,6 +5234,29 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, return true; } +template <> +bool LLParser::parseMDField(LocTy Loc, StringRef Name, + MDUnsignedOrMDField &Result) { + // Try to parse an unsigned int. + if (Lex.getKind() == lltok::APSInt) { + MDUnsignedField Res = Result.A; + if (!parseMDField(Loc, Name, Res)) { + Result.assign(Res); + return false; + } + return true; + } + + // Otherwise, try to parse as an MDField. + MDField Res = Result.B; + if (!parseMDField(Loc, Name, Res)) { + Result.assign(Res); + return false; + } + + return true; +} + template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDStringField &Result) { LocTy ValueLoc = Lex.getLoc(); @@ -5386,7 +5438,7 @@ bool LLParser::parseDISubrangeType(MDNode *&Result, bool IsDistinct) { OPTIONAL(line, LineField, ); \ OPTIONAL(scope, MDField, ); \ OPTIONAL(baseType, MDField, ); \ - OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(lowerBound, MDSignedOrMDField, ); \ @@ -5410,10 +5462,10 @@ bool LLParser::parseDISubrangeType(MDNode *&Result, bool IsDistinct) { Metadata *Stride = convToMetadata(stride); Metadata *Bias = convToMetadata(bias); - Result = GET_OR_DISTINCT(DISubrangeType, - (Context, name.Val, file.Val, line.Val, scope.Val, - size.Val, align.Val, flags.Val, baseType.Val, - LowerBound, UpperBound, Stride, Bias)); + Result = GET_OR_DISTINCT( + DISubrangeType, (Context, name.Val, file.Val, line.Val, scope.Val, + size.getValueAsMetadata(Context), align.Val, flags.Val, + baseType.Val, LowerBound, UpperBound, Stride, Bias)); return false; } @@ -5521,7 +5573,7 @@ bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \ OPTIONAL(name, MDStringField, ); \ - OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(encoding, DwarfAttEncodingField, ); \ OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \ @@ -5529,7 +5581,8 @@ bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) { PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, size.Val, + Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, + size.getValueAsMetadata(Context), align.Val, encoding.Val, num_extra_inhabitants.Val, flags.Val)); return false; @@ -5544,7 +5597,7 @@ bool LLParser::parseDIFixedPointType(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \ OPTIONAL(name, MDStringField, ); \ - OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(encoding, DwarfAttEncodingField, ); \ OPTIONAL(flags, DIFlagField, ); \ @@ -5556,7 +5609,8 @@ bool LLParser::parseDIFixedPointType(MDNode *&Result, bool IsDistinct) { #undef VISIT_MD_FIELDS Result = GET_OR_DISTINCT(DIFixedPointType, - (Context, tag.Val, name.Val, size.Val, align.Val, + (Context, tag.Val, name.Val, + size.getValueAsMetadata(Context), align.Val, encoding.Val, flags.Val, kind.Val, factor.Val, numerator.Val, denominator.Val)); return false; @@ -5571,7 +5625,7 @@ bool LLParser::parseDIStringType(MDNode *&Result, bool IsDistinct) { OPTIONAL(stringLength, MDField, ); \ OPTIONAL(stringLengthExpression, MDField, ); \ OPTIONAL(stringLocationExpression, MDField, ); \ - OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(encoding, DwarfAttEncodingField, ); PARSE_MD_FIELDS(); @@ -5580,7 +5634,8 @@ bool LLParser::parseDIStringType(MDNode *&Result, bool IsDistinct) { Result = GET_OR_DISTINCT( DIStringType, (Context, tag.Val, name.Val, stringLength.Val, stringLengthExpression.Val, - stringLocationExpression.Val, size.Val, align.Val, encoding.Val)); + stringLocationExpression.Val, size.getValueAsMetadata(Context), + align.Val, encoding.Val)); return false; } @@ -5601,9 +5656,9 @@ bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) { OPTIONAL(line, LineField, ); \ OPTIONAL(scope, MDField, ); \ REQUIRED(baseType, MDField, ); \ - OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ - OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(offset, MDUnsignedOrMDField, (0, UINT64_MAX)); \ OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(extraData, MDField, ); \ OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX)); \ @@ -5626,11 +5681,11 @@ bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) { (unsigned)ptrAuthExtraDiscriminator.Val, ptrAuthIsaPointer.Val, ptrAuthAuthenticatesNullValues.Val); - Result = GET_OR_DISTINCT(DIDerivedType, - (Context, tag.Val, name.Val, file.Val, line.Val, - scope.Val, baseType.Val, size.Val, align.Val, - offset.Val, DWARFAddressSpace, PtrAuthData, - flags.Val, extraData.Val, annotations.Val)); + Result = GET_OR_DISTINCT( + DIDerivedType, (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, + baseType.Val, size.getValueAsMetadata(Context), align.Val, + offset.getValueAsMetadata(Context), DWARFAddressSpace, + PtrAuthData, flags.Val, extraData.Val, annotations.Val)); return false; } @@ -5642,9 +5697,9 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { OPTIONAL(line, LineField, ); \ OPTIONAL(scope, MDField, ); \ OPTIONAL(baseType, MDField, ); \ - OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ - OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(offset, MDUnsignedOrMDField, (0, UINT64_MAX)); \ OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(elements, MDField, ); \ OPTIONAL(runtimeLang, DwarfLangField, ); \ @@ -5679,12 +5734,12 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { if (identifier.Val) if (auto *CT = DICompositeType::buildODRType( Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val, - scope.Val, baseType.Val, size.Val, align.Val, offset.Val, - specification.Val, num_extra_inhabitants.Val, flags.Val, - elements.Val, runtimeLang.Val, EnumKind, vtableHolder.Val, - templateParams.Val, discriminator.Val, dataLocation.Val, - associated.Val, allocated.Val, Rank, annotations.Val, - bitStride.Val)) { + scope.Val, baseType.Val, size.getValueAsMetadata(Context), + align.Val, offset.getValueAsMetadata(Context), specification.Val, + num_extra_inhabitants.Val, flags.Val, elements.Val, runtimeLang.Val, + EnumKind, vtableHolder.Val, templateParams.Val, discriminator.Val, + dataLocation.Val, associated.Val, allocated.Val, Rank, + annotations.Val, bitStride.Val)) { Result = CT; return false; } @@ -5694,7 +5749,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { Result = GET_OR_DISTINCT( DICompositeType, (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, - size.Val, align.Val, offset.Val, flags.Val, elements.Val, + size.getValueAsMetadata(Context), align.Val, + offset.getValueAsMetadata(Context), flags.Val, elements.Val, runtimeLang.Val, EnumKind, vtableHolder.Val, templateParams.Val, identifier.Val, discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, Rank, annotations.Val, specification.Val, diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 1cd1797c1092d..51f81228505fa 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1525,15 +1525,24 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (Record.size() < 6 || Record.size() > 8) return error("Invalid record"); - IsDistinct = Record[0]; + IsDistinct = Record[0] & 1; + bool SizeIsMetadata = Record[0] & 2; DINode::DIFlags Flags = (Record.size() > 6) ? static_cast(Record[6]) : DINode::FlagZero; uint32_t NumExtraInhabitants = (Record.size() > 7) ? Record[7] : 0; + Metadata *SizeInBits; + if (SizeIsMetadata) { + SizeInBits = getMDOrNull(Record[3]); + } else { + SizeInBits = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), Record[3])); + } + MetadataList.assignValue( GET_OR_DISTINCT(DIBasicType, - (Context, Record[1], getMDString(Record[2]), Record[3], + (Context, Record[1], getMDString(Record[2]), SizeInBits, Record[4], Record[5], NumExtraInhabitants, Flags)), NextMetadataNo); NextMetadataNo++; @@ -1543,9 +1552,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (Record.size() < 11) return error("Invalid record"); - IsDistinct = Record[0]; + IsDistinct = Record[0] & 1; + bool SizeIsMetadata = Record[0] & 2; DINode::DIFlags Flags = static_cast(Record[6]); + Metadata *SizeInBits; + if (SizeIsMetadata) { + SizeInBits = getMDOrNull(Record[3]); + } else { + SizeInBits = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), Record[3])); + } + size_t Offset = 9; auto ReadWideInt = [&]() { @@ -1565,7 +1583,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( MetadataList.assignValue( GET_OR_DISTINCT(DIFixedPointType, - (Context, Record[1], getMDString(Record[2]), Record[3], + (Context, Record[1], getMDString(Record[2]), SizeInBits, Record[4], Record[5], Flags, Record[7], Record[8], Numerator, Denominator)), NextMetadataNo); @@ -1576,17 +1594,26 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (Record.size() > 9 || Record.size() < 8) return error("Invalid record"); - IsDistinct = Record[0]; + IsDistinct = Record[0] & 1; + bool SizeIsMetadata = Record[0] & 2; bool SizeIs8 = Record.size() == 8; // StringLocationExp (i.e. Record[5]) is added at a later time // than the other fields. The code here enables backward compatibility. Metadata *StringLocationExp = SizeIs8 ? nullptr : getMDOrNull(Record[5]); unsigned Offset = SizeIs8 ? 5 : 6; + Metadata *SizeInBits; + if (SizeIsMetadata) { + SizeInBits = getMDOrNull(Record[Offset]); + } else { + SizeInBits = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), Record[Offset])); + } + MetadataList.assignValue( GET_OR_DISTINCT(DIStringType, (Context, Record[1], getMDString(Record[2]), getMDOrNull(Record[3]), getMDOrNull(Record[4]), - StringLocationExp, Record[Offset], Record[Offset + 1], + StringLocationExp, SizeInBits, Record[Offset + 1], Record[Offset + 2])), NextMetadataNo); NextMetadataNo++; @@ -1615,15 +1642,28 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( PtrAuthData.emplace(Record[14]); } - IsDistinct = Record[0]; + IsDistinct = Record[0] & 1; + bool SizeIsMetadata = Record[0] & 2; DINode::DIFlags Flags = static_cast(Record[10]); + + Metadata *SizeInBits, *OffsetInBits; + if (SizeIsMetadata) { + SizeInBits = getMDOrNull(Record[7]); + OffsetInBits = getMDOrNull(Record[9]); + } else { + SizeInBits = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), Record[7])); + OffsetInBits = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), Record[9])); + } + MetadataList.assignValue( GET_OR_DISTINCT(DIDerivedType, (Context, Record[1], getMDString(Record[2]), getMDOrNull(Record[3]), Record[4], getDITypeRefOrNull(Record[5]), - getDITypeRefOrNull(Record[6]), Record[7], Record[8], - Record[9], DWARFAddressSpace, PtrAuthData, Flags, + getDITypeRefOrNull(Record[6]), SizeInBits, Record[8], + OffsetInBits, DWARFAddressSpace, PtrAuthData, Flags, getDITypeRefOrNull(Record[11]), Annotations)), NextMetadataNo); NextMetadataNo++; @@ -1633,13 +1673,23 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (Record.size() != 13) return error("Invalid record"); - IsDistinct = Record[0]; + IsDistinct = Record[0] & 1; + bool SizeIsMetadata = Record[0] & 2; DINode::DIFlags Flags = static_cast(Record[7]); + + Metadata *SizeInBits; + if (SizeIsMetadata) { + SizeInBits = getMDOrNull(Record[5]); + } else { + SizeInBits = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), Record[5])); + } + MetadataList.assignValue( GET_OR_DISTINCT(DISubrangeType, (Context, getMDString(Record[1]), getMDOrNull(Record[2]), Record[3], - getMDOrNull(Record[4]), Record[5], Record[6], Flags, + getMDOrNull(Record[4]), SizeInBits, Record[6], Flags, getDITypeRefOrNull(Record[8]), getMDOrNull(Record[9]), getMDOrNull(Record[10]), getMDOrNull(Record[11]), getMDOrNull(Record[12]))), @@ -1654,18 +1704,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( // If we have a UUID and this is not a forward declaration, lookup the // mapping. IsDistinct = Record[0] & 0x1; - bool IsNotUsedInTypeRef = Record[0] >= 2; + bool IsNotUsedInTypeRef = Record[0] & 2; + bool SizeIsMetadata = Record[0] & 4; unsigned Tag = Record[1]; MDString *Name = getMDString(Record[2]); Metadata *File = getMDOrNull(Record[3]); unsigned Line = Record[4]; Metadata *Scope = getDITypeRefOrNull(Record[5]); Metadata *BaseType = nullptr; - uint64_t SizeInBits = Record[7]; if (Record[8] > (uint64_t)std::numeric_limits::max()) return error("Alignment value is too large"); uint32_t AlignInBits = Record[8]; - uint64_t OffsetInBits = 0; + Metadata *OffsetInBits = nullptr; uint32_t NumExtraInhabitants = (Record.size() > 22) ? Record[22] : 0; DINode::DIFlags Flags = static_cast(Record[10]); Metadata *Elements = nullptr; @@ -1712,7 +1762,14 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( TemplateParams = getMDOrNull(Record[14]); } else { BaseType = getDITypeRefOrNull(Record[6]); - OffsetInBits = Record[9]; + + if (SizeIsMetadata) { + OffsetInBits = getMDOrNull(Record[9]); + } else { + OffsetInBits = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), Record[9])); + } + Elements = getMDOrNull(Record[11]); VTableHolder = getDITypeRefOrNull(Record[13]); TemplateParams = getMDOrNull(Record[14]); @@ -1740,6 +1797,14 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (Record.size() > 24 && Record[24] != dwarf::DW_APPLE_ENUM_KIND_invalid) EnumKind = Record[24]; + Metadata *SizeInBits; + if (SizeIsMetadata) { + SizeInBits = getMDOrNull(Record[7]); + } else { + SizeInBits = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt64Ty(Context), Record[7])); + } + DICompositeType *CT = nullptr; if (Identifier) CT = DICompositeType::buildODRType( diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 8789b3123cd60..459d2cfc3670b 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1900,10 +1900,11 @@ void ModuleBitcodeWriter::writeDIEnumerator(const DIEnumerator *N, void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N, SmallVectorImpl &Record, unsigned Abbrev) { - Record.push_back(N->isDistinct()); + const unsigned SizeIsMetadata = 0x2; + Record.push_back(SizeIsMetadata | (unsigned)N->isDistinct()); Record.push_back(N->getTag()); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); - Record.push_back(N->getSizeInBits()); + Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits())); Record.push_back(N->getAlignInBits()); Record.push_back(N->getEncoding()); Record.push_back(N->getFlags()); @@ -1916,10 +1917,11 @@ void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N, void ModuleBitcodeWriter::writeDIFixedPointType( const DIFixedPointType *N, SmallVectorImpl &Record, unsigned Abbrev) { - Record.push_back(N->isDistinct()); + const unsigned SizeIsMetadata = 0x2; + Record.push_back(SizeIsMetadata | (unsigned)N->isDistinct()); Record.push_back(N->getTag()); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); - Record.push_back(N->getSizeInBits()); + Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits())); Record.push_back(N->getAlignInBits()); Record.push_back(N->getEncoding()); Record.push_back(N->getFlags()); @@ -1945,13 +1947,14 @@ void ModuleBitcodeWriter::writeDIFixedPointType( void ModuleBitcodeWriter::writeDIStringType(const DIStringType *N, SmallVectorImpl &Record, unsigned Abbrev) { - Record.push_back(N->isDistinct()); + const unsigned SizeIsMetadata = 0x2; + Record.push_back(SizeIsMetadata | (unsigned)N->isDistinct()); Record.push_back(N->getTag()); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); Record.push_back(VE.getMetadataOrNullID(N->getStringLength())); Record.push_back(VE.getMetadataOrNullID(N->getStringLengthExp())); Record.push_back(VE.getMetadataOrNullID(N->getStringLocationExp())); - Record.push_back(N->getSizeInBits()); + Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits())); Record.push_back(N->getAlignInBits()); Record.push_back(N->getEncoding()); @@ -1962,16 +1965,17 @@ void ModuleBitcodeWriter::writeDIStringType(const DIStringType *N, void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N, SmallVectorImpl &Record, unsigned Abbrev) { - Record.push_back(N->isDistinct()); + const unsigned SizeIsMetadata = 0x2; + Record.push_back(SizeIsMetadata | (unsigned)N->isDistinct()); Record.push_back(N->getTag()); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); Record.push_back(VE.getMetadataOrNullID(N->getFile())); Record.push_back(N->getLine()); Record.push_back(VE.getMetadataOrNullID(N->getScope())); Record.push_back(VE.getMetadataOrNullID(N->getBaseType())); - Record.push_back(N->getSizeInBits()); + Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits())); Record.push_back(N->getAlignInBits()); - Record.push_back(N->getOffsetInBits()); + Record.push_back(VE.getMetadataOrNullID(N->getRawOffsetInBits())); Record.push_back(N->getFlags()); Record.push_back(VE.getMetadataOrNullID(N->getExtraData())); @@ -1996,12 +2000,13 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N, void ModuleBitcodeWriter::writeDISubrangeType(const DISubrangeType *N, SmallVectorImpl &Record, unsigned Abbrev) { - Record.push_back(N->isDistinct()); + const unsigned SizeIsMetadata = 0x2; + Record.push_back(SizeIsMetadata | (unsigned)N->isDistinct()); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); Record.push_back(VE.getMetadataOrNullID(N->getFile())); Record.push_back(N->getLine()); Record.push_back(VE.getMetadataOrNullID(N->getScope())); - Record.push_back(N->getSizeInBits()); + Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits())); Record.push_back(N->getAlignInBits()); Record.push_back(N->getFlags()); Record.push_back(VE.getMetadataOrNullID(N->getBaseType())); @@ -2018,16 +2023,18 @@ void ModuleBitcodeWriter::writeDICompositeType( const DICompositeType *N, SmallVectorImpl &Record, unsigned Abbrev) { const unsigned IsNotUsedInOldTypeRef = 0x2; - Record.push_back(IsNotUsedInOldTypeRef | (unsigned)N->isDistinct()); + const unsigned SizeIsMetadata = 0x4; + Record.push_back(SizeIsMetadata | IsNotUsedInOldTypeRef | + (unsigned)N->isDistinct()); Record.push_back(N->getTag()); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); Record.push_back(VE.getMetadataOrNullID(N->getFile())); Record.push_back(N->getLine()); Record.push_back(VE.getMetadataOrNullID(N->getScope())); Record.push_back(VE.getMetadataOrNullID(N->getBaseType())); - Record.push_back(N->getSizeInBits()); + Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits())); Record.push_back(N->getAlignInBits()); - Record.push_back(N->getOffsetInBits()); + Record.push_back(VE.getMetadataOrNullID(N->getRawOffsetInBits())); Record.push_back(N->getFlags()); Record.push_back(VE.getMetadataOrNullID(N->getElements().get())); Record.push_back(N->getRuntimeLang()); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 5a1ac5d662704..ed50183859d00 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1002,7 +1002,6 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { // Add name if not anonymous or intermediate type. StringRef Name = CTy->getName(); - uint64_t Size = CTy->getSizeInBits() >> 3; uint16_t Tag = Buffer.getTag(); switch (Tag) { @@ -1165,15 +1164,29 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) { - // Add size if non-zero (derived types might be zero-sized.) - // Ignore the size if it's a non-enum forward decl. - // TODO: Do we care about size for enum forward declarations? - if (Size && - (!CTy->isForwardDecl() || Tag == dwarf::DW_TAG_enumeration_type)) - addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size); - else if (!CTy->isForwardDecl()) - // Add zero size if it is not a forward declaration. - addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, 0); + if (auto *Var = dyn_cast_or_null(CTy->getRawSizeInBits())) { + if (auto *VarDIE = getDIE(Var)) { + addDIEEntry(Buffer, dwarf::DW_AT_bit_size, *VarDIE); + } + } else if (auto *Exp = + dyn_cast_or_null(CTy->getRawSizeInBits())) { + DIELoc *Loc = new (DIEValueAllocator) DIELoc; + DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); + DwarfExpr.setMemoryLocationKind(); + DwarfExpr.addExpression(Exp); + addBlock(Buffer, dwarf::DW_AT_bit_size, DwarfExpr.finalize()); + } else { + uint64_t Size = CTy->getSizeInBits() >> 3; + // Add size if non-zero (derived types might be zero-sized.) + // Ignore the size if it's a non-enum forward decl. + // TODO: Do we care about size for enum forward declarations? + if (Size && + (!CTy->isForwardDecl() || Tag == dwarf::DW_TAG_enumeration_type)) + addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size); + else if (!CTy->isForwardDecl()) + // Add zero size if it is not a forward declaration. + addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, 0); + } // If we're a forward decl, say so. if (CTy->isForwardDecl()) @@ -1840,74 +1853,119 @@ DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie); } else { - uint64_t Size = DT->getSizeInBits(); - uint64_t FieldSize = DD->getBaseTypeSize(DT); - uint32_t AlignInBytes = DT->getAlignInBytes(); - uint64_t OffsetInBytes; + uint64_t Size = 0; + uint64_t FieldSize = 0; bool IsBitfield = DT->isBitField(); - if (IsBitfield) { - // Handle bitfield, assume bytes are 8 bits. - if (DD->useDWARF2Bitfields()) - addUInt(MemberDie, dwarf::DW_AT_byte_size, std::nullopt, FieldSize / 8); - addUInt(MemberDie, dwarf::DW_AT_bit_size, std::nullopt, Size); - - assert(DT->getOffsetInBits() <= - (uint64_t)std::numeric_limits::max()); - int64_t Offset = DT->getOffsetInBits(); - // We can't use DT->getAlignInBits() here: AlignInBits for member type - // is non-zero if and only if alignment was forced (e.g. _Alignas()), - // which can't be done with bitfields. Thus we use FieldSize here. - uint32_t AlignInBits = FieldSize; - uint32_t AlignMask = ~(AlignInBits - 1); - // The bits from the start of the storage unit to the start of the field. - uint64_t StartBitOffset = Offset - (Offset & AlignMask); - // The byte offset of the field's aligned storage unit inside the struct. - OffsetInBytes = (Offset - StartBitOffset) / 8; - - if (DD->useDWARF2Bitfields()) { - uint64_t HiMark = (Offset + FieldSize) & AlignMask; - uint64_t FieldOffset = (HiMark - FieldSize); - Offset -= FieldOffset; - - // Maybe we need to work from the other end. - if (Asm->getDataLayout().isLittleEndian()) - Offset = FieldSize - (Offset + Size); - - if (Offset < 0) - addSInt(MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata, - Offset); - else - addUInt(MemberDie, dwarf::DW_AT_bit_offset, std::nullopt, - (uint64_t)Offset); - OffsetInBytes = FieldOffset >> 3; - } else { - addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt, Offset); + + // Handle the size. + if (auto *Var = dyn_cast_or_null(DT->getRawSizeInBits())) { + if (auto *VarDIE = getDIE(Var)) { + addDIEEntry(MemberDie, dwarf::DW_AT_bit_size, *VarDIE); } + } else if (auto *Exp = + dyn_cast_or_null(DT->getRawSizeInBits())) { + DIELoc *Loc = new (DIEValueAllocator) DIELoc; + DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); + DwarfExpr.setMemoryLocationKind(); + DwarfExpr.addExpression(Exp); + addBlock(MemberDie, dwarf::DW_AT_bit_size, DwarfExpr.finalize()); } else { - // This is not a bitfield. - OffsetInBytes = DT->getOffsetInBits() / 8; - if (AlignInBytes) - addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, - AlignInBytes); + Size = DT->getSizeInBits(); + FieldSize = DD->getBaseTypeSize(DT); + if (IsBitfield) { + // Handle bitfield, assume bytes are 8 bits. + if (DD->useDWARF2Bitfields()) + addUInt(MemberDie, dwarf::DW_AT_byte_size, std::nullopt, + FieldSize / 8); + addUInt(MemberDie, dwarf::DW_AT_bit_size, std::nullopt, Size); + } } - if (DD->getDwarfVersion() <= 2) { - DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc; - addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); - addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes); - addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie); - } else if (!IsBitfield || DD->useDWARF2Bitfields()) { - // In DWARF v3, DW_FORM_data4/8 in DW_AT_data_member_location are - // interpreted as location-list pointers. Interpreting constants as - // pointers is not expected, so we use DW_FORM_udata to encode the - // constants here. - if (DD->getDwarfVersion() == 3) - addUInt(MemberDie, dwarf::DW_AT_data_member_location, - dwarf::DW_FORM_udata, OffsetInBytes); - else - addUInt(MemberDie, dwarf::DW_AT_data_member_location, std::nullopt, - OffsetInBytes); + // Handle the location. DW_AT_data_bit_offset won't allow an + // expression until DWARF 6, but it can be used as an extension. + // See https://dwarfstd.org/issues/250501.1.html + if (auto *Var = dyn_cast_or_null(DT->getRawOffsetInBits())) { + if (!Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= 6) { + if (auto *VarDIE = getDIE(Var)) { + addDIEEntry(MemberDie, dwarf::DW_AT_data_bit_offset, *VarDIE); + } + } + } else if (auto *Expr = + dyn_cast_or_null(DT->getRawOffsetInBits())) { + if (!Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= 6) { + DIELoc *Loc = new (DIEValueAllocator) DIELoc; + DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); + DwarfExpr.setMemoryLocationKind(); + DwarfExpr.addExpression(Expr); + addBlock(MemberDie, dwarf::DW_AT_data_bit_offset, DwarfExpr.finalize()); + } + } else { + uint32_t AlignInBytes = DT->getAlignInBytes(); + uint64_t OffsetInBytes; + + if (IsBitfield) { + assert(DT->getOffsetInBits() <= + (uint64_t)std::numeric_limits::max()); + int64_t Offset = DT->getOffsetInBits(); + // We can't use DT->getAlignInBits() here: AlignInBits for member type + // is non-zero if and only if alignment was forced (e.g. _Alignas()), + // which can't be done with bitfields. Thus we use FieldSize here. + uint32_t AlignInBits = FieldSize; + uint32_t AlignMask = ~(AlignInBits - 1); + // The bits from the start of the storage unit to the start of the + // field. + uint64_t StartBitOffset = Offset - (Offset & AlignMask); + // The byte offset of the field's aligned storage unit inside the + // struct. + OffsetInBytes = (Offset - StartBitOffset) / 8; + + if (DD->useDWARF2Bitfields()) { + uint64_t HiMark = (Offset + FieldSize) & AlignMask; + uint64_t FieldOffset = (HiMark - FieldSize); + Offset -= FieldOffset; + + // Maybe we need to work from the other end. + if (Asm->getDataLayout().isLittleEndian()) + Offset = FieldSize - (Offset + Size); + + if (Offset < 0) + addSInt(MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata, + Offset); + else + addUInt(MemberDie, dwarf::DW_AT_bit_offset, std::nullopt, + (uint64_t)Offset); + OffsetInBytes = FieldOffset >> 3; + } else { + addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt, + Offset); + } + } else { + // This is not a bitfield. + OffsetInBytes = DT->getOffsetInBits() / 8; + if (AlignInBytes) + addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, + AlignInBytes); + } + + if (DD->getDwarfVersion() <= 2) { + DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc; + addUInt(*MemLocationDie, dwarf::DW_FORM_data1, + dwarf::DW_OP_plus_uconst); + addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes); + addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie); + } else if (!IsBitfield || DD->useDWARF2Bitfields()) { + // In DWARF v3, DW_FORM_data4/8 in DW_AT_data_member_location are + // interpreted as location-list pointers. Interpreting constants as + // pointers is not expected, so we use DW_FORM_udata to encode the + // constants here. + if (DD->getDwarfVersion() == 3) + addUInt(MemberDie, dwarf::DW_AT_data_member_location, + dwarf::DW_FORM_udata, OffsetInBytes); + else + addUInt(MemberDie, dwarf::DW_AT_data_member_location, std::nullopt, + OffsetInBytes); + } } } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 5e5ff22132e99..d5eb7851c2aae 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -326,21 +326,22 @@ DIStringType *DIBuilder::createStringType(StringRef Name, } DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) { - return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, 0, - 0, 0, std::nullopt, std::nullopt, DINode::FlagZero); + return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, + (uint64_t)0, 0, (uint64_t)0, std::nullopt, + std::nullopt, DINode::FlagZero); } DIDerivedType *DIBuilder::createPtrAuthQualifiedType( DIType *FromTy, unsigned Key, bool IsAddressDiscriminated, unsigned ExtraDiscriminator, bool IsaPointer, bool AuthenticatesNullValues) { - return DIDerivedType::get(VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, "", - nullptr, 0, nullptr, FromTy, 0, 0, 0, std::nullopt, - std::optional( - std::in_place, Key, IsAddressDiscriminated, - ExtraDiscriminator, IsaPointer, - AuthenticatesNullValues), - DINode::FlagZero); + return DIDerivedType::get( + VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, "", nullptr, 0, nullptr, + FromTy, (uint64_t)0, 0, (uint64_t)0, std::nullopt, + std::optional( + std::in_place, Key, IsAddressDiscriminated, ExtraDiscriminator, + IsaPointer, AuthenticatesNullValues), + DINode::FlagZero); } DIDerivedType * @@ -382,9 +383,9 @@ DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name, DINode::DIFlags Flags, DINodeArray Annotations) { return DIDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File, - LineNo, getNonCompileUnitScope(Context), Ty, 0, - AlignInBits, 0, std::nullopt, std::nullopt, Flags, - nullptr, Annotations); + LineNo, getNonCompileUnitScope(Context), Ty, + (uint64_t)0, AlignInBits, (uint64_t)0, std::nullopt, + std::nullopt, Flags, nullptr, Annotations); } DIDerivedType * @@ -393,17 +394,17 @@ DIBuilder::createTemplateAlias(DIType *Ty, StringRef Name, DIFile *File, DINodeArray TParams, uint32_t AlignInBits, DINode::DIFlags Flags, DINodeArray Annotations) { return DIDerivedType::get(VMContext, dwarf::DW_TAG_template_alias, Name, File, - LineNo, getNonCompileUnitScope(Context), Ty, 0, - AlignInBits, 0, std::nullopt, std::nullopt, Flags, - TParams.get(), Annotations); + LineNo, getNonCompileUnitScope(Context), Ty, + (uint64_t)0, AlignInBits, (uint64_t)0, std::nullopt, + std::nullopt, Flags, TParams.get(), Annotations); } DIDerivedType *DIBuilder::createFriend(DIType *Ty, DIType *FriendTy) { assert(Ty && "Invalid type!"); assert(FriendTy && "Invalid friend type!"); return DIDerivedType::get(VMContext, dwarf::DW_TAG_friend, "", nullptr, 0, Ty, - FriendTy, 0, 0, 0, std::nullopt, std::nullopt, - DINode::FlagZero); + FriendTy, (uint64_t)0, 0, (uint64_t)0, std::nullopt, + std::nullopt, DINode::FlagZero); } DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy, @@ -428,6 +429,16 @@ DIDerivedType *DIBuilder::createMemberType( std::nullopt, Flags, nullptr, Annotations); } +DIDerivedType *DIBuilder::createMemberType( + DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, + Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits, + DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) { + return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, + LineNumber, getNonCompileUnitScope(Scope), Ty, + SizeInBits, AlignInBits, OffsetInBits, std::nullopt, + std::nullopt, Flags, nullptr, Annotations); +} + static ConstantAsMetadata *getConstantOrNull(Constant *C) { if (C) return ConstantAsMetadata::get(C); @@ -452,14 +463,29 @@ DIDerivedType *DIBuilder::createVariantMemberType(DIScope *Scope, Constant *Discriminant, DIType *Ty) { auto *V = DICompositeType::get(VMContext, dwarf::DW_TAG_variant, {}, nullptr, - 0, getNonCompileUnitScope(Scope), {}, 0, 0, 0, - DINode::FlagZero, Elements, 0, {}, nullptr); + 0, getNonCompileUnitScope(Scope), {}, + (uint64_t)0, 0, (uint64_t)0, DINode::FlagZero, + Elements, 0, {}, nullptr); trackIfUnresolved(V); return createVariantMemberType(Scope, {}, nullptr, 0, 0, 0, 0, Discriminant, DINode::FlagZero, V); } +DIDerivedType *DIBuilder::createBitFieldMemberType( + DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, + Metadata *SizeInBits, Metadata *OffsetInBits, uint64_t StorageOffsetInBits, + DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) { + Flags |= DINode::FlagBitField; + return DIDerivedType::get( + VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, + getNonCompileUnitScope(Scope), Ty, SizeInBits, /*AlignInBits=*/0, + OffsetInBits, std::nullopt, std::nullopt, Flags, + ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(VMContext, 64), + StorageOffsetInBits)), + Annotations); +} + DIDerivedType *DIBuilder::createBitFieldMemberType( DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint64_t OffsetInBits, uint64_t StorageOffsetInBits, @@ -481,9 +507,9 @@ DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned Tag, uint32_t AlignInBits) { Flags |= DINode::FlagStaticMember; return DIDerivedType::get(VMContext, Tag, Name, File, LineNumber, - getNonCompileUnitScope(Scope), Ty, 0, AlignInBits, - 0, std::nullopt, std::nullopt, Flags, - getConstantOrNull(Val)); + getNonCompileUnitScope(Scope), Ty, (uint64_t)0, + AlignInBits, (uint64_t)0, std::nullopt, + std::nullopt, Flags, getConstantOrNull(Val)); } DIDerivedType * @@ -564,6 +590,22 @@ DICompositeType *DIBuilder::createClassType( return R; } +DICompositeType *DIBuilder::createStructType( + DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber, + Metadata *SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags, + DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang, + DIType *VTableHolder, StringRef UniqueIdentifier, DIType *Specification, + uint32_t NumExtraInhabitants) { + auto *R = DICompositeType::get( + VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber, + getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0, + Flags, Elements, RunTimeLang, /*EnumKind=*/std::nullopt, VTableHolder, + nullptr, UniqueIdentifier, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, Specification, NumExtraInhabitants); + trackIfUnresolved(R); + return R; +} + DICompositeType *DIBuilder::createStructType( DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags, diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 473114b99225b..44b0f0d50067c 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -825,25 +825,23 @@ DIGenericSubrange::BoundType DIGenericSubrange::getStride() const { } DISubrangeType::DISubrangeType(LLVMContext &C, StorageType Storage, - unsigned Line, uint64_t SizeInBits, - uint32_t AlignInBits, DIFlags Flags, - ArrayRef Ops) + unsigned Line, uint32_t AlignInBits, + DIFlags Flags, ArrayRef Ops) : DIType(C, DISubrangeTypeKind, Storage, dwarf::DW_TAG_subrange_type, Line, - SizeInBits, AlignInBits, 0, 0, Flags, Ops) {} + AlignInBits, 0, Flags, Ops) {} DISubrangeType *DISubrangeType::getImpl( LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line, - Metadata *Scope, uint64_t SizeInBits, uint32_t AlignInBits, DIFlags Flags, + Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits, DIFlags Flags, Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride, Metadata *Bias, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DISubrangeType, (Name, File, Line, Scope, SizeInBits, AlignInBits, Flags, BaseType, LowerBound, UpperBound, Stride, Bias)); - Metadata *Ops[] = {File, Scope, Name, BaseType, - LowerBound, UpperBound, Stride, Bias}; - DEFINE_GETIMPL_STORE(DISubrangeType, (Line, SizeInBits, AlignInBits, Flags), - Ops); + Metadata *Ops[] = {File, Scope, Name, SizeInBits, nullptr, + BaseType, LowerBound, UpperBound, Stride, Bias}; + DEFINE_GETIMPL_STORE(DISubrangeType, (Line, AlignInBits, Flags), Ops); } DISubrangeType::BoundType @@ -883,18 +881,17 @@ DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value, } DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag, - MDString *Name, uint64_t SizeInBits, + MDString *Name, Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, DIFlags Flags, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIBasicType, (Tag, Name, SizeInBits, AlignInBits, Encoding, NumExtraInhabitants, Flags)); - Metadata *Ops[] = {nullptr, nullptr, Name}; - DEFINE_GETIMPL_STORE( - DIBasicType, - (Tag, SizeInBits, AlignInBits, Encoding, NumExtraInhabitants, Flags), - Ops); + Metadata *Ops[] = {nullptr, nullptr, Name, SizeInBits, nullptr}; + DEFINE_GETIMPL_STORE(DIBasicType, + (Tag, AlignInBits, Encoding, NumExtraInhabitants, Flags), + Ops); } std::optional DIBasicType::getSignedness() const { @@ -914,18 +911,18 @@ std::optional DIBasicType::getSignedness() const { DIFixedPointType * DIFixedPointType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, - uint64_t SizeInBits, uint32_t AlignInBits, + Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding, DIFlags Flags, unsigned Kind, int Factor, APInt Numerator, APInt Denominator, StorageType Storage, bool ShouldCreate) { DEFINE_GETIMPL_LOOKUP(DIFixedPointType, (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags, Kind, Factor, Numerator, Denominator)); - Metadata *Ops[] = {nullptr, nullptr, Name}; - DEFINE_GETIMPL_STORE(DIFixedPointType, - (Tag, SizeInBits, AlignInBits, Encoding, Flags, Kind, - Factor, Numerator, Denominator), - Ops); + Metadata *Ops[] = {nullptr, nullptr, Name, SizeInBits, nullptr}; + DEFINE_GETIMPL_STORE( + DIFixedPointType, + (Tag, AlignInBits, Encoding, Flags, Kind, Factor, Numerator, Denominator), + Ops); } bool DIFixedPointType::isSigned() const { @@ -957,17 +954,17 @@ DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *StringLength, Metadata *StringLengthExp, Metadata *StringLocationExp, - uint64_t SizeInBits, uint32_t AlignInBits, + Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIStringType, (Tag, Name, StringLength, StringLengthExp, StringLocationExp, SizeInBits, AlignInBits, Encoding)); - Metadata *Ops[] = {nullptr, nullptr, Name, - StringLength, StringLengthExp, StringLocationExp}; - DEFINE_GETIMPL_STORE(DIStringType, (Tag, SizeInBits, AlignInBits, Encoding), - Ops); + Metadata *Ops[] = {nullptr, nullptr, Name, + SizeInBits, nullptr, StringLength, + StringLengthExp, StringLocationExp}; + DEFINE_GETIMPL_STORE(DIStringType, (Tag, AlignInBits, Encoding), Ops); } DIType *DIDerivedType::getClassType() const { assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); @@ -1004,8 +1001,8 @@ Constant *DIDerivedType::getDiscriminantValue() const { DIDerivedType *DIDerivedType::getImpl( LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, - unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, + unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits, + uint32_t AlignInBits, Metadata *OffsetInBits, std::optional DWARFAddressSpace, std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData, Metadata *Annotations, StorageType Storage, bool ShouldCreate) { @@ -1014,11 +1011,11 @@ DIDerivedType *DIDerivedType::getImpl( (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData, Flags, ExtraData, Annotations)); - Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData, Annotations}; - DEFINE_GETIMPL_STORE(DIDerivedType, - (Tag, Line, SizeInBits, AlignInBits, OffsetInBits, - DWARFAddressSpace, PtrAuthData, Flags), - Ops); + Metadata *Ops[] = {File, Scope, Name, SizeInBits, + OffsetInBits, BaseType, ExtraData, Annotations}; + DEFINE_GETIMPL_STORE( + DIDerivedType, + (Tag, Line, AlignInBits, DWARFAddressSpace, PtrAuthData, Flags), Ops); } std::optional @@ -1030,8 +1027,8 @@ DIDerivedType::getPtrAuthData() const { DICompositeType *DICompositeType::getImpl( LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, - unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, + unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits, + uint32_t AlignInBits, Metadata *OffsetInBits, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, std::optional EnumKind, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, @@ -1047,20 +1044,21 @@ DICompositeType *DICompositeType::getImpl( OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, Annotations, Specification, NumExtraInhabitants, BitStride)); - Metadata *Ops[] = {File, Scope, Name, BaseType, - Elements, VTableHolder, TemplateParams, Identifier, - Discriminator, DataLocation, Associated, Allocated, - Rank, Annotations, Specification, BitStride}; + Metadata *Ops[] = {File, Scope, Name, SizeInBits, + OffsetInBits, BaseType, Elements, VTableHolder, + TemplateParams, Identifier, Discriminator, DataLocation, + Associated, Allocated, Rank, Annotations, + Specification, BitStride}; DEFINE_GETIMPL_STORE(DICompositeType, - (Tag, Line, RuntimeLang, SizeInBits, AlignInBits, - OffsetInBits, NumExtraInhabitants, EnumKind, Flags), + (Tag, Line, RuntimeLang, AlignInBits, + NumExtraInhabitants, EnumKind, Flags), Ops); } DICompositeType *DICompositeType::buildODRType( LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, - uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, + Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits, Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, std::optional EnumKind, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, @@ -1086,12 +1084,13 @@ DICompositeType *DICompositeType::buildODRType( return CT; // Mutate CT in place. Keep this in sync with getImpl. - CT->mutate(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, - NumExtraInhabitants, EnumKind, Flags); - Metadata *Ops[] = {File, Scope, Name, BaseType, - Elements, VTableHolder, TemplateParams, &Identifier, - Discriminator, DataLocation, Associated, Allocated, - Rank, Annotations, Specification, BitStride}; + CT->mutate(Tag, Line, RuntimeLang, AlignInBits, NumExtraInhabitants, EnumKind, + Flags); + Metadata *Ops[] = {File, Scope, Name, SizeInBits, + OffsetInBits, BaseType, Elements, VTableHolder, + TemplateParams, &Identifier, Discriminator, DataLocation, + Associated, Allocated, Rank, Annotations, + Specification, BitStride}; assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() && "Mismatched number of operands"); for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I) @@ -1103,7 +1102,7 @@ DICompositeType *DICompositeType::buildODRType( DICompositeType *DICompositeType::getODRType( LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, - uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, + Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits, Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, std::optional EnumKind, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, @@ -1138,7 +1137,7 @@ DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags, uint8_t CC, ArrayRef Ops) : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0, - 0, 0, 0, 0, Flags, Ops), + 0, 0, Flags, Ops), CC(CC) {} DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags, @@ -1146,7 +1145,7 @@ DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags, StorageType Storage, bool ShouldCreate) { DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, CC, TypeArray)); - Metadata *Ops[] = {nullptr, nullptr, nullptr, TypeArray}; + Metadata *Ops[] = {nullptr, nullptr, nullptr, nullptr, nullptr, TypeArray}; DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops); } diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 21f5c06ea24f3..3e55ff884966c 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -488,27 +488,28 @@ template <> struct MDNodeKeyImpl { template <> struct MDNodeKeyImpl { unsigned Tag; MDString *Name; - uint64_t SizeInBits; + Metadata *SizeInBits; uint32_t AlignInBits; unsigned Encoding; uint32_t NumExtraInhabitants; unsigned Flags; - MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits, + MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, unsigned Flags) : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding), NumExtraInhabitants(NumExtraInhabitants), Flags(Flags) {} MDNodeKeyImpl(const DIBasicType *N) - : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()), - AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()), + : Tag(N->getTag()), Name(N->getRawName()), + SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()), + Encoding(N->getEncoding()), NumExtraInhabitants(N->getNumExtraInhabitants()), Flags(N->getFlags()) { } bool isKeyOf(const DIBasicType *RHS) const { return Tag == RHS->getTag() && Name == RHS->getRawName() && - SizeInBits == RHS->getSizeInBits() && + SizeInBits == RHS->getRawSizeInBits() && AlignInBits == RHS->getAlignInBits() && Encoding == RHS->getEncoding() && NumExtraInhabitants == RHS->getNumExtraInhabitants() && @@ -523,7 +524,7 @@ template <> struct MDNodeKeyImpl { template <> struct MDNodeKeyImpl { unsigned Tag; MDString *Name; - uint64_t SizeInBits; + Metadata *SizeInBits; uint32_t AlignInBits; unsigned Encoding; unsigned Flags; @@ -532,20 +533,21 @@ template <> struct MDNodeKeyImpl { APInt Numerator; APInt Denominator; - MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits, + MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding, unsigned Flags, unsigned Kind, int Factor, APInt Numerator, APInt Denominator) : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding), Flags(Flags), Kind(Kind), Factor(Factor), Numerator(Numerator), Denominator(Denominator) {} MDNodeKeyImpl(const DIFixedPointType *N) - : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()), - AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()), - Flags(N->getFlags()), Kind(N->getKind()), Factor(N->getFactorRaw()), - Numerator(N->getNumeratorRaw()), Denominator(N->getDenominatorRaw()) {} + : Tag(N->getTag()), Name(N->getRawName()), + SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()), + Encoding(N->getEncoding()), Flags(N->getFlags()), Kind(N->getKind()), + Factor(N->getFactorRaw()), Numerator(N->getNumeratorRaw()), + Denominator(N->getDenominatorRaw()) {} bool isKeyOf(const DIFixedPointType *RHS) const { - return Name == RHS->getRawName() && SizeInBits == RHS->getSizeInBits() && + return Name == RHS->getRawName() && SizeInBits == RHS->getRawSizeInBits() && AlignInBits == RHS->getAlignInBits() && Kind == RHS->getKind() && (RHS->isRational() ? (Numerator == RHS->getNumerator() && Denominator == RHS->getDenominator()) @@ -563,13 +565,13 @@ template <> struct MDNodeKeyImpl { Metadata *StringLength; Metadata *StringLengthExp; Metadata *StringLocationExp; - uint64_t SizeInBits; + Metadata *SizeInBits; uint32_t AlignInBits; unsigned Encoding; MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength, Metadata *StringLengthExp, Metadata *StringLocationExp, - uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding) + Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding) : Tag(Tag), Name(Name), StringLength(StringLength), StringLengthExp(StringLengthExp), StringLocationExp(StringLocationExp), SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding) {} @@ -578,7 +580,7 @@ template <> struct MDNodeKeyImpl { StringLength(N->getRawStringLength()), StringLengthExp(N->getRawStringLengthExp()), StringLocationExp(N->getRawStringLocationExp()), - SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()), + SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()) {} bool isKeyOf(const DIStringType *RHS) const { @@ -586,7 +588,7 @@ template <> struct MDNodeKeyImpl { StringLength == RHS->getRawStringLength() && StringLengthExp == RHS->getRawStringLengthExp() && StringLocationExp == RHS->getRawStringLocationExp() && - SizeInBits == RHS->getSizeInBits() && + SizeInBits == RHS->getRawSizeInBits() && AlignInBits == RHS->getAlignInBits() && Encoding == RHS->getEncoding(); } @@ -606,8 +608,8 @@ template <> struct MDNodeKeyImpl { unsigned Line; Metadata *Scope; Metadata *BaseType; - uint64_t SizeInBits; - uint64_t OffsetInBits; + Metadata *SizeInBits; + Metadata *OffsetInBits; uint32_t AlignInBits; std::optional DWARFAddressSpace; std::optional PtrAuthData; @@ -616,8 +618,8 @@ template <> struct MDNodeKeyImpl { Metadata *Annotations; MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, - Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, + Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits, + uint32_t AlignInBits, Metadata *OffsetInBits, std::optional DWARFAddressSpace, std::optional PtrAuthData, unsigned Flags, Metadata *ExtraData, Metadata *Annotations) @@ -629,8 +631,8 @@ template <> struct MDNodeKeyImpl { MDNodeKeyImpl(const DIDerivedType *N) : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), - BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), - OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()), + BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()), + OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()), DWARFAddressSpace(N->getDWARFAddressSpace()), PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()), ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {} @@ -639,9 +641,9 @@ template <> struct MDNodeKeyImpl { return Tag == RHS->getTag() && Name == RHS->getRawName() && File == RHS->getRawFile() && Line == RHS->getLine() && Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() && - SizeInBits == RHS->getSizeInBits() && + SizeInBits == RHS->getRawSizeInBits() && AlignInBits == RHS->getAlignInBits() && - OffsetInBits == RHS->getOffsetInBits() && + OffsetInBits == RHS->getRawOffsetInBits() && DWARFAddressSpace == RHS->getDWARFAddressSpace() && PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() && ExtraData == RHS->getRawExtraData() && @@ -670,7 +672,7 @@ template <> struct MDNodeKeyImpl { Metadata *File; unsigned Line; Metadata *Scope; - uint64_t SizeInBits; + Metadata *SizeInBits; uint32_t AlignInBits; unsigned Flags; Metadata *BaseType; @@ -680,7 +682,7 @@ template <> struct MDNodeKeyImpl { Metadata *Bias; MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, - uint64_t SizeInBits, uint32_t AlignInBits, unsigned Flags, + Metadata *SizeInBits, uint32_t AlignInBits, unsigned Flags, Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride, Metadata *Bias) : Name(Name), File(File), Line(Line), Scope(Scope), @@ -689,7 +691,7 @@ template <> struct MDNodeKeyImpl { Stride(Stride), Bias(Bias) {} MDNodeKeyImpl(const DISubrangeType *N) : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), - Scope(N->getRawScope()), SizeInBits(N->getSizeInBits()), + Scope(N->getRawScope()), SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()), Flags(N->getFlags()), BaseType(N->getRawBaseType()), LowerBound(N->getRawLowerBound()), UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()), @@ -713,7 +715,7 @@ template <> struct MDNodeKeyImpl { return Name == RHS->getRawName() && File == RHS->getRawFile() && Line == RHS->getLine() && Scope == RHS->getRawScope() && - SizeInBits == RHS->getSizeInBits() && + SizeInBits == RHS->getRawSizeInBits() && AlignInBits == RHS->getAlignInBits() && Flags == RHS->getFlags() && BaseType == RHS->getRawBaseType() && BoundsEqual(LowerBound, RHS->getRawLowerBound()) && @@ -781,8 +783,8 @@ template <> struct MDNodeKeyImpl { unsigned Line; Metadata *Scope; Metadata *BaseType; - uint64_t SizeInBits; - uint64_t OffsetInBits; + Metadata *SizeInBits; + Metadata *OffsetInBits; uint32_t AlignInBits; unsigned Flags; Metadata *Elements; @@ -801,8 +803,8 @@ template <> struct MDNodeKeyImpl { Metadata *BitStride; MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, - Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, + Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits, + uint32_t AlignInBits, Metadata *OffsetInBits, unsigned Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, @@ -822,8 +824,8 @@ template <> struct MDNodeKeyImpl { MDNodeKeyImpl(const DICompositeType *N) : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), - BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), - OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()), + BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()), + OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()), Flags(N->getFlags()), Elements(N->getRawElements()), RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()), TemplateParams(N->getRawTemplateParams()), @@ -840,10 +842,10 @@ template <> struct MDNodeKeyImpl { return Tag == RHS->getTag() && Name == RHS->getRawName() && File == RHS->getRawFile() && Line == RHS->getLine() && Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() && - SizeInBits == RHS->getSizeInBits() && + SizeInBits == RHS->getRawSizeInBits() && AlignInBits == RHS->getAlignInBits() && - OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() && - Elements == RHS->getRawElements() && + OffsetInBits == RHS->getRawOffsetInBits() && + Flags == RHS->getFlags() && Elements == RHS->getRawElements() && RuntimeLang == RHS->getRuntimeLang() && VTableHolder == RHS->getRawVTableHolder() && TemplateParams == RHS->getRawTemplateParams() && diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index fdb4ddaafbbcc..a58034f6451cb 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1173,6 +1173,10 @@ void Verifier::visitDISubrangeType(const DISubrangeType &N) { CheckDI(!Bias || isa(Bias) || isa(Bias) || isa(Bias), "Bias must be signed constant or DIVariable or DIExpression", &N); + // Subrange types currently only support constant size. + auto *Size = N.getRawSizeInBits(); + CheckDI(!Size || isa(Size), + "SizeInBits must be a constant"); } void Verifier::visitDISubrange(const DISubrange &N) { @@ -1234,6 +1238,10 @@ void Verifier::visitDIBasicType(const DIBasicType &N) { N.getTag() == dwarf::DW_TAG_unspecified_type || N.getTag() == dwarf::DW_TAG_string_type, "invalid tag", &N); + // Basic types currently only support constant size. + auto *Size = N.getRawSizeInBits(); + CheckDI(!Size || isa(Size), + "SizeInBits must be a constant"); } void Verifier::visitDIFixedPointType(const DIFixedPointType &N) { @@ -1314,6 +1322,11 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) { "DWARF address space only applies to pointer or reference types", &N); } + + auto *Size = N.getRawSizeInBits(); + CheckDI(!Size || isa(Size) || isa(Size) || + isa(Size), + "SizeInBits must be a constant or DIVariable or DIExpression"); } /// Detect mutually exclusive flags. @@ -1401,6 +1414,11 @@ void Verifier::visitDICompositeType(const DICompositeType &N) { if (N.getTag() == dwarf::DW_TAG_array_type) { CheckDI(N.getRawBaseType(), "array types must have a base type", &N); } + + auto *Size = N.getRawSizeInBits(); + CheckDI(!Size || isa(Size) || isa(Size) || + isa(Size), + "SizeInBits must be a constant or DIVariable or DIExpression"); } void Verifier::visitDISubroutineType(const DISubroutineType &N) { diff --git a/llvm/test/DebugInfo/dynamic-bitfield.ll b/llvm/test/DebugInfo/dynamic-bitfield.ll new file mode 100644 index 0000000000000..1a5ed81774538 --- /dev/null +++ b/llvm/test/DebugInfo/dynamic-bitfield.ll @@ -0,0 +1,62 @@ +; RUN: llc -O0 -filetype=obj -o - %s | llvm-dwarfdump -v -debug-info - | FileCheck %s + +; A basic test of using a DIExpression for DW_AT_data_bit_offset and +; DW_AT_bit_size. + +source_filename = "bitfield.c" + +%struct.PackedBits = type <{ i8, i32 }> + +@s = common global %struct.PackedBits zeroinitializer, align 1, !dbg !2 +@value = common global i32 zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!4} +!llvm.module.flags = !{!17, !18, !19} +!llvm.ident = !{!20} + +!0 = distinct !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = !DIGlobalVariable(name: "value", scope: !4, file: !5, line: 8, type: !15, isLocal: false, isDefinition: true) +!2 = distinct !DIGlobalVariableExpression(var: !3, expr: !DIExpression()) +!3 = !DIGlobalVariable(name: "s", scope: !4, file: !5, line: 8, type: !8, isLocal: false, isDefinition: true) + + +!4 = distinct !DICompileUnit(language: DW_LANG_C99, file: !5, producer: "clang version 3.9.0 (trunk 267633)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !6, globals: !7) +!5 = !DIFile(filename: "bitfield.c", directory: "/Volumes/Data/llvm") +!6 = !{} +!7 = !{!0, !2} +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "PackedBits", file: !5, line: 3, size: 40, elements: !9) +!9 = !{!10, !12, !16} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !5, line: 5, baseType: !11, size: 8) +; CHECK: DW_TAG_member +; CHECK-NEXT: DW_AT_name{{.*}}"a" +; CHECK-NOT: DW_TAG +; CHECK-NOT: DW_AT_bit_offset +; CHECK-NOT: DW_AT_data_bit_offset +; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00) +!11 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!12 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !5, line: 6, baseType: !13, size: !3, offset: !3, flags: DIFlagBitField) +!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "uint32_t", file: !14, line: 183, baseType: !15) +!14 = !DIFile(filename: "/Volumes/Data/llvm/_build.ninja.release/bin/../lib/clang/3.9.0/include/stdint.h", directory: "/Volumes/Data/llvm") +!15 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +; CHECK: DW_TAG_member +; CHECK-NEXT: DW_AT_name{{.*}}"b" +; CHECK-NOT: DW_TAG +; CHECK-NOT: DW_AT_bit_offset +; CHECK-NOT: DW_AT_byte_size +; CHECK: DW_AT_bit_size [DW_FORM_ref4] ({{.*}}) +; CHECK-NEXT: DW_AT_data_bit_offset [DW_FORM_ref4] ({{.*}}) +; CHECK-NOT: DW_AT_data_member_location +!16 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !8, file: !5, line: 7, baseType: !13, size: !DIExpression(DW_OP_constu, 27), offset: !DIExpression(DW_OP_constu, 13), flags: DIFlagBitField) +!17 = !{i32 2, !"Dwarf Version", i32 4} +!18 = !{i32 2, !"Debug Info Version", i32 3} +!19 = !{i32 1, !"PIC Level", i32 2} +; CHECK: DW_TAG_member +; CHECK-NEXT: DW_AT_name{{.*}}"c" +; CHECK-NOT: DW_TAG +; CHECK-NOT: DW_AT_bit_offset +; CHECK-NOT: DW_AT_byte_size +; CHECK: DW_AT_bit_size [DW_FORM_exprloc] (DW_OP_lit27) +; CHECK-NEXT: DW_AT_data_bit_offset [DW_FORM_exprloc] (DW_OP_lit13) +; CHECK-NOT: DW_AT_data_member_location +; CHECK: DW_TAG +!20 = !{!"clang version 3.9.0 (trunk 267633)"} diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp index c3a0f665d423a..418331eb57150 100644 --- a/llvm/unittests/IR/DebugInfoTest.cpp +++ b/llvm/unittests/IR/DebugInfoTest.cpp @@ -1337,4 +1337,33 @@ TEST(DIBuilder, CompositeTypes) { EXPECT_EQ(Enum->getTag(), dwarf::DW_TAG_enumeration_type); } +TEST(DIBuilder, DynamicOffsetAndSize) { + LLVMContext Ctx; + std::unique_ptr M(new Module("MyModule", Ctx)); + DIBuilder DIB(*M); + DIScope *Scope = DISubprogram::getDistinct( + Ctx, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0, + DINode::FlagZero, DISubprogram::SPFlagZero, nullptr); + DIFile *F = DIB.createFile("main.adb", "/"); + + DIVariable *Len = DIB.createAutoVariable(Scope, "length", F, 0, nullptr, + false, DINode::FlagZero, 0); + + DICompositeType *Struct = DIB.createStructType( + Scope, "some_record", F, 18, Len, 8, DINode::FlagZero, nullptr, {}); + EXPECT_EQ(Struct->getTag(), dwarf::DW_TAG_structure_type); + + SmallVector ops; + ops.push_back(llvm::dwarf::DW_OP_push_object_address); + DIExpression::appendOffset(ops, 3); + ops.push_back(llvm::dwarf::DW_OP_deref); + DIExpression *Expr = DIB.createExpression(ops); + + DIDerivedType *Field = DIB.createMemberType(Scope, "field", F, 23, Len, 0, + Expr, DINode::FlagZero, Struct); + + EXPECT_EQ(Field->getRawOffsetInBits(), Expr); + EXPECT_EQ(Field->getRawSizeInBits(), Len); +} + } // end namespace diff --git a/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp b/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp index e1ce671852c8b..6716796e71c5a 100644 --- a/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp +++ b/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp @@ -141,12 +141,12 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { DO_FOR_FIELD(BaseType) \ DO_FOR_FIELD(Elements) \ DO_FOR_FIELD(VTableHolder) \ - DO_FOR_FIELD(TemplateParams) + DO_FOR_FIELD(TemplateParams) \ + DO_FOR_FIELD(SizeInBits) \ + DO_FOR_FIELD(OffsetInBits) #define FOR_EACH_INLINEFIELD() \ DO_FOR_FIELD(Line) \ - DO_FOR_FIELD(SizeInBits) \ DO_FOR_FIELD(AlignInBits) \ - DO_FOR_FIELD(OffsetInBits) \ DO_FOR_FIELD(NumExtraInhabitants) \ DO_FOR_FIELD(RuntimeLang) \ DO_FOR_FIELD(EnumKind)