10b57cec5SDimitry Andric //===- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h --------------*- 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 Microsoft CodeView debug info. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H 140b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H 150b57cec5SDimitry Andric 1606c3fb27SDimitry Andric #include "llvm/ADT/APSInt.h" 170b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 180b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 190b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h" 200b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h" 210b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h" 220b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h" 235f757f3fSDimitry Andric #include "llvm/ADT/SmallSet.h" 240b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/DbgEntityHistoryCalculator.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/DebugHandlerBase.h" 275f757f3fSDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h" 280b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h" 290b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" 300b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h" 310b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 320b57cec5SDimitry Andric #include "llvm/Support/Allocator.h" 330b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 340b57cec5SDimitry Andric #include <cstdint> 350b57cec5SDimitry Andric #include <map> 360b57cec5SDimitry Andric #include <string> 370b57cec5SDimitry Andric #include <tuple> 380b57cec5SDimitry Andric #include <unordered_map> 390b57cec5SDimitry Andric #include <utility> 400b57cec5SDimitry Andric #include <vector> 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric namespace llvm { 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric struct ClassInfo; 450b57cec5SDimitry Andric class StringRef; 460b57cec5SDimitry Andric class AsmPrinter; 470b57cec5SDimitry Andric class Function; 480b57cec5SDimitry Andric class GlobalVariable; 490b57cec5SDimitry Andric class MCSectionCOFF; 500b57cec5SDimitry Andric class MCStreamer; 510b57cec5SDimitry Andric class MCSymbol; 520b57cec5SDimitry Andric class MachineFunction; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric /// Collects and handles line tables information in a CodeView format. 550b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { 5681ad6265SDimitry Andric public: 5781ad6265SDimitry Andric struct LocalVarDef { 580b57cec5SDimitry Andric /// Indicates that variable data is stored in memory relative to the 590b57cec5SDimitry Andric /// specified register. 600b57cec5SDimitry Andric int InMemory : 1; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric /// Offset of variable data in memory. 630b57cec5SDimitry Andric int DataOffset : 31; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric /// Non-zero if this is a piece of an aggregate. 660b57cec5SDimitry Andric uint16_t IsSubfield : 1; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric /// Offset into aggregate. 690b57cec5SDimitry Andric uint16_t StructOffset : 15; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric /// Register containing the data or the register base of the memory 720b57cec5SDimitry Andric /// location containing the data. 730b57cec5SDimitry Andric uint16_t CVRegister; 740b57cec5SDimitry Andric 7581ad6265SDimitry Andric uint64_t static toOpaqueValue(const LocalVarDef DR) { 7681ad6265SDimitry Andric uint64_t Val = 0; 7781ad6265SDimitry Andric std::memcpy(&Val, &DR, sizeof(Val)); 7881ad6265SDimitry Andric return Val; 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 8181ad6265SDimitry Andric LocalVarDef static createFromOpaqueValue(uint64_t Val) { 8281ad6265SDimitry Andric LocalVarDef DR; 8381ad6265SDimitry Andric std::memcpy(&DR, &Val, sizeof(Val)); 8481ad6265SDimitry Andric return DR; 8581ad6265SDimitry Andric } 860b57cec5SDimitry Andric }; 870b57cec5SDimitry Andric 88bdd1243dSDimitry Andric static_assert(sizeof(uint64_t) == sizeof(LocalVarDef)); 8981ad6265SDimitry Andric 9081ad6265SDimitry Andric private: 9181ad6265SDimitry Andric MCStreamer &OS; 9281ad6265SDimitry Andric BumpPtrAllocator Allocator; 9381ad6265SDimitry Andric codeview::GlobalTypeTableBuilder TypeTable; 9481ad6265SDimitry Andric 9581ad6265SDimitry Andric /// Whether to emit type record hashes into .debug$H. 9681ad6265SDimitry Andric bool EmitDebugGlobalHashes = false; 9781ad6265SDimitry Andric 9881ad6265SDimitry Andric /// The codeview CPU type used by the translation unit. 9981ad6265SDimitry Andric codeview::CPUType TheCPU; 10081ad6265SDimitry Andric 10181ad6265SDimitry Andric static LocalVarDef createDefRangeMem(uint16_t CVRegister, int Offset); 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric /// Similar to DbgVariable in DwarfDebug, but not dwarf-specific. 1040b57cec5SDimitry Andric struct LocalVariable { 1050b57cec5SDimitry Andric const DILocalVariable *DIVar = nullptr; 10681ad6265SDimitry Andric MapVector<LocalVarDef, 10781ad6265SDimitry Andric SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1>> 10881ad6265SDimitry Andric DefRanges; 1090b57cec5SDimitry Andric bool UseReferenceType = false; 110bdd1243dSDimitry Andric std::optional<APSInt> ConstantValue; 1110b57cec5SDimitry Andric }; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric struct CVGlobalVariable { 1140b57cec5SDimitry Andric const DIGlobalVariable *DIGV; 1150b57cec5SDimitry Andric PointerUnion<const GlobalVariable *, const DIExpression *> GVInfo; 1160b57cec5SDimitry Andric }; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric struct InlineSite { 1190b57cec5SDimitry Andric SmallVector<LocalVariable, 1> InlinedLocals; 1200b57cec5SDimitry Andric SmallVector<const DILocation *, 1> ChildSites; 1210b57cec5SDimitry Andric const DISubprogram *Inlinee = nullptr; 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric /// The ID of the inline site or function used with .cv_loc. Not a type 1240b57cec5SDimitry Andric /// index. 1250b57cec5SDimitry Andric unsigned SiteFuncId = 0; 1260b57cec5SDimitry Andric }; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric // Combines information from DILexicalBlock and LexicalScope. 1290b57cec5SDimitry Andric struct LexicalBlock { 1300b57cec5SDimitry Andric SmallVector<LocalVariable, 1> Locals; 1310b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> Globals; 1320b57cec5SDimitry Andric SmallVector<LexicalBlock *, 1> Children; 1330b57cec5SDimitry Andric const MCSymbol *Begin; 1340b57cec5SDimitry Andric const MCSymbol *End; 1350b57cec5SDimitry Andric StringRef Name; 1360b57cec5SDimitry Andric }; 1370b57cec5SDimitry Andric 1385f757f3fSDimitry Andric struct JumpTableInfo { 1395f757f3fSDimitry Andric codeview::JumpTableEntrySize EntrySize; 1405f757f3fSDimitry Andric const MCSymbol *Base; 1415f757f3fSDimitry Andric uint64_t BaseOffset; 1425f757f3fSDimitry Andric const MCSymbol *Branch; 1435f757f3fSDimitry Andric const MCSymbol *Table; 1445f757f3fSDimitry Andric size_t TableSize; 1455f757f3fSDimitry Andric }; 1465f757f3fSDimitry Andric 1470b57cec5SDimitry Andric // For each function, store a vector of labels to its instructions, as well as 1480b57cec5SDimitry Andric // to the end of the function. 1490b57cec5SDimitry Andric struct FunctionInfo { 1500b57cec5SDimitry Andric FunctionInfo() = default; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric // Uncopyable. 1530b57cec5SDimitry Andric FunctionInfo(const FunctionInfo &FI) = delete; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric /// Map from inlined call site to inlined instructions and child inlined 1560b57cec5SDimitry Andric /// call sites. Listed in program order. 1570b57cec5SDimitry Andric std::unordered_map<const DILocation *, InlineSite> InlineSites; 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric /// Ordered list of top-level inlined call sites. 1600b57cec5SDimitry Andric SmallVector<const DILocation *, 1> ChildSites; 1610b57cec5SDimitry Andric 1625f757f3fSDimitry Andric /// Set of all functions directly inlined into this one. 1635f757f3fSDimitry Andric SmallSet<codeview::TypeIndex, 1> Inlinees; 1645f757f3fSDimitry Andric 1650b57cec5SDimitry Andric SmallVector<LocalVariable, 1> Locals; 1660b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> Globals; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric std::unordered_map<const DILexicalBlockBase*, LexicalBlock> LexicalBlocks; 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric // Lexical blocks containing local variables. 1710b57cec5SDimitry Andric SmallVector<LexicalBlock *, 1> ChildBlocks; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric std::vector<std::pair<MCSymbol *, MDNode *>> Annotations; 174c14a5a88SDimitry Andric std::vector<std::tuple<const MCSymbol *, const MCSymbol *, const DIType *>> 175c14a5a88SDimitry Andric HeapAllocSites; 1760b57cec5SDimitry Andric 1775f757f3fSDimitry Andric std::vector<JumpTableInfo> JumpTables; 1785f757f3fSDimitry Andric 1790b57cec5SDimitry Andric const MCSymbol *Begin = nullptr; 1800b57cec5SDimitry Andric const MCSymbol *End = nullptr; 1810b57cec5SDimitry Andric unsigned FuncId = 0; 1820b57cec5SDimitry Andric unsigned LastFileId = 0; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric /// Number of bytes allocated in the prologue for all local stack objects. 1850b57cec5SDimitry Andric unsigned FrameSize = 0; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric /// Number of bytes of parameters on the stack. 1880b57cec5SDimitry Andric unsigned ParamSize = 0; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric /// Number of bytes pushed to save CSRs. 1910b57cec5SDimitry Andric unsigned CSRSize = 0; 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric /// Adjustment to apply on x86 when using the VFRAME frame pointer. 1940b57cec5SDimitry Andric int OffsetAdjustment = 0; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric /// Two-bit value indicating which register is the designated frame pointer 1970b57cec5SDimitry Andric /// register for local variables. Included in S_FRAMEPROC. 1980b57cec5SDimitry Andric codeview::EncodedFramePtrReg EncodedLocalFramePtrReg = 1990b57cec5SDimitry Andric codeview::EncodedFramePtrReg::None; 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric /// Two-bit value indicating which register is the designated frame pointer 2020b57cec5SDimitry Andric /// register for stack parameters. Included in S_FRAMEPROC. 2030b57cec5SDimitry Andric codeview::EncodedFramePtrReg EncodedParamFramePtrReg = 2040b57cec5SDimitry Andric codeview::EncodedFramePtrReg::None; 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric codeview::FrameProcedureOptions FrameProcOpts; 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric bool HasStackRealignment = false; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric bool HaveLineInfo = false; 21106c3fb27SDimitry Andric 21206c3fb27SDimitry Andric bool HasFramePointer = false; 2130b57cec5SDimitry Andric }; 2140b57cec5SDimitry Andric FunctionInfo *CurFn = nullptr; 2150b57cec5SDimitry Andric 216349cc55cSDimitry Andric codeview::SourceLanguage CurrentSourceLanguage = 217349cc55cSDimitry Andric codeview::SourceLanguage::Masm; 218349cc55cSDimitry Andric 219349cc55cSDimitry Andric // This map records the constant offset in DIExpression of the 220349cc55cSDimitry Andric // DIGlobalVariableExpression referencing the DIGlobalVariable. 221349cc55cSDimitry Andric DenseMap<const DIGlobalVariable *, uint64_t> CVGlobalVariableOffsets; 222349cc55cSDimitry Andric 223*0fca6ea1SDimitry Andric // Map used to separate variables according to the lexical scope they belong 2240b57cec5SDimitry Andric // in. This is populated by recordLocalVariable() before 2250b57cec5SDimitry Andric // collectLexicalBlocks() separates the variables between the FunctionInfo 2260b57cec5SDimitry Andric // and LexicalBlocks. 2270b57cec5SDimitry Andric DenseMap<const LexicalScope *, SmallVector<LocalVariable, 1>> ScopeVariables; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric // Map to separate global variables according to the lexical scope they 2300b57cec5SDimitry Andric // belong in. A null local scope represents the global scope. 2310b57cec5SDimitry Andric typedef SmallVector<CVGlobalVariable, 1> GlobalVariableList; 2320b57cec5SDimitry Andric DenseMap<const DIScope*, std::unique_ptr<GlobalVariableList> > ScopeGlobals; 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric // Array of global variables which need to be emitted into a COMDAT section. 2350b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> ComdatVariables; 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric // Array of non-COMDAT global variables. 2380b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> GlobalVariables; 2390b57cec5SDimitry Andric 240e8d8bef9SDimitry Andric /// List of static const data members to be emitted as S_CONSTANTs. 241e8d8bef9SDimitry Andric SmallVector<const DIDerivedType *, 4> StaticConstMembers; 242e8d8bef9SDimitry Andric 2430b57cec5SDimitry Andric /// The set of comdat .debug$S sections that we've seen so far. Each section 2440b57cec5SDimitry Andric /// must start with a magic version number that must only be emitted once. 2450b57cec5SDimitry Andric /// This set tracks which sections we've already opened. 2460b57cec5SDimitry Andric DenseSet<MCSectionCOFF *> ComdatDebugSections; 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric /// Switch to the appropriate .debug$S section for GVSym. If GVSym, the symbol 2490b57cec5SDimitry Andric /// of an emitted global value, is in a comdat COFF section, this will switch 2500b57cec5SDimitry Andric /// to a new .debug$S section in that comdat. This method ensures that the 2510b57cec5SDimitry Andric /// section starts with the magic version number on first use. If GVSym is 2520b57cec5SDimitry Andric /// null, uses the main .debug$S section. 2530b57cec5SDimitry Andric void switchToDebugSectionForSymbol(const MCSymbol *GVSym); 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric /// The next available function index for use with our .cv_* directives. Not 2560b57cec5SDimitry Andric /// to be confused with type indices for LF_FUNC_ID records. 2570b57cec5SDimitry Andric unsigned NextFuncId = 0; 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric InlineSite &getInlineSite(const DILocation *InlinedAt, 2600b57cec5SDimitry Andric const DISubprogram *Inlinee); 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP); 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric void calculateRanges(LocalVariable &Var, 2650b57cec5SDimitry Andric const DbgValueHistoryMap::Entries &Entries); 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric /// Remember some debug info about each function. Keep it in a stable order to 2680b57cec5SDimitry Andric /// emit at the end of the TU. 2690b57cec5SDimitry Andric MapVector<const Function *, std::unique_ptr<FunctionInfo>> FnDebugInfo; 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric /// Map from full file path to .cv_file id. Full paths are built from DIFiles 2720b57cec5SDimitry Andric /// and are stored in FileToFilepathMap; 2730b57cec5SDimitry Andric DenseMap<StringRef, unsigned> FileIdMap; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric /// All inlined subprograms in the order they should be emitted. 2760b57cec5SDimitry Andric SmallSetVector<const DISubprogram *, 4> InlinedSubprograms; 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric /// Map from a pair of DI metadata nodes and its DI type (or scope) that can 2790b57cec5SDimitry Andric /// be nullptr, to CodeView type indices. Primarily indexed by 2800b57cec5SDimitry Andric /// {DIType*, DIType*} and {DISubprogram*, DIType*}. 2810b57cec5SDimitry Andric /// 2820b57cec5SDimitry Andric /// The second entry in the key is needed for methods as DISubroutineType 2830b57cec5SDimitry Andric /// representing static method type are shared with non-method function type. 2840b57cec5SDimitry Andric DenseMap<std::pair<const DINode *, const DIType *>, codeview::TypeIndex> 2850b57cec5SDimitry Andric TypeIndices; 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric /// Map from DICompositeType* to complete type index. Non-record types are 2880b57cec5SDimitry Andric /// always looked up in the normal TypeIndices map. 2890b57cec5SDimitry Andric DenseMap<const DICompositeType *, codeview::TypeIndex> CompleteTypeIndices; 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric /// Complete record types to emit after all active type lowerings are 2920b57cec5SDimitry Andric /// finished. 2930b57cec5SDimitry Andric SmallVector<const DICompositeType *, 4> DeferredCompleteTypes; 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric /// Number of type lowering frames active on the stack. 2960b57cec5SDimitry Andric unsigned TypeEmissionLevel = 0; 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric codeview::TypeIndex VBPType; 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric const DISubprogram *CurrentSubprogram = nullptr; 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric // The UDTs we have seen while processing types; each entry is a pair of type 3030b57cec5SDimitry Andric // index and type name. 3040b57cec5SDimitry Andric std::vector<std::pair<std::string, const DIType *>> LocalUDTs; 3050b57cec5SDimitry Andric std::vector<std::pair<std::string, const DIType *>> GlobalUDTs; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric using FileToFilepathMapTy = std::map<const DIFile *, std::string>; 3080b57cec5SDimitry Andric FileToFilepathMapTy FileToFilepathMap; 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric StringRef getFullFilepath(const DIFile *File); 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric unsigned maybeRecordFile(const DIFile *F); 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric void maybeRecordLocation(const DebugLoc &DL, const MachineFunction *MF); 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric void clear(); 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric void setCurrentSubprogram(const DISubprogram *SP) { 3190b57cec5SDimitry Andric CurrentSubprogram = SP; 3200b57cec5SDimitry Andric LocalUDTs.clear(); 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric /// Emit the magic version number at the start of a CodeView type or symbol 3240b57cec5SDimitry Andric /// section. Appears at the front of every .debug$S or .debug$T or .debug$P 3250b57cec5SDimitry Andric /// section. 3260b57cec5SDimitry Andric void emitCodeViewMagicVersion(); 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric void emitTypeInformation(); 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric void emitTypeGlobalHashes(); 3310b57cec5SDimitry Andric 3320eae32dcSDimitry Andric void emitObjName(); 3330eae32dcSDimitry Andric 3340b57cec5SDimitry Andric void emitCompilerInformation(); 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric void emitBuildInfo(); 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric void emitInlineeLinesSubsection(); 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric void emitDebugInfoForThunk(const Function *GV, 3410b57cec5SDimitry Andric FunctionInfo &FI, 3420b57cec5SDimitry Andric const MCSymbol *Fn); 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI); 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric void emitDebugInfoForRetainedTypes(); 3470b57cec5SDimitry Andric 3485ffd83dbSDimitry Andric void emitDebugInfoForUDTs( 3495ffd83dbSDimitry Andric const std::vector<std::pair<std::string, const DIType *>> &UDTs); 3500b57cec5SDimitry Andric 351e8d8bef9SDimitry Andric void collectDebugInfoForGlobals(); 3520b57cec5SDimitry Andric void emitDebugInfoForGlobals(); 3530b57cec5SDimitry Andric void emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals); 354fe6060f1SDimitry Andric void emitConstantSymbolRecord(const DIType *DTy, APSInt &Value, 355fe6060f1SDimitry Andric const std::string &QualifiedName); 3560b57cec5SDimitry Andric void emitDebugInfoForGlobal(const CVGlobalVariable &CVGV); 357e8d8bef9SDimitry Andric void emitStaticConstMemberList(); 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric /// Opens a subsection of the given kind in a .debug$S codeview section. 3600b57cec5SDimitry Andric /// Returns an end label for use with endCVSubsection when the subsection is 3610b57cec5SDimitry Andric /// finished. 3620b57cec5SDimitry Andric MCSymbol *beginCVSubsection(codeview::DebugSubsectionKind Kind); 3630b57cec5SDimitry Andric void endCVSubsection(MCSymbol *EndLabel); 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric /// Opens a symbol record of the given kind. Returns an end label for use with 3660b57cec5SDimitry Andric /// endSymbolRecord. 3670b57cec5SDimitry Andric MCSymbol *beginSymbolRecord(codeview::SymbolKind Kind); 3680b57cec5SDimitry Andric void endSymbolRecord(MCSymbol *SymEnd); 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric /// Emits an S_END, S_INLINESITE_END, or S_PROC_ID_END record. These records 3710b57cec5SDimitry Andric /// are empty, so we emit them with a simpler assembly sequence that doesn't 3720b57cec5SDimitry Andric /// involve labels. 3730b57cec5SDimitry Andric void emitEndSymbolRecord(codeview::SymbolKind EndKind); 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt, 3760b57cec5SDimitry Andric const InlineSite &Site); 3770b57cec5SDimitry Andric 3785f757f3fSDimitry Andric void emitInlinees(const SmallSet<codeview::TypeIndex, 1> &Inlinees); 3795f757f3fSDimitry Andric 3800b57cec5SDimitry Andric using InlinedEntity = DbgValueHistoryMap::InlinedEntity; 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric void collectGlobalVariableInfo(); 3830b57cec5SDimitry Andric void collectVariableInfo(const DISubprogram *SP); 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric void collectVariableInfoFromMFTable(DenseSet<InlinedEntity> &Processed); 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric // Construct the lexical block tree for a routine, pruning emptpy lexical 3880b57cec5SDimitry Andric // scopes, and populate it with local variables. 3890b57cec5SDimitry Andric void collectLexicalBlockInfo(SmallVectorImpl<LexicalScope *> &Scopes, 3900b57cec5SDimitry Andric SmallVectorImpl<LexicalBlock *> &Blocks, 3910b57cec5SDimitry Andric SmallVectorImpl<LocalVariable> &Locals, 3920b57cec5SDimitry Andric SmallVectorImpl<CVGlobalVariable> &Globals); 3930b57cec5SDimitry Andric void collectLexicalBlockInfo(LexicalScope &Scope, 3940b57cec5SDimitry Andric SmallVectorImpl<LexicalBlock *> &ParentBlocks, 3950b57cec5SDimitry Andric SmallVectorImpl<LocalVariable> &ParentLocals, 3960b57cec5SDimitry Andric SmallVectorImpl<CVGlobalVariable> &ParentGlobals); 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric /// Records information about a local variable in the appropriate scope. In 3990b57cec5SDimitry Andric /// particular, locals from inlined code live inside the inlining site. 4000b57cec5SDimitry Andric void recordLocalVariable(LocalVariable &&Var, const LexicalScope *LS); 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric /// Emits local variables in the appropriate order. 4030b57cec5SDimitry Andric void emitLocalVariableList(const FunctionInfo &FI, 4040b57cec5SDimitry Andric ArrayRef<LocalVariable> Locals); 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric /// Emits an S_LOCAL record and its associated defined ranges. 4070b57cec5SDimitry Andric void emitLocalVariable(const FunctionInfo &FI, const LocalVariable &Var); 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric /// Emits a sequence of lexical block scopes and their children. 4100b57cec5SDimitry Andric void emitLexicalBlockList(ArrayRef<LexicalBlock *> Blocks, 4110b57cec5SDimitry Andric const FunctionInfo& FI); 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric /// Emit a lexical block scope and its children. 4140b57cec5SDimitry Andric void emitLexicalBlock(const LexicalBlock &Block, const FunctionInfo& FI); 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric /// Translates the DIType to codeview if necessary and returns a type index 4170b57cec5SDimitry Andric /// for it. 4180b57cec5SDimitry Andric codeview::TypeIndex getTypeIndex(const DIType *Ty, 4190b57cec5SDimitry Andric const DIType *ClassTy = nullptr); 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric codeview::TypeIndex 4220b57cec5SDimitry Andric getTypeIndexForThisPtr(const DIDerivedType *PtrTy, 4230b57cec5SDimitry Andric const DISubroutineType *SubroutineTy); 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric codeview::TypeIndex getTypeIndexForReferenceTo(const DIType *Ty); 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric codeview::TypeIndex getMemberFunctionType(const DISubprogram *SP, 4280b57cec5SDimitry Andric const DICompositeType *Class); 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric codeview::TypeIndex getScopeIndex(const DIScope *Scope); 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric codeview::TypeIndex getVBPTypeIndex(); 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric void addToUDTs(const DIType *Ty); 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric void addUDTSrcLine(const DIType *Ty, codeview::TypeIndex TI); 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric codeview::TypeIndex lowerType(const DIType *Ty, const DIType *ClassTy); 4390b57cec5SDimitry Andric codeview::TypeIndex lowerTypeAlias(const DIDerivedType *Ty); 4400b57cec5SDimitry Andric codeview::TypeIndex lowerTypeArray(const DICompositeType *Ty); 441349cc55cSDimitry Andric codeview::TypeIndex lowerTypeString(const DIStringType *Ty); 4420b57cec5SDimitry Andric codeview::TypeIndex lowerTypeBasic(const DIBasicType *Ty); 4430b57cec5SDimitry Andric codeview::TypeIndex lowerTypePointer( 4440b57cec5SDimitry Andric const DIDerivedType *Ty, 4450b57cec5SDimitry Andric codeview::PointerOptions PO = codeview::PointerOptions::None); 4460b57cec5SDimitry Andric codeview::TypeIndex lowerTypeMemberPointer( 4470b57cec5SDimitry Andric const DIDerivedType *Ty, 4480b57cec5SDimitry Andric codeview::PointerOptions PO = codeview::PointerOptions::None); 4490b57cec5SDimitry Andric codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty); 4500b57cec5SDimitry Andric codeview::TypeIndex lowerTypeFunction(const DISubroutineType *Ty); 4510b57cec5SDimitry Andric codeview::TypeIndex lowerTypeVFTableShape(const DIDerivedType *Ty); 4520b57cec5SDimitry Andric codeview::TypeIndex lowerTypeMemberFunction( 4530b57cec5SDimitry Andric const DISubroutineType *Ty, const DIType *ClassTy, int ThisAdjustment, 4540b57cec5SDimitry Andric bool IsStaticMethod, 4550b57cec5SDimitry Andric codeview::FunctionOptions FO = codeview::FunctionOptions::None); 4560b57cec5SDimitry Andric codeview::TypeIndex lowerTypeEnum(const DICompositeType *Ty); 4570b57cec5SDimitry Andric codeview::TypeIndex lowerTypeClass(const DICompositeType *Ty); 4580b57cec5SDimitry Andric codeview::TypeIndex lowerTypeUnion(const DICompositeType *Ty); 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric /// Symbol records should point to complete types, but type records should 4610b57cec5SDimitry Andric /// always point to incomplete types to avoid cycles in the type graph. Only 4620b57cec5SDimitry Andric /// use this entry point when generating symbol records. The complete and 4630b57cec5SDimitry Andric /// incomplete type indices only differ for record types. All other types use 4640b57cec5SDimitry Andric /// the same index. 4650b57cec5SDimitry Andric codeview::TypeIndex getCompleteTypeIndex(const DIType *Ty); 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric codeview::TypeIndex lowerCompleteTypeClass(const DICompositeType *Ty); 4680b57cec5SDimitry Andric codeview::TypeIndex lowerCompleteTypeUnion(const DICompositeType *Ty); 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric struct TypeLoweringScope; 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric void emitDeferredCompleteTypes(); 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric void collectMemberInfo(ClassInfo &Info, const DIDerivedType *DDTy); 4750b57cec5SDimitry Andric ClassInfo collectClassInfo(const DICompositeType *Ty); 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric /// Common record member lowering functionality for record types, which are 4780b57cec5SDimitry Andric /// structs, classes, and unions. Returns the field list index and the member 4790b57cec5SDimitry Andric /// count. 4800b57cec5SDimitry Andric std::tuple<codeview::TypeIndex, codeview::TypeIndex, unsigned, bool> 4810b57cec5SDimitry Andric lowerRecordFieldList(const DICompositeType *Ty); 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric /// Inserts {{Node, ClassTy}, TI} into TypeIndices and checks for duplicates. 4840b57cec5SDimitry Andric codeview::TypeIndex recordTypeIndexForDINode(const DINode *Node, 4850b57cec5SDimitry Andric codeview::TypeIndex TI, 4860b57cec5SDimitry Andric const DIType *ClassTy = nullptr); 4870b57cec5SDimitry Andric 4885ffd83dbSDimitry Andric /// Collect the names of parent scopes, innermost to outermost. Return the 4895ffd83dbSDimitry Andric /// innermost subprogram scope if present. Ensure that parent type scopes are 4905ffd83dbSDimitry Andric /// inserted into the type table. 4915ffd83dbSDimitry Andric const DISubprogram * 4925ffd83dbSDimitry Andric collectParentScopeNames(const DIScope *Scope, 4935ffd83dbSDimitry Andric SmallVectorImpl<StringRef> &ParentScopeNames); 4945ffd83dbSDimitry Andric std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name); 4955ffd83dbSDimitry Andric std::string getFullyQualifiedName(const DIScope *Scope); 4965ffd83dbSDimitry Andric 4970b57cec5SDimitry Andric unsigned getPointerSizeInBytes(); 4980b57cec5SDimitry Andric 4995f757f3fSDimitry Andric void discoverJumpTableBranches(const MachineFunction *MF, bool isThumb); 5005f757f3fSDimitry Andric void collectDebugInfoForJumpTables(const MachineFunction *MF, bool isThumb); 5015f757f3fSDimitry Andric void emitDebugInfoForJumpTables(const FunctionInfo &FI); 5025f757f3fSDimitry Andric 5030b57cec5SDimitry Andric protected: 5040b57cec5SDimitry Andric /// Gather pre-function debug information. 5050b57cec5SDimitry Andric void beginFunctionImpl(const MachineFunction *MF) override; 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric /// Gather post-function debug information. 5080b57cec5SDimitry Andric void endFunctionImpl(const MachineFunction *) override; 5090b57cec5SDimitry Andric 510349cc55cSDimitry Andric /// Check if the current module is in Fortran. 511349cc55cSDimitry Andric bool moduleIsInFortran() { 512349cc55cSDimitry Andric return CurrentSourceLanguage == codeview::SourceLanguage::Fortran; 513349cc55cSDimitry Andric } 514349cc55cSDimitry Andric 5150b57cec5SDimitry Andric public: 5160b57cec5SDimitry Andric CodeViewDebug(AsmPrinter *AP); 5170b57cec5SDimitry Andric 518e8d8bef9SDimitry Andric void beginModule(Module *M) override; 519e8d8bef9SDimitry Andric 5200b57cec5SDimitry Andric /// Emit the COFF section that holds the line table information. 5210b57cec5SDimitry Andric void endModule() override; 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric /// Process beginning of an instruction. 5240b57cec5SDimitry Andric void beginInstruction(const MachineInstr *MI) override; 5250b57cec5SDimitry Andric }; 5260b57cec5SDimitry Andric 52781ad6265SDimitry Andric template <> struct DenseMapInfo<CodeViewDebug::LocalVarDef> { 52881ad6265SDimitry Andric 52981ad6265SDimitry Andric static inline CodeViewDebug::LocalVarDef getEmptyKey() { 53081ad6265SDimitry Andric return CodeViewDebug::LocalVarDef::createFromOpaqueValue(~0ULL); 53181ad6265SDimitry Andric } 53281ad6265SDimitry Andric 53381ad6265SDimitry Andric static inline CodeViewDebug::LocalVarDef getTombstoneKey() { 53481ad6265SDimitry Andric return CodeViewDebug::LocalVarDef::createFromOpaqueValue(~0ULL - 1ULL); 53581ad6265SDimitry Andric } 53681ad6265SDimitry Andric 53781ad6265SDimitry Andric static unsigned getHashValue(const CodeViewDebug::LocalVarDef &DR) { 53881ad6265SDimitry Andric return CodeViewDebug::LocalVarDef::toOpaqueValue(DR) * 37ULL; 53981ad6265SDimitry Andric } 54081ad6265SDimitry Andric 54181ad6265SDimitry Andric static bool isEqual(const CodeViewDebug::LocalVarDef &LHS, 54281ad6265SDimitry Andric const CodeViewDebug::LocalVarDef &RHS) { 54381ad6265SDimitry Andric return CodeViewDebug::LocalVarDef::toOpaqueValue(LHS) == 54481ad6265SDimitry Andric CodeViewDebug::LocalVarDef::toOpaqueValue(RHS); 54581ad6265SDimitry Andric } 54681ad6265SDimitry Andric }; 54781ad6265SDimitry Andric 5480b57cec5SDimitry Andric } // end namespace llvm 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H 551