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