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 160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 170b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 180b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h" 190b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h" 200b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h" 210b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h" 220b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/DbgEntityHistoryCalculator.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/DebugHandlerBase.h" 250b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h" 260b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" 270b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h" 280b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 290b57cec5SDimitry Andric #include "llvm/Support/Allocator.h" 300b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 310b57cec5SDimitry Andric #include <cstdint> 320b57cec5SDimitry Andric #include <map> 330b57cec5SDimitry Andric #include <string> 340b57cec5SDimitry Andric #include <tuple> 350b57cec5SDimitry Andric #include <unordered_map> 360b57cec5SDimitry Andric #include <utility> 370b57cec5SDimitry Andric #include <vector> 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric namespace llvm { 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric struct ClassInfo; 420b57cec5SDimitry Andric class StringRef; 430b57cec5SDimitry Andric class AsmPrinter; 440b57cec5SDimitry Andric class Function; 450b57cec5SDimitry Andric class GlobalVariable; 460b57cec5SDimitry Andric class MCSectionCOFF; 470b57cec5SDimitry Andric class MCStreamer; 480b57cec5SDimitry Andric class MCSymbol; 490b57cec5SDimitry Andric class MachineFunction; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric /// Collects and handles line tables information in a CodeView format. 520b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { 5381ad6265SDimitry Andric public: 5481ad6265SDimitry Andric struct LocalVarDef { 550b57cec5SDimitry Andric /// Indicates that variable data is stored in memory relative to the 560b57cec5SDimitry Andric /// specified register. 570b57cec5SDimitry Andric int InMemory : 1; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric /// Offset of variable data in memory. 600b57cec5SDimitry Andric int DataOffset : 31; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric /// Non-zero if this is a piece of an aggregate. 630b57cec5SDimitry Andric uint16_t IsSubfield : 1; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric /// Offset into aggregate. 660b57cec5SDimitry Andric uint16_t StructOffset : 15; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric /// Register containing the data or the register base of the memory 690b57cec5SDimitry Andric /// location containing the data. 700b57cec5SDimitry Andric uint16_t CVRegister; 710b57cec5SDimitry Andric 7281ad6265SDimitry Andric uint64_t static toOpaqueValue(const LocalVarDef DR) { 7381ad6265SDimitry Andric uint64_t Val = 0; 7481ad6265SDimitry Andric std::memcpy(&Val, &DR, sizeof(Val)); 7581ad6265SDimitry Andric return Val; 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric 7881ad6265SDimitry Andric LocalVarDef static createFromOpaqueValue(uint64_t Val) { 7981ad6265SDimitry Andric LocalVarDef DR; 8081ad6265SDimitry Andric std::memcpy(&DR, &Val, sizeof(Val)); 8181ad6265SDimitry Andric return DR; 8281ad6265SDimitry Andric } 830b57cec5SDimitry Andric }; 840b57cec5SDimitry Andric 85*bdd1243dSDimitry Andric static_assert(sizeof(uint64_t) == sizeof(LocalVarDef)); 8681ad6265SDimitry Andric 8781ad6265SDimitry Andric private: 8881ad6265SDimitry Andric MCStreamer &OS; 8981ad6265SDimitry Andric BumpPtrAllocator Allocator; 9081ad6265SDimitry Andric codeview::GlobalTypeTableBuilder TypeTable; 9181ad6265SDimitry Andric 9281ad6265SDimitry Andric /// Whether to emit type record hashes into .debug$H. 9381ad6265SDimitry Andric bool EmitDebugGlobalHashes = false; 9481ad6265SDimitry Andric 9581ad6265SDimitry Andric /// The codeview CPU type used by the translation unit. 9681ad6265SDimitry Andric codeview::CPUType TheCPU; 9781ad6265SDimitry Andric 9881ad6265SDimitry Andric static LocalVarDef createDefRangeMem(uint16_t CVRegister, int Offset); 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric /// Similar to DbgVariable in DwarfDebug, but not dwarf-specific. 1010b57cec5SDimitry Andric struct LocalVariable { 1020b57cec5SDimitry Andric const DILocalVariable *DIVar = nullptr; 10381ad6265SDimitry Andric MapVector<LocalVarDef, 10481ad6265SDimitry Andric SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1>> 10581ad6265SDimitry Andric DefRanges; 1060b57cec5SDimitry Andric bool UseReferenceType = false; 107*bdd1243dSDimitry Andric std::optional<APSInt> ConstantValue; 1080b57cec5SDimitry Andric }; 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric struct CVGlobalVariable { 1110b57cec5SDimitry Andric const DIGlobalVariable *DIGV; 1120b57cec5SDimitry Andric PointerUnion<const GlobalVariable *, const DIExpression *> GVInfo; 1130b57cec5SDimitry Andric }; 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric struct InlineSite { 1160b57cec5SDimitry Andric SmallVector<LocalVariable, 1> InlinedLocals; 1170b57cec5SDimitry Andric SmallVector<const DILocation *, 1> ChildSites; 1180b57cec5SDimitry Andric const DISubprogram *Inlinee = nullptr; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric /// The ID of the inline site or function used with .cv_loc. Not a type 1210b57cec5SDimitry Andric /// index. 1220b57cec5SDimitry Andric unsigned SiteFuncId = 0; 1230b57cec5SDimitry Andric }; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric // Combines information from DILexicalBlock and LexicalScope. 1260b57cec5SDimitry Andric struct LexicalBlock { 1270b57cec5SDimitry Andric SmallVector<LocalVariable, 1> Locals; 1280b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> Globals; 1290b57cec5SDimitry Andric SmallVector<LexicalBlock *, 1> Children; 1300b57cec5SDimitry Andric const MCSymbol *Begin; 1310b57cec5SDimitry Andric const MCSymbol *End; 1320b57cec5SDimitry Andric StringRef Name; 1330b57cec5SDimitry Andric }; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric // For each function, store a vector of labels to its instructions, as well as 1360b57cec5SDimitry Andric // to the end of the function. 1370b57cec5SDimitry Andric struct FunctionInfo { 1380b57cec5SDimitry Andric FunctionInfo() = default; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric // Uncopyable. 1410b57cec5SDimitry Andric FunctionInfo(const FunctionInfo &FI) = delete; 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric /// Map from inlined call site to inlined instructions and child inlined 1440b57cec5SDimitry Andric /// call sites. Listed in program order. 1450b57cec5SDimitry Andric std::unordered_map<const DILocation *, InlineSite> InlineSites; 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric /// Ordered list of top-level inlined call sites. 1480b57cec5SDimitry Andric SmallVector<const DILocation *, 1> ChildSites; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric SmallVector<LocalVariable, 1> Locals; 1510b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> Globals; 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric std::unordered_map<const DILexicalBlockBase*, LexicalBlock> LexicalBlocks; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric // Lexical blocks containing local variables. 1560b57cec5SDimitry Andric SmallVector<LexicalBlock *, 1> ChildBlocks; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric std::vector<std::pair<MCSymbol *, MDNode *>> Annotations; 159c14a5a88SDimitry Andric std::vector<std::tuple<const MCSymbol *, const MCSymbol *, const DIType *>> 160c14a5a88SDimitry Andric HeapAllocSites; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric const MCSymbol *Begin = nullptr; 1630b57cec5SDimitry Andric const MCSymbol *End = nullptr; 1640b57cec5SDimitry Andric unsigned FuncId = 0; 1650b57cec5SDimitry Andric unsigned LastFileId = 0; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric /// Number of bytes allocated in the prologue for all local stack objects. 1680b57cec5SDimitry Andric unsigned FrameSize = 0; 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric /// Number of bytes of parameters on the stack. 1710b57cec5SDimitry Andric unsigned ParamSize = 0; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric /// Number of bytes pushed to save CSRs. 1740b57cec5SDimitry Andric unsigned CSRSize = 0; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric /// Adjustment to apply on x86 when using the VFRAME frame pointer. 1770b57cec5SDimitry Andric int OffsetAdjustment = 0; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric /// Two-bit value indicating which register is the designated frame pointer 1800b57cec5SDimitry Andric /// register for local variables. Included in S_FRAMEPROC. 1810b57cec5SDimitry Andric codeview::EncodedFramePtrReg EncodedLocalFramePtrReg = 1820b57cec5SDimitry Andric codeview::EncodedFramePtrReg::None; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric /// Two-bit value indicating which register is the designated frame pointer 1850b57cec5SDimitry Andric /// register for stack parameters. Included in S_FRAMEPROC. 1860b57cec5SDimitry Andric codeview::EncodedFramePtrReg EncodedParamFramePtrReg = 1870b57cec5SDimitry Andric codeview::EncodedFramePtrReg::None; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric codeview::FrameProcedureOptions FrameProcOpts; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric bool HasStackRealignment = false; 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric bool HaveLineInfo = false; 1940b57cec5SDimitry Andric }; 1950b57cec5SDimitry Andric FunctionInfo *CurFn = nullptr; 1960b57cec5SDimitry Andric 197349cc55cSDimitry Andric codeview::SourceLanguage CurrentSourceLanguage = 198349cc55cSDimitry Andric codeview::SourceLanguage::Masm; 199349cc55cSDimitry Andric 200349cc55cSDimitry Andric // This map records the constant offset in DIExpression of the 201349cc55cSDimitry Andric // DIGlobalVariableExpression referencing the DIGlobalVariable. 202349cc55cSDimitry Andric DenseMap<const DIGlobalVariable *, uint64_t> CVGlobalVariableOffsets; 203349cc55cSDimitry Andric 2040b57cec5SDimitry Andric // Map used to seperate variables according to the lexical scope they belong 2050b57cec5SDimitry Andric // in. This is populated by recordLocalVariable() before 2060b57cec5SDimitry Andric // collectLexicalBlocks() separates the variables between the FunctionInfo 2070b57cec5SDimitry Andric // and LexicalBlocks. 2080b57cec5SDimitry Andric DenseMap<const LexicalScope *, SmallVector<LocalVariable, 1>> ScopeVariables; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric // Map to separate global variables according to the lexical scope they 2110b57cec5SDimitry Andric // belong in. A null local scope represents the global scope. 2120b57cec5SDimitry Andric typedef SmallVector<CVGlobalVariable, 1> GlobalVariableList; 2130b57cec5SDimitry Andric DenseMap<const DIScope*, std::unique_ptr<GlobalVariableList> > ScopeGlobals; 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric // Array of global variables which need to be emitted into a COMDAT section. 2160b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> ComdatVariables; 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric // Array of non-COMDAT global variables. 2190b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> GlobalVariables; 2200b57cec5SDimitry Andric 221e8d8bef9SDimitry Andric /// List of static const data members to be emitted as S_CONSTANTs. 222e8d8bef9SDimitry Andric SmallVector<const DIDerivedType *, 4> StaticConstMembers; 223e8d8bef9SDimitry Andric 2240b57cec5SDimitry Andric /// The set of comdat .debug$S sections that we've seen so far. Each section 2250b57cec5SDimitry Andric /// must start with a magic version number that must only be emitted once. 2260b57cec5SDimitry Andric /// This set tracks which sections we've already opened. 2270b57cec5SDimitry Andric DenseSet<MCSectionCOFF *> ComdatDebugSections; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric /// Switch to the appropriate .debug$S section for GVSym. If GVSym, the symbol 2300b57cec5SDimitry Andric /// of an emitted global value, is in a comdat COFF section, this will switch 2310b57cec5SDimitry Andric /// to a new .debug$S section in that comdat. This method ensures that the 2320b57cec5SDimitry Andric /// section starts with the magic version number on first use. If GVSym is 2330b57cec5SDimitry Andric /// null, uses the main .debug$S section. 2340b57cec5SDimitry Andric void switchToDebugSectionForSymbol(const MCSymbol *GVSym); 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric /// The next available function index for use with our .cv_* directives. Not 2370b57cec5SDimitry Andric /// to be confused with type indices for LF_FUNC_ID records. 2380b57cec5SDimitry Andric unsigned NextFuncId = 0; 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric InlineSite &getInlineSite(const DILocation *InlinedAt, 2410b57cec5SDimitry Andric const DISubprogram *Inlinee); 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP); 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric void calculateRanges(LocalVariable &Var, 2460b57cec5SDimitry Andric const DbgValueHistoryMap::Entries &Entries); 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric /// Remember some debug info about each function. Keep it in a stable order to 2490b57cec5SDimitry Andric /// emit at the end of the TU. 2500b57cec5SDimitry Andric MapVector<const Function *, std::unique_ptr<FunctionInfo>> FnDebugInfo; 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric /// Map from full file path to .cv_file id. Full paths are built from DIFiles 2530b57cec5SDimitry Andric /// and are stored in FileToFilepathMap; 2540b57cec5SDimitry Andric DenseMap<StringRef, unsigned> FileIdMap; 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric /// All inlined subprograms in the order they should be emitted. 2570b57cec5SDimitry Andric SmallSetVector<const DISubprogram *, 4> InlinedSubprograms; 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric /// Map from a pair of DI metadata nodes and its DI type (or scope) that can 2600b57cec5SDimitry Andric /// be nullptr, to CodeView type indices. Primarily indexed by 2610b57cec5SDimitry Andric /// {DIType*, DIType*} and {DISubprogram*, DIType*}. 2620b57cec5SDimitry Andric /// 2630b57cec5SDimitry Andric /// The second entry in the key is needed for methods as DISubroutineType 2640b57cec5SDimitry Andric /// representing static method type are shared with non-method function type. 2650b57cec5SDimitry Andric DenseMap<std::pair<const DINode *, const DIType *>, codeview::TypeIndex> 2660b57cec5SDimitry Andric TypeIndices; 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric /// Map from DICompositeType* to complete type index. Non-record types are 2690b57cec5SDimitry Andric /// always looked up in the normal TypeIndices map. 2700b57cec5SDimitry Andric DenseMap<const DICompositeType *, codeview::TypeIndex> CompleteTypeIndices; 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric /// Complete record types to emit after all active type lowerings are 2730b57cec5SDimitry Andric /// finished. 2740b57cec5SDimitry Andric SmallVector<const DICompositeType *, 4> DeferredCompleteTypes; 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric /// Number of type lowering frames active on the stack. 2770b57cec5SDimitry Andric unsigned TypeEmissionLevel = 0; 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric codeview::TypeIndex VBPType; 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric const DISubprogram *CurrentSubprogram = nullptr; 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric // The UDTs we have seen while processing types; each entry is a pair of type 2840b57cec5SDimitry Andric // index and type name. 2850b57cec5SDimitry Andric std::vector<std::pair<std::string, const DIType *>> LocalUDTs; 2860b57cec5SDimitry Andric std::vector<std::pair<std::string, const DIType *>> GlobalUDTs; 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric using FileToFilepathMapTy = std::map<const DIFile *, std::string>; 2890b57cec5SDimitry Andric FileToFilepathMapTy FileToFilepathMap; 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric StringRef getFullFilepath(const DIFile *File); 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric unsigned maybeRecordFile(const DIFile *F); 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric void maybeRecordLocation(const DebugLoc &DL, const MachineFunction *MF); 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric void clear(); 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric void setCurrentSubprogram(const DISubprogram *SP) { 3000b57cec5SDimitry Andric CurrentSubprogram = SP; 3010b57cec5SDimitry Andric LocalUDTs.clear(); 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric /// Emit the magic version number at the start of a CodeView type or symbol 3050b57cec5SDimitry Andric /// section. Appears at the front of every .debug$S or .debug$T or .debug$P 3060b57cec5SDimitry Andric /// section. 3070b57cec5SDimitry Andric void emitCodeViewMagicVersion(); 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric void emitTypeInformation(); 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric void emitTypeGlobalHashes(); 3120b57cec5SDimitry Andric 3130eae32dcSDimitry Andric void emitObjName(); 3140eae32dcSDimitry Andric 3150b57cec5SDimitry Andric void emitCompilerInformation(); 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric void emitBuildInfo(); 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric void emitInlineeLinesSubsection(); 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric void emitDebugInfoForThunk(const Function *GV, 3220b57cec5SDimitry Andric FunctionInfo &FI, 3230b57cec5SDimitry Andric const MCSymbol *Fn); 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI); 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric void emitDebugInfoForRetainedTypes(); 3280b57cec5SDimitry Andric 3295ffd83dbSDimitry Andric void emitDebugInfoForUDTs( 3305ffd83dbSDimitry Andric const std::vector<std::pair<std::string, const DIType *>> &UDTs); 3310b57cec5SDimitry Andric 332e8d8bef9SDimitry Andric void collectDebugInfoForGlobals(); 3330b57cec5SDimitry Andric void emitDebugInfoForGlobals(); 3340b57cec5SDimitry Andric void emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals); 335fe6060f1SDimitry Andric void emitConstantSymbolRecord(const DIType *DTy, APSInt &Value, 336fe6060f1SDimitry Andric const std::string &QualifiedName); 3370b57cec5SDimitry Andric void emitDebugInfoForGlobal(const CVGlobalVariable &CVGV); 338e8d8bef9SDimitry Andric void emitStaticConstMemberList(); 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric /// Opens a subsection of the given kind in a .debug$S codeview section. 3410b57cec5SDimitry Andric /// Returns an end label for use with endCVSubsection when the subsection is 3420b57cec5SDimitry Andric /// finished. 3430b57cec5SDimitry Andric MCSymbol *beginCVSubsection(codeview::DebugSubsectionKind Kind); 3440b57cec5SDimitry Andric void endCVSubsection(MCSymbol *EndLabel); 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric /// Opens a symbol record of the given kind. Returns an end label for use with 3470b57cec5SDimitry Andric /// endSymbolRecord. 3480b57cec5SDimitry Andric MCSymbol *beginSymbolRecord(codeview::SymbolKind Kind); 3490b57cec5SDimitry Andric void endSymbolRecord(MCSymbol *SymEnd); 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric /// Emits an S_END, S_INLINESITE_END, or S_PROC_ID_END record. These records 3520b57cec5SDimitry Andric /// are empty, so we emit them with a simpler assembly sequence that doesn't 3530b57cec5SDimitry Andric /// involve labels. 3540b57cec5SDimitry Andric void emitEndSymbolRecord(codeview::SymbolKind EndKind); 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt, 3570b57cec5SDimitry Andric const InlineSite &Site); 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric using InlinedEntity = DbgValueHistoryMap::InlinedEntity; 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric void collectGlobalVariableInfo(); 3620b57cec5SDimitry Andric void collectVariableInfo(const DISubprogram *SP); 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric void collectVariableInfoFromMFTable(DenseSet<InlinedEntity> &Processed); 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric // Construct the lexical block tree for a routine, pruning emptpy lexical 3670b57cec5SDimitry Andric // scopes, and populate it with local variables. 3680b57cec5SDimitry Andric void collectLexicalBlockInfo(SmallVectorImpl<LexicalScope *> &Scopes, 3690b57cec5SDimitry Andric SmallVectorImpl<LexicalBlock *> &Blocks, 3700b57cec5SDimitry Andric SmallVectorImpl<LocalVariable> &Locals, 3710b57cec5SDimitry Andric SmallVectorImpl<CVGlobalVariable> &Globals); 3720b57cec5SDimitry Andric void collectLexicalBlockInfo(LexicalScope &Scope, 3730b57cec5SDimitry Andric SmallVectorImpl<LexicalBlock *> &ParentBlocks, 3740b57cec5SDimitry Andric SmallVectorImpl<LocalVariable> &ParentLocals, 3750b57cec5SDimitry Andric SmallVectorImpl<CVGlobalVariable> &ParentGlobals); 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric /// Records information about a local variable in the appropriate scope. In 3780b57cec5SDimitry Andric /// particular, locals from inlined code live inside the inlining site. 3790b57cec5SDimitry Andric void recordLocalVariable(LocalVariable &&Var, const LexicalScope *LS); 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric /// Emits local variables in the appropriate order. 3820b57cec5SDimitry Andric void emitLocalVariableList(const FunctionInfo &FI, 3830b57cec5SDimitry Andric ArrayRef<LocalVariable> Locals); 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric /// Emits an S_LOCAL record and its associated defined ranges. 3860b57cec5SDimitry Andric void emitLocalVariable(const FunctionInfo &FI, const LocalVariable &Var); 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric /// Emits a sequence of lexical block scopes and their children. 3890b57cec5SDimitry Andric void emitLexicalBlockList(ArrayRef<LexicalBlock *> Blocks, 3900b57cec5SDimitry Andric const FunctionInfo& FI); 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric /// Emit a lexical block scope and its children. 3930b57cec5SDimitry Andric void emitLexicalBlock(const LexicalBlock &Block, const FunctionInfo& FI); 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric /// Translates the DIType to codeview if necessary and returns a type index 3960b57cec5SDimitry Andric /// for it. 3970b57cec5SDimitry Andric codeview::TypeIndex getTypeIndex(const DIType *Ty, 3980b57cec5SDimitry Andric const DIType *ClassTy = nullptr); 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric codeview::TypeIndex 4010b57cec5SDimitry Andric getTypeIndexForThisPtr(const DIDerivedType *PtrTy, 4020b57cec5SDimitry Andric const DISubroutineType *SubroutineTy); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric codeview::TypeIndex getTypeIndexForReferenceTo(const DIType *Ty); 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric codeview::TypeIndex getMemberFunctionType(const DISubprogram *SP, 4070b57cec5SDimitry Andric const DICompositeType *Class); 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric codeview::TypeIndex getScopeIndex(const DIScope *Scope); 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric codeview::TypeIndex getVBPTypeIndex(); 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric void addToUDTs(const DIType *Ty); 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric void addUDTSrcLine(const DIType *Ty, codeview::TypeIndex TI); 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric codeview::TypeIndex lowerType(const DIType *Ty, const DIType *ClassTy); 4180b57cec5SDimitry Andric codeview::TypeIndex lowerTypeAlias(const DIDerivedType *Ty); 4190b57cec5SDimitry Andric codeview::TypeIndex lowerTypeArray(const DICompositeType *Ty); 420349cc55cSDimitry Andric codeview::TypeIndex lowerTypeString(const DIStringType *Ty); 4210b57cec5SDimitry Andric codeview::TypeIndex lowerTypeBasic(const DIBasicType *Ty); 4220b57cec5SDimitry Andric codeview::TypeIndex lowerTypePointer( 4230b57cec5SDimitry Andric const DIDerivedType *Ty, 4240b57cec5SDimitry Andric codeview::PointerOptions PO = codeview::PointerOptions::None); 4250b57cec5SDimitry Andric codeview::TypeIndex lowerTypeMemberPointer( 4260b57cec5SDimitry Andric const DIDerivedType *Ty, 4270b57cec5SDimitry Andric codeview::PointerOptions PO = codeview::PointerOptions::None); 4280b57cec5SDimitry Andric codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty); 4290b57cec5SDimitry Andric codeview::TypeIndex lowerTypeFunction(const DISubroutineType *Ty); 4300b57cec5SDimitry Andric codeview::TypeIndex lowerTypeVFTableShape(const DIDerivedType *Ty); 4310b57cec5SDimitry Andric codeview::TypeIndex lowerTypeMemberFunction( 4320b57cec5SDimitry Andric const DISubroutineType *Ty, const DIType *ClassTy, int ThisAdjustment, 4330b57cec5SDimitry Andric bool IsStaticMethod, 4340b57cec5SDimitry Andric codeview::FunctionOptions FO = codeview::FunctionOptions::None); 4350b57cec5SDimitry Andric codeview::TypeIndex lowerTypeEnum(const DICompositeType *Ty); 4360b57cec5SDimitry Andric codeview::TypeIndex lowerTypeClass(const DICompositeType *Ty); 4370b57cec5SDimitry Andric codeview::TypeIndex lowerTypeUnion(const DICompositeType *Ty); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric /// Symbol records should point to complete types, but type records should 4400b57cec5SDimitry Andric /// always point to incomplete types to avoid cycles in the type graph. Only 4410b57cec5SDimitry Andric /// use this entry point when generating symbol records. The complete and 4420b57cec5SDimitry Andric /// incomplete type indices only differ for record types. All other types use 4430b57cec5SDimitry Andric /// the same index. 4440b57cec5SDimitry Andric codeview::TypeIndex getCompleteTypeIndex(const DIType *Ty); 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric codeview::TypeIndex lowerCompleteTypeClass(const DICompositeType *Ty); 4470b57cec5SDimitry Andric codeview::TypeIndex lowerCompleteTypeUnion(const DICompositeType *Ty); 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric struct TypeLoweringScope; 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric void emitDeferredCompleteTypes(); 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric void collectMemberInfo(ClassInfo &Info, const DIDerivedType *DDTy); 4540b57cec5SDimitry Andric ClassInfo collectClassInfo(const DICompositeType *Ty); 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric /// Common record member lowering functionality for record types, which are 4570b57cec5SDimitry Andric /// structs, classes, and unions. Returns the field list index and the member 4580b57cec5SDimitry Andric /// count. 4590b57cec5SDimitry Andric std::tuple<codeview::TypeIndex, codeview::TypeIndex, unsigned, bool> 4600b57cec5SDimitry Andric lowerRecordFieldList(const DICompositeType *Ty); 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric /// Inserts {{Node, ClassTy}, TI} into TypeIndices and checks for duplicates. 4630b57cec5SDimitry Andric codeview::TypeIndex recordTypeIndexForDINode(const DINode *Node, 4640b57cec5SDimitry Andric codeview::TypeIndex TI, 4650b57cec5SDimitry Andric const DIType *ClassTy = nullptr); 4660b57cec5SDimitry Andric 4675ffd83dbSDimitry Andric /// Collect the names of parent scopes, innermost to outermost. Return the 4685ffd83dbSDimitry Andric /// innermost subprogram scope if present. Ensure that parent type scopes are 4695ffd83dbSDimitry Andric /// inserted into the type table. 4705ffd83dbSDimitry Andric const DISubprogram * 4715ffd83dbSDimitry Andric collectParentScopeNames(const DIScope *Scope, 4725ffd83dbSDimitry Andric SmallVectorImpl<StringRef> &ParentScopeNames); 4735ffd83dbSDimitry Andric std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name); 4745ffd83dbSDimitry Andric std::string getFullyQualifiedName(const DIScope *Scope); 4755ffd83dbSDimitry Andric 4760b57cec5SDimitry Andric unsigned getPointerSizeInBytes(); 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric protected: 4790b57cec5SDimitry Andric /// Gather pre-function debug information. 4800b57cec5SDimitry Andric void beginFunctionImpl(const MachineFunction *MF) override; 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric /// Gather post-function debug information. 4830b57cec5SDimitry Andric void endFunctionImpl(const MachineFunction *) override; 4840b57cec5SDimitry Andric 485349cc55cSDimitry Andric /// Check if the current module is in Fortran. 486349cc55cSDimitry Andric bool moduleIsInFortran() { 487349cc55cSDimitry Andric return CurrentSourceLanguage == codeview::SourceLanguage::Fortran; 488349cc55cSDimitry Andric } 489349cc55cSDimitry Andric 4900b57cec5SDimitry Andric public: 4910b57cec5SDimitry Andric CodeViewDebug(AsmPrinter *AP); 4920b57cec5SDimitry Andric 493e8d8bef9SDimitry Andric void beginModule(Module *M) override; 494e8d8bef9SDimitry Andric 4950b57cec5SDimitry Andric void setSymbolSize(const MCSymbol *, uint64_t) override {} 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric /// Emit the COFF section that holds the line table information. 4980b57cec5SDimitry Andric void endModule() override; 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric /// Process beginning of an instruction. 5010b57cec5SDimitry Andric void beginInstruction(const MachineInstr *MI) override; 5020b57cec5SDimitry Andric }; 5030b57cec5SDimitry Andric 50481ad6265SDimitry Andric template <> struct DenseMapInfo<CodeViewDebug::LocalVarDef> { 50581ad6265SDimitry Andric 50681ad6265SDimitry Andric static inline CodeViewDebug::LocalVarDef getEmptyKey() { 50781ad6265SDimitry Andric return CodeViewDebug::LocalVarDef::createFromOpaqueValue(~0ULL); 50881ad6265SDimitry Andric } 50981ad6265SDimitry Andric 51081ad6265SDimitry Andric static inline CodeViewDebug::LocalVarDef getTombstoneKey() { 51181ad6265SDimitry Andric return CodeViewDebug::LocalVarDef::createFromOpaqueValue(~0ULL - 1ULL); 51281ad6265SDimitry Andric } 51381ad6265SDimitry Andric 51481ad6265SDimitry Andric static unsigned getHashValue(const CodeViewDebug::LocalVarDef &DR) { 51581ad6265SDimitry Andric return CodeViewDebug::LocalVarDef::toOpaqueValue(DR) * 37ULL; 51681ad6265SDimitry Andric } 51781ad6265SDimitry Andric 51881ad6265SDimitry Andric static bool isEqual(const CodeViewDebug::LocalVarDef &LHS, 51981ad6265SDimitry Andric const CodeViewDebug::LocalVarDef &RHS) { 52081ad6265SDimitry Andric return CodeViewDebug::LocalVarDef::toOpaqueValue(LHS) == 52181ad6265SDimitry Andric CodeViewDebug::LocalVarDef::toOpaqueValue(RHS); 52281ad6265SDimitry Andric } 52381ad6265SDimitry Andric }; 52481ad6265SDimitry Andric 5250b57cec5SDimitry Andric } // end namespace llvm 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H 528