diff options
Diffstat (limited to 'include/llvm/IR/DebugInfoMetadata.h')
-rw-r--r-- | include/llvm/IR/DebugInfoMetadata.h | 350 |
1 files changed, 219 insertions, 131 deletions
diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 456313a70e834..853a94afd9d98 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -43,21 +43,25 @@ namespace llvm { -/// \brief Pointer union between a subclass of DINode and MDString. +template <typename T> class Optional; + +/// Holds a subclass of DINode. /// -/// \a DICompositeType can be referenced via an \a MDString unique identifier. -/// This class allows some type safety in the face of that, requiring either a -/// node of a particular type or an \a MDString. +/// FIXME: This class doesn't currently make much sense. Previously it was a +/// union beteen MDString (for ODR-uniqued types) and things like DIType. To +/// support CodeView work, it wasn't deleted outright when MDString-based type +/// references were deleted; we'll soon need a similar concept for CodeView +/// DITypeIndex. template <class T> class TypedDINodeRef { const Metadata *MD = nullptr; public: TypedDINodeRef() = default; TypedDINodeRef(std::nullptr_t) {} + TypedDINodeRef(const T *MD) : MD(MD) {} - /// \brief Construct from a raw pointer. explicit TypedDINodeRef(const Metadata *MD) : MD(MD) { - assert((!MD || isa<MDString>(MD) || isa<T>(MD)) && "Expected valid ref"); + assert((!MD || isa<T>(MD)) && "Expected valid type ref"); } template <class U> @@ -69,26 +73,10 @@ public: operator Metadata *() const { return const_cast<Metadata *>(MD); } + T *resolve() const { return const_cast<T *>(cast_or_null<T>(MD)); } + bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; } bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; } - - /// \brief Create a reference. - /// - /// Get a reference to \c N, using an \a MDString reference if available. - static TypedDINodeRef get(const T *N); - - template <class MapTy> T *resolve(const MapTy &Map) const { - if (!MD) - return nullptr; - - if (auto *Typed = dyn_cast<T>(MD)) - return const_cast<T *>(Typed); - - auto *S = cast<MDString>(MD); - auto I = Map.find(S); - assert(I != Map.end() && "Missing identifier in type map"); - return cast<T>(I->second); - } }; typedef TypedDINodeRef<DINode> DINodeRef; @@ -173,6 +161,9 @@ protected: return MDString::get(Context, S); } + /// Allow subclasses to mutate the tag. + void setTag(unsigned Tag) { SubclassData16 = Tag; } + public: unsigned getTag() const { return SubclassData16; } @@ -183,7 +174,9 @@ public: enum DIFlags { #define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID, #include "llvm/IR/DebugInfoFlags.def" - FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic + FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic, + FlagPtrToMemberRep = FlagSingleInheritance | FlagMultipleInheritance | + FlagVirtualInheritance, }; static unsigned getFlag(StringRef Flag); @@ -196,8 +189,6 @@ public: static unsigned splitFlags(unsigned Flags, SmallVectorImpl<unsigned> &SplitFlags); - DINodeRef getRef() const { return DINodeRef::get(this); } - static bool classof(const Metadata *MD) { switch (MD->getMetadataID()) { default: @@ -291,6 +282,7 @@ public: unsigned getTag() const { return SubclassData16; } StringRef getHeader() const { return getStringOperand(0); } + MDString *getRawHeader() const { return getOperandAs<MDString>(0); } op_iterator dwarf_op_begin() const { return op_begin() + 1; } op_iterator dwarf_op_end() const { return op_end(); } @@ -431,8 +423,6 @@ public: : static_cast<Metadata *>(getOperand(0)); } - DIScopeRef getRef() const { return DIScopeRef::get(this); } - static bool classof(const Metadata *MD) { switch (MD->getMetadataID()) { default: @@ -527,11 +517,28 @@ protected: DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops) - : DIScope(C, ID, Storage, Tag, Ops), Line(Line), Flags(Flags), - SizeInBits(SizeInBits), AlignInBits(AlignInBits), - OffsetInBits(OffsetInBits) {} + : DIScope(C, ID, Storage, Tag, Ops) { + init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags); + } ~DIType() = default; + void init(unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags) { + this->Line = Line; + this->Flags = Flags; + this->SizeInBits = SizeInBits; + this->AlignInBits = AlignInBits; + this->OffsetInBits = OffsetInBits; + } + + /// Change fields in place. + void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits, + uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags) { + assert(isDistinct() && "Only distinct nodes can mutate"); + setTag(Tag); + init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags); + } + public: TempDIType clone() const { return TempDIType(cast<DIType>(MDNode::clone().release())); @@ -574,13 +581,12 @@ public: return getFlags() & FlagObjcClassComplete; } bool isVector() const { return getFlags() & FlagVector; } + bool isBitField() const { return getFlags() & FlagBitField; } bool isStaticMember() const { return getFlags() & FlagStaticMember; } bool isLValueReference() const { return getFlags() & FlagLValueReference; } bool isRValueReference() const { return getFlags() & FlagRValueReference; } bool isExternalTypeRef() const { return getFlags() & FlagExternalTypeRef; } - DITypeRef getRef() const { return DITypeRef::get(this); } - static bool classof(const Metadata *MD) { switch (MD->getMetadataID()) { default: @@ -735,6 +741,12 @@ public: DIObjCProperty *getObjCProperty() const { return dyn_cast_or_null<DIObjCProperty>(getExtraData()); } + Constant *getStorageOffsetInBits() const { + assert(getTag() == dwarf::DW_TAG_member && isBitField()); + if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData())) + return C->getValue(); + return nullptr; + } Constant *getConstant() const { assert(getTag() == dwarf::DW_TAG_member && isStaticMember()); if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData())) @@ -767,6 +779,16 @@ class DICompositeType : public DIType { RuntimeLang(RuntimeLang) {} ~DICompositeType() = default; + /// Change fields in place. + void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang, + uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, + unsigned Flags) { + assert(isDistinct() && "Only distinct nodes can mutate"); + assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate"); + this->RuntimeLang = RuntimeLang; + DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags); + } + static DICompositeType * getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File, unsigned Line, DIScopeRef Scope, DITypeRef BaseType, @@ -822,6 +844,40 @@ public: TempDICompositeType clone() const { return cloneImpl(); } + /// Get a DICompositeType with the given ODR identifier. + /// + /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped + /// DICompositeType for the given ODR \c Identifier. If none exists, creates + /// a new node. + /// + /// Else, returns \c nullptr. + static DICompositeType * + getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, + MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, + Metadata *BaseType, uint64_t SizeInBits, uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags, Metadata *Elements, + unsigned RuntimeLang, Metadata *VTableHolder, + Metadata *TemplateParams); + static DICompositeType *getODRTypeIfExists(LLVMContext &Context, + MDString &Identifier); + + /// Build a DICompositeType with the given ODR identifier. + /// + /// Looks up the mapped DICompositeType for the given ODR \c Identifier. If + /// it doesn't exist, creates a new one. If it does exist and \a + /// isForwardDecl(), and the new arguments would be a definition, mutates the + /// the type in place. In either case, returns the type. + /// + /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns + /// nullptr. + static DICompositeType * + buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, + MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, + Metadata *BaseType, uint64_t SizeInBits, uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags, Metadata *Elements, + unsigned RuntimeLang, Metadata *VTableHolder, + Metadata *TemplateParams); + DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); } DINodeArray getElements() const { return cast_or_null<MDTuple>(getRawElements()); @@ -866,14 +922,6 @@ public: } }; -template <class T> TypedDINodeRef<T> TypedDINodeRef<T>::get(const T *N) { - if (N) - if (auto *Composite = dyn_cast<DICompositeType>(N)) - if (auto *S = Composite->getRawIdentifier()) - return TypedDINodeRef<T>(S); - return TypedDINodeRef<T>(N); -} - /// \brief Type array for a subprogram. /// /// TODO: Fold the array of types in directly as operands. @@ -881,35 +929,44 @@ class DISubroutineType : public DIType { friend class LLVMContextImpl; friend class MDNode; + /// The calling convention used with DW_AT_calling_convention. Actually of + /// type dwarf::CallingConvention. + uint8_t CC; + DISubroutineType(LLVMContext &C, StorageType Storage, unsigned Flags, - ArrayRef<Metadata *> Ops) + uint8_t CC, ArrayRef<Metadata *> Ops) : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, - 0, 0, 0, 0, Flags, Ops) {} + 0, 0, 0, 0, Flags, Ops), + CC(CC) {} ~DISubroutineType() = default; static DISubroutineType *getImpl(LLVMContext &Context, unsigned Flags, - DITypeRefArray TypeArray, + uint8_t CC, DITypeRefArray TypeArray, StorageType Storage, bool ShouldCreate = true) { - return getImpl(Context, Flags, TypeArray.get(), Storage, ShouldCreate); + return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate); } static DISubroutineType *getImpl(LLVMContext &Context, unsigned Flags, - Metadata *TypeArray, StorageType Storage, + uint8_t CC, Metadata *TypeArray, + StorageType Storage, bool ShouldCreate = true); TempDISubroutineType cloneImpl() const { - return getTemporary(getContext(), getFlags(), getTypeArray()); + return getTemporary(getContext(), getFlags(), getCC(), getTypeArray()); } public: DEFINE_MDNODE_GET(DISubroutineType, - (unsigned Flags, DITypeRefArray TypeArray), - (Flags, TypeArray)) - DEFINE_MDNODE_GET(DISubroutineType, (unsigned Flags, Metadata *TypeArray), - (Flags, TypeArray)) + (unsigned Flags, uint8_t CC, DITypeRefArray TypeArray), + (Flags, CC, TypeArray)) + DEFINE_MDNODE_GET(DISubroutineType, + (unsigned Flags, uint8_t CC, Metadata *TypeArray), + (Flags, CC, TypeArray)) TempDISubroutineType clone() const { return cloneImpl(); } + uint8_t getCC() const { return CC; } + DITypeRefArray getTypeArray() const { return cast_or_null<MDTuple>(getRawTypeArray()); } @@ -924,7 +981,17 @@ public: class DICompileUnit : public DIScope { friend class LLVMContextImpl; friend class MDNode; +public: + enum DebugEmissionKind : unsigned { + NoDebug = 0, + FullDebug, + LineTablesOnly, + LastEmissionKind = LineTablesOnly + }; + static Optional<DebugEmissionKind> getEmissionKind(StringRef Str); + static const char *EmissionKindString(DebugEmissionKind EK); +private: unsigned SourceLanguage; bool IsOptimized; unsigned RuntimeVersion; @@ -947,33 +1014,30 @@ class DICompileUnit : public DIScope { StringRef Producer, bool IsOptimized, StringRef Flags, unsigned RuntimeVersion, StringRef SplitDebugFilename, unsigned EmissionKind, DICompositeTypeArray EnumTypes, - DITypeArray RetainedTypes, DISubprogramArray Subprograms, - DIGlobalVariableArray GlobalVariables, + DIScopeArray RetainedTypes, DIGlobalVariableArray GlobalVariables, DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, uint64_t DWOId, StorageType Storage, bool ShouldCreate = true) { - return getImpl(Context, SourceLanguage, File, - getCanonicalMDString(Context, Producer), IsOptimized, - getCanonicalMDString(Context, Flags), RuntimeVersion, - getCanonicalMDString(Context, SplitDebugFilename), - EmissionKind, EnumTypes.get(), RetainedTypes.get(), - Subprograms.get(), GlobalVariables.get(), - ImportedEntities.get(), Macros.get(), DWOId, Storage, - ShouldCreate); + return getImpl( + Context, SourceLanguage, File, getCanonicalMDString(Context, Producer), + IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion, + getCanonicalMDString(Context, SplitDebugFilename), EmissionKind, + EnumTypes.get(), RetainedTypes.get(), GlobalVariables.get(), + ImportedEntities.get(), Macros.get(), DWOId, Storage, ShouldCreate); } static DICompileUnit * getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File, MDString *Producer, bool IsOptimized, MDString *Flags, unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, - Metadata *Subprograms, Metadata *GlobalVariables, - Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, - StorageType Storage, bool ShouldCreate = true); + Metadata *GlobalVariables, Metadata *ImportedEntities, + Metadata *Macros, uint64_t DWOId, StorageType Storage, + bool ShouldCreate = true); TempDICompileUnit cloneImpl() const { return getTemporary( getContext(), getSourceLanguage(), getFile(), getProducer(), isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(), - getEmissionKind(), getEnumTypes(), getRetainedTypes(), getSubprograms(), + getEmissionKind(), getEnumTypes(), getRetainedTypes(), getGlobalVariables(), getImportedEntities(), getMacros(), DWOId); } @@ -985,24 +1049,23 @@ public: DICompileUnit, (unsigned SourceLanguage, DIFile *File, StringRef Producer, bool IsOptimized, StringRef Flags, unsigned RuntimeVersion, - StringRef SplitDebugFilename, unsigned EmissionKind, - DICompositeTypeArray EnumTypes, DITypeArray RetainedTypes, - DISubprogramArray Subprograms, DIGlobalVariableArray GlobalVariables, + StringRef SplitDebugFilename, DebugEmissionKind EmissionKind, + DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes, + DIGlobalVariableArray GlobalVariables, DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, uint64_t DWOId), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, - SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, Subprograms, + SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId)) DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( DICompileUnit, (unsigned SourceLanguage, Metadata *File, MDString *Producer, bool IsOptimized, MDString *Flags, unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, - Metadata *RetainedTypes, Metadata *Subprograms, - Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, - uint64_t DWOId), + Metadata *RetainedTypes, Metadata *GlobalVariables, + Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, - SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, Subprograms, + SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId)) TempDICompileUnit clone() const { return cloneImpl(); } @@ -1010,19 +1073,18 @@ public: unsigned getSourceLanguage() const { return SourceLanguage; } bool isOptimized() const { return IsOptimized; } unsigned getRuntimeVersion() const { return RuntimeVersion; } - unsigned getEmissionKind() const { return EmissionKind; } + DebugEmissionKind getEmissionKind() const { + return (DebugEmissionKind)EmissionKind; + } StringRef getProducer() const { return getStringOperand(1); } StringRef getFlags() const { return getStringOperand(2); } StringRef getSplitDebugFilename() const { return getStringOperand(3); } DICompositeTypeArray getEnumTypes() const { return cast_or_null<MDTuple>(getRawEnumTypes()); } - DITypeArray getRetainedTypes() const { + DIScopeArray getRetainedTypes() const { return cast_or_null<MDTuple>(getRawRetainedTypes()); } - DISubprogramArray getSubprograms() const { - return cast_or_null<MDTuple>(getRawSubprograms()); - } DIGlobalVariableArray getGlobalVariables() const { return cast_or_null<MDTuple>(getRawGlobalVariables()); } @@ -1042,10 +1104,9 @@ public: } Metadata *getRawEnumTypes() const { return getOperand(4); } Metadata *getRawRetainedTypes() const { return getOperand(5); } - Metadata *getRawSubprograms() const { return getOperand(6); } - Metadata *getRawGlobalVariables() const { return getOperand(7); } - Metadata *getRawImportedEntities() const { return getOperand(8); } - Metadata *getRawMacros() const { return getOperand(9); } + Metadata *getRawGlobalVariables() const { return getOperand(6); } + Metadata *getRawImportedEntities() const { return getOperand(7); } + Metadata *getRawMacros() const { return getOperand(8); } /// \brief Replace arrays. /// @@ -1059,16 +1120,13 @@ public: void replaceRetainedTypes(DITypeArray N) { replaceOperandWith(5, N.get()); } - void replaceSubprograms(DISubprogramArray N) { - replaceOperandWith(6, N.get()); - } void replaceGlobalVariables(DIGlobalVariableArray N) { - replaceOperandWith(7, N.get()); + replaceOperandWith(6, N.get()); } void replaceImportedEntities(DIImportedEntityArray N) { - replaceOperandWith(8, N.get()); + replaceOperandWith(7, N.get()); } - void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(9, N.get()); } + void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); } /// @} static bool classof(const Metadata *MD) { @@ -1095,6 +1153,12 @@ public: /// chain. DISubprogram *getSubprogram() const; + /// Get the first non DILexicalBlockFile scope of this scope. + /// + /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the + /// scope chain. + DILocalScope *getNonLexicalBlockFileScope() const; + static bool classof(const Metadata *MD) { return MD->getMetadataID() == DISubprogramKind || MD->getMetadataID() == DILexicalBlockKind || @@ -1192,15 +1256,6 @@ public: /// instructions that are on different basic blocks. inline unsigned getDiscriminator() const; - /// \brief Compute new discriminator in the given context. - /// - /// This modifies the \a LLVMContext that \c this is in to increment the next - /// discriminator for \c this's line/filename combination. - /// - /// FIXME: Delete this. See comments in implementation and at the only call - /// site in \a AddDiscriminators::runOnFunction(). - unsigned computeNewDiscriminator() const; - Metadata *getRawScope() const { return getOperand(0); } Metadata *getRawInlinedAt() const { if (getNumOperands() == 2) @@ -1223,22 +1278,41 @@ class DISubprogram : public DILocalScope { unsigned Line; unsigned ScopeLine; - unsigned Virtuality; unsigned VirtualIndex; - unsigned Flags; - bool IsLocalToUnit; - bool IsDefinition; - bool IsOptimized; + + /// In the MS ABI, the implicit 'this' parameter is adjusted in the prologue + /// of method overrides from secondary bases by this amount. It may be + /// negative. + int ThisAdjustment; + + // Virtuality can only assume three values, so we can pack + // in 2 bits (none/pure/pure_virtual). + unsigned Virtuality : 2; + + unsigned Flags : 27; + + // These are boolean flags so one bit is enough. + // MSVC starts a new container field every time the base + // type changes so we can't use 'bool' to ensure these bits + // are packed. + unsigned IsLocalToUnit : 1; + unsigned IsDefinition : 1; + unsigned IsOptimized : 1; DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line, unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex, - unsigned Flags, bool IsLocalToUnit, bool IsDefinition, - bool IsOptimized, ArrayRef<Metadata *> Ops) + int ThisAdjustment, unsigned Flags, bool IsLocalToUnit, + bool IsDefinition, bool IsOptimized, ArrayRef<Metadata *> Ops) : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops), - Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality), - VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit), - IsDefinition(IsDefinition), IsOptimized(IsOptimized) {} + Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex), + ThisAdjustment(ThisAdjustment), Virtuality(Virtuality), Flags(Flags), + IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), + IsOptimized(IsOptimized) { + static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range"); + assert(Virtuality < 4 && "Virtuality out of range"); + assert((Flags < (1 << 27)) && "Flags out of range"); + } ~DISubprogram() = default; static DISubprogram * @@ -1246,32 +1320,34 @@ class DISubprogram : public DILocalScope { StringRef LinkageName, DIFile *File, unsigned Line, DISubroutineType *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, DITypeRef ContainingType, unsigned Virtuality, - unsigned VirtualIndex, unsigned Flags, bool IsOptimized, + unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, + bool IsOptimized, DICompileUnit *Unit, DITemplateParameterArray TemplateParams, DISubprogram *Declaration, DILocalVariableArray Variables, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, Flags, IsOptimized, - TemplateParams.get(), Declaration, Variables.get(), Storage, - ShouldCreate); + Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams.get(), Declaration, Variables.get(), + Storage, ShouldCreate); } static DISubprogram * getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, - unsigned Flags, bool IsOptimized, Metadata *TemplateParams, - Metadata *Declaration, Metadata *Variables, StorageType Storage, - bool ShouldCreate = true); + int ThisAdjustment, unsigned Flags, bool IsOptimized, Metadata *Unit, + Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables, + StorageType Storage, bool ShouldCreate = true); TempDISubprogram cloneImpl() const { return getTemporary( getContext(), getScope(), getName(), getLinkageName(), getFile(), getLine(), getType(), isLocalToUnit(), isDefinition(), getScopeLine(), - getContainingType(), getVirtuality(), getVirtualIndex(), getFlags(), - isOptimized(), getTemplateParams(), getDeclaration(), getVariables()); + getContainingType(), getVirtuality(), getVirtualIndex(), + getThisAdjustment(), getFlags(), isOptimized(), getUnit(), + getTemplateParams(), getDeclaration(), getVariables()); } public: @@ -1280,25 +1356,26 @@ public: DIFile *File, unsigned Line, DISubroutineType *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, DITypeRef ContainingType, unsigned Virtuality, - unsigned VirtualIndex, unsigned Flags, bool IsOptimized, + unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, + bool IsOptimized, DICompileUnit *Unit, DITemplateParameterArray TemplateParams = nullptr, DISubprogram *Declaration = nullptr, DILocalVariableArray Variables = nullptr), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, TemplateParams, - Declaration, Variables)) + VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, Variables)) DEFINE_MDNODE_GET( DISubprogram, (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, - unsigned VirtualIndex, unsigned Flags, bool IsOptimized, - Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr, - Metadata *Variables = nullptr), + unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, + bool IsOptimized, Metadata *Unit, Metadata *TemplateParams = nullptr, + Metadata *Declaration = nullptr, Metadata *Variables = nullptr), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized, - TemplateParams, Declaration, Variables)) + ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment, + Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables)) TempDISubprogram clone() const { return cloneImpl(); } @@ -1306,6 +1383,7 @@ public: unsigned getLine() const { return Line; } unsigned getVirtuality() const { return Virtuality; } unsigned getVirtualIndex() const { return VirtualIndex; } + int getThisAdjustment() const { return ThisAdjustment; } unsigned getScopeLine() const { return ScopeLine; } unsigned getFlags() const { return Flags; } bool isLocalToUnit() const { return IsLocalToUnit; } @@ -1357,6 +1435,12 @@ public: return DITypeRef(getRawContainingType()); } + DICompileUnit *getUnit() const { + return cast_or_null<DICompileUnit>(getRawUnit()); + } + void replaceUnit(DICompileUnit *CU) { + replaceOperandWith(7, CU); + } DITemplateParameterArray getTemplateParams() const { return cast_or_null<MDTuple>(getRawTemplateParams()); } @@ -1370,9 +1454,10 @@ public: Metadata *getRawScope() const { return getOperand(1); } Metadata *getRawType() const { return getOperand(5); } Metadata *getRawContainingType() const { return getOperand(6); } - Metadata *getRawTemplateParams() const { return getOperand(7); } - Metadata *getRawDeclaration() const { return getOperand(8); } - Metadata *getRawVariables() const { return getOperand(9); } + Metadata *getRawUnit() const { return getOperand(7); } + Metadata *getRawTemplateParams() const { return getOperand(8); } + Metadata *getRawDeclaration() const { return getOperand(9); } + Metadata *getRawVariables() const { return getOperand(10); } /// \brief Check if this subprogram describes the given function. /// @@ -1852,13 +1937,16 @@ class DILocalVariable : public DIVariable { friend class LLVMContextImpl; friend class MDNode; - unsigned Arg; - unsigned Flags; + unsigned Arg : 16; + unsigned Flags : 16; DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line, unsigned Arg, unsigned Flags, ArrayRef<Metadata *> Ops) : DIVariable(C, DILocalVariableKind, Storage, Line, Ops), Arg(Arg), - Flags(Flags) {} + Flags(Flags) { + assert(Flags < (1 << 16) && "DILocalVariable: Flags out of range"); + assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range"); + } ~DILocalVariable() = default; static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope, |