10b57cec5SDimitry Andric //===-- llvm/CodeGen/DwarfUnit.h - Dwarf Compile Unit ---*- C++ -*--===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains support for writing dwarf compile unit. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFUNIT_H 140b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFUNIT_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "DwarfDebug.h" 170b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/DIE.h" 20fe6060f1SDimitry Andric #include "llvm/Target/TargetMachine.h" 21bdd1243dSDimitry Andric #include <optional> 22e8d8bef9SDimitry Andric #include <string> 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric namespace llvm { 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric class ConstantFP; 27e8d8bef9SDimitry Andric class ConstantInt; 280b57cec5SDimitry Andric class DwarfCompileUnit; 29e8d8bef9SDimitry Andric class MCDwarfDwoLineTable; 30e8d8bef9SDimitry Andric class MCSymbol; 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 330b57cec5SDimitry Andric /// This dwarf writer support class manages information associated with a 340b57cec5SDimitry Andric /// source file. 350b57cec5SDimitry Andric class DwarfUnit : public DIEUnit { 360b57cec5SDimitry Andric protected: 375f757f3fSDimitry Andric /// A numeric ID unique among all CUs in the module 385f757f3fSDimitry Andric unsigned UniqueID; 390b57cec5SDimitry Andric /// MDNode for the compile unit. 400b57cec5SDimitry Andric const DICompileUnit *CUNode; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric // All DIEValues are allocated through this allocator. 430b57cec5SDimitry Andric BumpPtrAllocator DIEValueAllocator; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric /// Target of Dwarf emission. 460b57cec5SDimitry Andric AsmPrinter *Asm; 470b57cec5SDimitry Andric 485f757f3fSDimitry Andric /// The start of the unit within its section. 495f757f3fSDimitry Andric MCSymbol *LabelBegin = nullptr; 505f757f3fSDimitry Andric 510b57cec5SDimitry Andric /// Emitted at the end of the CU and used to compute the CU Length field. 520b57cec5SDimitry Andric MCSymbol *EndLabel = nullptr; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric // Holders for some common dwarf information. 550b57cec5SDimitry Andric DwarfDebug *DD; 560b57cec5SDimitry Andric DwarfFile *DU; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric /// An anonymous type for index type. Owned by DIEUnit. 591fd87a68SDimitry Andric DIE *IndexTyDie = nullptr; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric /// Tracks the mapping of unit level debug information variables to debug 620b57cec5SDimitry Andric /// information entries. 630b57cec5SDimitry Andric DenseMap<const MDNode *, DIE *> MDNodeToDieMap; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric /// A list of all the DIEBlocks in use. 660b57cec5SDimitry Andric std::vector<DIEBlock *> DIEBlocks; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric /// A list of all the DIELocs in use. 690b57cec5SDimitry Andric std::vector<DIELoc *> DIELocs; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric /// This map is used to keep track of subprogram DIEs that need 720b57cec5SDimitry Andric /// DW_AT_containing_type attribute. This attribute points to a DIE that 730b57cec5SDimitry Andric /// corresponds to the MDNode mapped with the subprogram DIE. 740b57cec5SDimitry Andric DenseMap<DIE *, const DINode *> ContainingTypeMap; 750b57cec5SDimitry Andric 765f757f3fSDimitry Andric DwarfUnit(dwarf::Tag, const DICompileUnit *Node, AsmPrinter *A, 775f757f3fSDimitry Andric DwarfDebug *DW, DwarfFile *DWU, unsigned UniqueID = 0); 780b57cec5SDimitry Andric 79fe6060f1SDimitry Andric bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie, bool Minimal); 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric bool isShareableAcrossCUs(const DINode *D) const; 820b57cec5SDimitry Andric 83fe6060f1SDimitry Andric template <typename T> addAttribute(DIEValueList & Die,dwarf::Attribute Attribute,dwarf::Form Form,T && Value)84fe6060f1SDimitry Andric void addAttribute(DIEValueList &Die, dwarf::Attribute Attribute, 85fe6060f1SDimitry Andric dwarf::Form Form, T &&Value) { 86fe6060f1SDimitry Andric // For strict DWARF mode, only generate attributes available to current 87fe6060f1SDimitry Andric // DWARF version. 88fe6060f1SDimitry Andric // Attribute 0 is used when emitting form-encoded values in blocks, which 89fe6060f1SDimitry Andric // don't have attributes (only forms) so we cannot detect their DWARF 90fe6060f1SDimitry Andric // version compatibility here and assume they are compatible. 91fe6060f1SDimitry Andric if (Attribute != 0 && Asm->TM.Options.DebugStrictDwarf && 92fe6060f1SDimitry Andric DD->getDwarfVersion() < dwarf::AttributeVersion(Attribute)) 93fe6060f1SDimitry Andric return; 94fe6060f1SDimitry Andric 95fe6060f1SDimitry Andric Die.addValue(DIEValueAllocator, 96fe6060f1SDimitry Andric DIEValue(Attribute, Form, std::forward<T>(Value))); 97fe6060f1SDimitry Andric } 98fe6060f1SDimitry Andric 990b57cec5SDimitry Andric public: 1005f757f3fSDimitry Andric /// Gets Unique ID for this unit. getUniqueID()1015f757f3fSDimitry Andric unsigned getUniqueID() const { return UniqueID; } 1020b57cec5SDimitry Andric // Accessors. getAsmPrinter()1030b57cec5SDimitry Andric AsmPrinter* getAsmPrinter() const { return Asm; } 1045f757f3fSDimitry Andric /// Get the the symbol for start of the section for this unit. getLabelBegin()1055f757f3fSDimitry Andric MCSymbol *getLabelBegin() const { 1065f757f3fSDimitry Andric assert(LabelBegin && "LabelBegin is not initialized"); 1075f757f3fSDimitry Andric return LabelBegin; 1085f757f3fSDimitry Andric } getEndLabel()1090b57cec5SDimitry Andric MCSymbol *getEndLabel() const { return EndLabel; } getLanguage()1100b57cec5SDimitry Andric uint16_t getLanguage() const { return CUNode->getSourceLanguage(); } getCUNode()1110b57cec5SDimitry Andric const DICompileUnit *getCUNode() const { return CUNode; } getDwarfDebug()112e8d8bef9SDimitry Andric DwarfDebug &getDwarfDebug() const { return *DD; } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric /// Return true if this compile unit has something to write out. hasContent()1150b57cec5SDimitry Andric bool hasContent() const { return getUnitDie().hasChildren(); } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric /// Get string containing language specific context for a global name. 1180b57cec5SDimitry Andric /// 1190b57cec5SDimitry Andric /// Walks the metadata parent chain in a language specific manner (using the 1200b57cec5SDimitry Andric /// compile unit language) and returns it as a string. This is done at the 1210b57cec5SDimitry Andric /// metadata level because DIEs may not currently have been added to the 1220b57cec5SDimitry Andric /// parent context and walking the DIEs looking for names is more expensive 1230b57cec5SDimitry Andric /// than walking the metadata. 1240b57cec5SDimitry Andric std::string getParentContextString(const DIScope *Context) const; 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric /// Add a new global name to the compile unit. 1270b57cec5SDimitry Andric virtual void addGlobalName(StringRef Name, const DIE &Die, 1280b57cec5SDimitry Andric const DIScope *Context) = 0; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric /// Add a new global type to the compile unit. 131*0fca6ea1SDimitry Andric virtual void addGlobalTypeImpl(const DIType *Ty, const DIE &Die, 1320b57cec5SDimitry Andric const DIScope *Context) = 0; 1330b57cec5SDimitry Andric 134*0fca6ea1SDimitry Andric void addGlobalType(const DIType *Ty, const DIE &Die, const DIScope *Context); 135*0fca6ea1SDimitry Andric 1360b57cec5SDimitry Andric /// Returns the DIE map slot for the specified debug variable. 1370b57cec5SDimitry Andric /// 1380b57cec5SDimitry Andric /// We delegate the request to DwarfDebug when the MDNode can be part of the 1390b57cec5SDimitry Andric /// type system, since DIEs for the type system can be shared across CUs and 1400b57cec5SDimitry Andric /// the mappings are kept in DwarfDebug. 1410b57cec5SDimitry Andric DIE *getDIE(const DINode *D) const; 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric /// Returns a fresh newly allocated DIELoc. getDIELoc()1440b57cec5SDimitry Andric DIELoc *getDIELoc() { return new (DIEValueAllocator) DIELoc; } 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric /// Insert DIE into the map. 1470b57cec5SDimitry Andric /// 1480b57cec5SDimitry Andric /// We delegate the request to DwarfDebug when the MDNode can be part of the 1490b57cec5SDimitry Andric /// type system, since DIEs for the type system can be shared across CUs and 1500b57cec5SDimitry Andric /// the mappings are kept in DwarfDebug. 1510b57cec5SDimitry Andric void insertDIE(const DINode *Desc, DIE *D); 1520b57cec5SDimitry Andric 1538bcb0991SDimitry Andric void insertDIE(DIE *D); 1548bcb0991SDimitry Andric 1550b57cec5SDimitry Andric /// Add a flag that is true to the DIE. 1560b57cec5SDimitry Andric void addFlag(DIE &Die, dwarf::Attribute Attribute); 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric /// Add an unsigned integer attribute data and value. 1590b57cec5SDimitry Andric void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, 160bdd1243dSDimitry Andric std::optional<dwarf::Form> Form, uint64_t Integer); 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric void addUInt(DIEValueList &Block, dwarf::Form Form, uint64_t Integer); 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric /// Add an signed integer attribute data and value. 1650b57cec5SDimitry Andric void addSInt(DIEValueList &Die, dwarf::Attribute Attribute, 166bdd1243dSDimitry Andric std::optional<dwarf::Form> Form, int64_t Integer); 1670b57cec5SDimitry Andric 168bdd1243dSDimitry Andric void addSInt(DIELoc &Die, std::optional<dwarf::Form> Form, int64_t Integer); 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric /// Add a string attribute data and value. 1710b57cec5SDimitry Andric /// 1720b57cec5SDimitry Andric /// We always emit a reference to the string pool instead of immediate 1730b57cec5SDimitry Andric /// strings so that DIEs have more predictable sizes. In the case of split 1740b57cec5SDimitry Andric /// dwarf we emit an index into another table which gets us the static offset 1750b57cec5SDimitry Andric /// into the string table. 1760b57cec5SDimitry Andric void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric /// Add a Dwarf label attribute data and value. 179fe6060f1SDimitry Andric void addLabel(DIEValueList &Die, dwarf::Attribute Attribute, dwarf::Form Form, 1800b57cec5SDimitry Andric const MCSymbol *Label); 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric void addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label); 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric /// Add an offset into a section attribute data and value. 1850b57cec5SDimitry Andric void addSectionOffset(DIE &Die, dwarf::Attribute Attribute, uint64_t Integer); 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric /// Add a dwarf op address data and value using the form given and an 1880b57cec5SDimitry Andric /// op of either DW_FORM_addr or DW_FORM_GNU_addr_index. 1890b57cec5SDimitry Andric void addOpAddress(DIELoc &Die, const MCSymbol *Sym); 190fe6060f1SDimitry Andric void addPoolOpAddress(DIEValueList &Die, const MCSymbol *Label); 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric /// Add a label delta attribute data and value. 193fe6060f1SDimitry Andric void addLabelDelta(DIEValueList &Die, dwarf::Attribute Attribute, 194fe6060f1SDimitry Andric const MCSymbol *Hi, const MCSymbol *Lo); 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric /// Add a DIE attribute data and value. 1970b57cec5SDimitry Andric void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry); 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric /// Add a DIE attribute data and value. 2000b57cec5SDimitry Andric void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIEEntry Entry); 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric /// Add a type's DW_AT_signature and set the declaration flag. 2030b57cec5SDimitry Andric void addDIETypeSignature(DIE &Die, uint64_t Signature); 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric /// Add block data. 2060b57cec5SDimitry Andric void addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc); 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric /// Add block data. 2090b57cec5SDimitry Andric void addBlock(DIE &Die, dwarf::Attribute Attribute, DIEBlock *Block); 210fe6060f1SDimitry Andric void addBlock(DIE &Die, dwarf::Attribute Attribute, dwarf::Form Form, 211fe6060f1SDimitry Andric DIEBlock *Block); 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric /// Add location information to specified debug information entry. 2140b57cec5SDimitry Andric void addSourceLine(DIE &Die, unsigned Line, const DIFile *File); 2150b57cec5SDimitry Andric void addSourceLine(DIE &Die, const DILocalVariable *V); 2160b57cec5SDimitry Andric void addSourceLine(DIE &Die, const DIGlobalVariable *G); 2170b57cec5SDimitry Andric void addSourceLine(DIE &Die, const DISubprogram *SP); 2180b57cec5SDimitry Andric void addSourceLine(DIE &Die, const DILabel *L); 2190b57cec5SDimitry Andric void addSourceLine(DIE &Die, const DIType *Ty); 2200b57cec5SDimitry Andric void addSourceLine(DIE &Die, const DIObjCProperty *Ty); 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric /// Add constant value entry in variable DIE. 2230b57cec5SDimitry Andric void addConstantValue(DIE &Die, const ConstantInt *CI, const DIType *Ty); 2240b57cec5SDimitry Andric void addConstantValue(DIE &Die, const APInt &Val, const DIType *Ty); 2250b57cec5SDimitry Andric void addConstantValue(DIE &Die, const APInt &Val, bool Unsigned); 2260b57cec5SDimitry Andric void addConstantValue(DIE &Die, uint64_t Val, const DIType *Ty); 2270b57cec5SDimitry Andric void addConstantValue(DIE &Die, bool Unsigned, uint64_t Val); 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric /// Add constant value entry in variable DIE. 2300b57cec5SDimitry Andric void addConstantFPValue(DIE &Die, const ConstantFP *CFP); 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric /// Add a linkage name, if it isn't empty. 2330b57cec5SDimitry Andric void addLinkageName(DIE &Die, StringRef LinkageName); 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric /// Add template parameters in buffer. 2360b57cec5SDimitry Andric void addTemplateParams(DIE &Buffer, DINodeArray TParams); 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric /// Add thrown types. 2390b57cec5SDimitry Andric void addThrownTypes(DIE &Die, DINodeArray ThrownTypes); 2400b57cec5SDimitry Andric 2410eae32dcSDimitry Andric /// Add the accessibility attribute. 2420eae32dcSDimitry Andric void addAccess(DIE &Die, DINode::DIFlags Flags); 2430eae32dcSDimitry Andric 2440b57cec5SDimitry Andric /// Add a new type attribute to the specified entity. 2450b57cec5SDimitry Andric /// 2460b57cec5SDimitry Andric /// This takes and attribute parameter because DW_AT_friend attributes are 2470b57cec5SDimitry Andric /// also type references. 2480b57cec5SDimitry Andric void addType(DIE &Entity, const DIType *Ty, 2490b57cec5SDimitry Andric dwarf::Attribute Attribute = dwarf::DW_AT_type); 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric DIE *getOrCreateNameSpace(const DINamespace *NS); 2520b57cec5SDimitry Andric DIE *getOrCreateModule(const DIModule *M); 2530b57cec5SDimitry Andric DIE *getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal = false); 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, 2560b57cec5SDimitry Andric bool SkipSPAttributes = false); 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric /// Creates type DIE with specific context. 2590b57cec5SDimitry Andric DIE *createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty); 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric /// Find existing DIE or create new DIE for the given type. 26206c3fb27SDimitry Andric virtual DIE *getOrCreateTypeDIE(const MDNode *TyNode); 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric /// Get context owner's DIE. 26506c3fb27SDimitry Andric virtual DIE *getOrCreateContextDIE(const DIScope *Context); 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric /// Construct DIEs for types that contain vtables. 2680b57cec5SDimitry Andric void constructContainingTypeDIEs(); 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric /// Construct function argument DIEs. 2710b57cec5SDimitry Andric void constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args); 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric /// Create a DIE with the given Tag, add the DIE to its parent, and 2740b57cec5SDimitry Andric /// call insertDIE if MD is not null. 275fe6060f1SDimitry Andric DIE &createAndAddDIE(dwarf::Tag Tag, DIE &Parent, const DINode *N = nullptr); 2760b57cec5SDimitry Andric useSegmentedStringOffsetsTable()2770b57cec5SDimitry Andric bool useSegmentedStringOffsetsTable() const { 2780b57cec5SDimitry Andric return DD->useSegmentedStringOffsetsTable(); 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric /// Compute the size of a header for this unit, not including the initial 2820b57cec5SDimitry Andric /// length field. getHeaderSize()2830b57cec5SDimitry Andric virtual unsigned getHeaderSize() const { 2840b57cec5SDimitry Andric return sizeof(int16_t) + // DWARF version number 285e8d8bef9SDimitry Andric Asm->getDwarfOffsetByteSize() + // Offset Into Abbrev. Section 2860b57cec5SDimitry Andric sizeof(int8_t) + // Pointer Size (in bytes) 2870b57cec5SDimitry Andric (DD->getDwarfVersion() >= 5 ? sizeof(int8_t) 2880b57cec5SDimitry Andric : 0); // DWARF v5 unit type 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric /// Emit the header for this unit, not including the initial length field. 2920b57cec5SDimitry Andric virtual void emitHeader(bool UseOffsets) = 0; 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric /// Add the DW_AT_str_offsets_base attribute to the unit DIE. 2950b57cec5SDimitry Andric void addStringOffsetsStart(); 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric /// Add the DW_AT_rnglists_base attribute to the unit DIE. 2980b57cec5SDimitry Andric void addRnglistsBase(); 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric virtual DwarfCompileUnit &getCU() = 0; 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy); 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric /// addSectionDelta - Add a label delta attribute data and value. 305fe6060f1SDimitry Andric void addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, 306fe6060f1SDimitry Andric const MCSymbol *Lo); 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric /// Add a Dwarf section label attribute data and value. 309fe6060f1SDimitry Andric void addSectionLabel(DIE &Die, dwarf::Attribute Attribute, 310fe6060f1SDimitry Andric const MCSymbol *Label, const MCSymbol *Sec); 3110b57cec5SDimitry Andric 312349cc55cSDimitry Andric /// Add DW_TAG_LLVM_annotation. 313349cc55cSDimitry Andric void addAnnotation(DIE &Buffer, DINodeArray Annotations); 314349cc55cSDimitry Andric 3150b57cec5SDimitry Andric /// Get context owner's DIE. 3160b57cec5SDimitry Andric DIE *createTypeDIE(const DICompositeType *Ty); 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric protected: 3190b57cec5SDimitry Andric ~DwarfUnit(); 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric /// Create new static data member DIE. 3220b57cec5SDimitry Andric DIE *getOrCreateStaticMemberDIE(const DIDerivedType *DT); 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric /// Look up the source ID for the given file. If none currently exists, 3250b57cec5SDimitry Andric /// create a new ID and insert it in the line table. 3260b57cec5SDimitry Andric virtual unsigned getOrCreateSourceID(const DIFile *File) = 0; 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric /// Emit the common part of the header for this unit. 3290b57cec5SDimitry Andric void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT); 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric private: 3320b57cec5SDimitry Andric void constructTypeDIE(DIE &Buffer, const DIBasicType *BTy); 333e8d8bef9SDimitry Andric void constructTypeDIE(DIE &Buffer, const DIStringType *BTy); 3340b57cec5SDimitry Andric void constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy); 3350b57cec5SDimitry Andric void constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy); 3360b57cec5SDimitry Andric void constructSubrangeDIE(DIE &Buffer, const DISubrange *SR, DIE *IndexTy); 337e8d8bef9SDimitry Andric void constructGenericSubrangeDIE(DIE &Buffer, const DIGenericSubrange *SR, 338e8d8bef9SDimitry Andric DIE *IndexTy); 3390b57cec5SDimitry Andric void constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy); 3400b57cec5SDimitry Andric void constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy); 3410b57cec5SDimitry Andric DIE &constructMemberDIE(DIE &Buffer, const DIDerivedType *DT); 3420b57cec5SDimitry Andric void constructTemplateTypeParameterDIE(DIE &Buffer, 3430b57cec5SDimitry Andric const DITemplateTypeParameter *TP); 3440b57cec5SDimitry Andric void constructTemplateValueParameterDIE(DIE &Buffer, 3450b57cec5SDimitry Andric const DITemplateValueParameter *TVP); 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric /// Return the default lower bound for an array. 3480b57cec5SDimitry Andric /// 3490b57cec5SDimitry Andric /// If the DWARF version doesn't handle the language, return -1. 3500b57cec5SDimitry Andric int64_t getDefaultLowerBound() const; 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric /// Get an anonymous type for index type. 3530b57cec5SDimitry Andric DIE *getIndexTyDie(); 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric /// Set D as anonymous type for index which can be reused later. setIndexTyDie(DIE * D)3560b57cec5SDimitry Andric void setIndexTyDie(DIE *D) { IndexTyDie = D; } 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric virtual void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) = 0; 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric /// If this is a named finished type then include it in the list of types for 3610b57cec5SDimitry Andric /// the accelerator tables. 3620b57cec5SDimitry Andric void updateAcceleratorTables(const DIScope *Context, const DIType *Ty, 3630b57cec5SDimitry Andric const DIE &TyDIE); 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric virtual bool isDwoUnit() const = 0; 3660b57cec5SDimitry Andric const MCSymbol *getCrossSectionRelativeBaseAddress() const override; 367bdd1243dSDimitry Andric 368bdd1243dSDimitry Andric /// Returns 'true' if the current DwarfVersion is compatible 369bdd1243dSDimitry Andric /// with the specified \p Version. 370bdd1243dSDimitry Andric bool isCompatibleWithVersion(uint16_t Version) const; 3710b57cec5SDimitry Andric }; 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric class DwarfTypeUnit final : public DwarfUnit { 3740b57cec5SDimitry Andric uint64_t TypeSignature; 3750b57cec5SDimitry Andric const DIE *Ty; 3760b57cec5SDimitry Andric DwarfCompileUnit &CU; 3770b57cec5SDimitry Andric MCDwarfDwoLineTable *SplitLineTable; 3780b57cec5SDimitry Andric bool UsedLineTable = false; 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric unsigned getOrCreateSourceID(const DIFile *File) override; 3810b57cec5SDimitry Andric void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) override; 3820b57cec5SDimitry Andric bool isDwoUnit() const override; 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric public: 3850b57cec5SDimitry Andric DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW, 3865f757f3fSDimitry Andric DwarfFile *DWU, unsigned UniqueID, 3875f757f3fSDimitry Andric MCDwarfDwoLineTable *SplitLineTable = nullptr); 3880b57cec5SDimitry Andric setTypeSignature(uint64_t Signature)3890b57cec5SDimitry Andric void setTypeSignature(uint64_t Signature) { TypeSignature = Signature; } 3905f757f3fSDimitry Andric /// Returns Type Signature. getTypeSignature()3915f757f3fSDimitry Andric uint64_t getTypeSignature() const { return TypeSignature; } setType(const DIE * Ty)3920b57cec5SDimitry Andric void setType(const DIE *Ty) { this->Ty = Ty; } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric /// Emit the header for this unit, not including the initial length field. 3950b57cec5SDimitry Andric void emitHeader(bool UseOffsets) override; getHeaderSize()3960b57cec5SDimitry Andric unsigned getHeaderSize() const override { 3970b57cec5SDimitry Andric return DwarfUnit::getHeaderSize() + sizeof(uint64_t) + // Type Signature 398e8d8bef9SDimitry Andric Asm->getDwarfOffsetByteSize(); // Type DIE Offset 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric void addGlobalName(StringRef Name, const DIE &Die, 4010b57cec5SDimitry Andric const DIScope *Context) override; 402*0fca6ea1SDimitry Andric void addGlobalTypeImpl(const DIType *Ty, const DIE &Die, 4030b57cec5SDimitry Andric const DIScope *Context) override; getCU()4040b57cec5SDimitry Andric DwarfCompileUnit &getCU() override { return CU; } 4050b57cec5SDimitry Andric }; 4060b57cec5SDimitry Andric } // end llvm namespace 4070b57cec5SDimitry Andric #endif 408