1*0b57cec5SDimitry Andric //===- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h --------------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file contains support for writing Microsoft CodeView debug info. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H 14*0b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 17*0b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h" 19*0b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h" 20*0b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h" 21*0b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h" 22*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 23*0b57cec5SDimitry Andric #include "llvm/CodeGen/DbgEntityHistoryCalculator.h" 24*0b57cec5SDimitry Andric #include "llvm/CodeGen/DebugHandlerBase.h" 25*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h" 26*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" 27*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h" 28*0b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 29*0b57cec5SDimitry Andric #include "llvm/Support/Allocator.h" 30*0b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 31*0b57cec5SDimitry Andric #include <cstdint> 32*0b57cec5SDimitry Andric #include <map> 33*0b57cec5SDimitry Andric #include <string> 34*0b57cec5SDimitry Andric #include <tuple> 35*0b57cec5SDimitry Andric #include <unordered_map> 36*0b57cec5SDimitry Andric #include <utility> 37*0b57cec5SDimitry Andric #include <vector> 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric namespace llvm { 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andric struct ClassInfo; 42*0b57cec5SDimitry Andric class StringRef; 43*0b57cec5SDimitry Andric class AsmPrinter; 44*0b57cec5SDimitry Andric class Function; 45*0b57cec5SDimitry Andric class GlobalVariable; 46*0b57cec5SDimitry Andric class MCSectionCOFF; 47*0b57cec5SDimitry Andric class MCStreamer; 48*0b57cec5SDimitry Andric class MCSymbol; 49*0b57cec5SDimitry Andric class MachineFunction; 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric /// Collects and handles line tables information in a CodeView format. 52*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { 53*0b57cec5SDimitry Andric MCStreamer &OS; 54*0b57cec5SDimitry Andric BumpPtrAllocator Allocator; 55*0b57cec5SDimitry Andric codeview::GlobalTypeTableBuilder TypeTable; 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric /// Whether to emit type record hashes into .debug$H. 58*0b57cec5SDimitry Andric bool EmitDebugGlobalHashes = false; 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric /// The codeview CPU type used by the translation unit. 61*0b57cec5SDimitry Andric codeview::CPUType TheCPU; 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andric /// Represents the most general definition range. 64*0b57cec5SDimitry Andric struct LocalVarDefRange { 65*0b57cec5SDimitry Andric /// Indicates that variable data is stored in memory relative to the 66*0b57cec5SDimitry Andric /// specified register. 67*0b57cec5SDimitry Andric int InMemory : 1; 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric /// Offset of variable data in memory. 70*0b57cec5SDimitry Andric int DataOffset : 31; 71*0b57cec5SDimitry Andric 72*0b57cec5SDimitry Andric /// Non-zero if this is a piece of an aggregate. 73*0b57cec5SDimitry Andric uint16_t IsSubfield : 1; 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric /// Offset into aggregate. 76*0b57cec5SDimitry Andric uint16_t StructOffset : 15; 77*0b57cec5SDimitry Andric 78*0b57cec5SDimitry Andric /// Register containing the data or the register base of the memory 79*0b57cec5SDimitry Andric /// location containing the data. 80*0b57cec5SDimitry Andric uint16_t CVRegister; 81*0b57cec5SDimitry Andric 82*0b57cec5SDimitry Andric /// Compares all location fields. This includes all fields except the label 83*0b57cec5SDimitry Andric /// ranges. 84*0b57cec5SDimitry Andric bool isDifferentLocation(LocalVarDefRange &O) { 85*0b57cec5SDimitry Andric return InMemory != O.InMemory || DataOffset != O.DataOffset || 86*0b57cec5SDimitry Andric IsSubfield != O.IsSubfield || StructOffset != O.StructOffset || 87*0b57cec5SDimitry Andric CVRegister != O.CVRegister; 88*0b57cec5SDimitry Andric } 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1> Ranges; 91*0b57cec5SDimitry Andric }; 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andric static LocalVarDefRange createDefRangeMem(uint16_t CVRegister, int Offset); 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric /// Similar to DbgVariable in DwarfDebug, but not dwarf-specific. 96*0b57cec5SDimitry Andric struct LocalVariable { 97*0b57cec5SDimitry Andric const DILocalVariable *DIVar = nullptr; 98*0b57cec5SDimitry Andric SmallVector<LocalVarDefRange, 1> DefRanges; 99*0b57cec5SDimitry Andric bool UseReferenceType = false; 100*0b57cec5SDimitry Andric }; 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric struct CVGlobalVariable { 103*0b57cec5SDimitry Andric const DIGlobalVariable *DIGV; 104*0b57cec5SDimitry Andric PointerUnion<const GlobalVariable *, const DIExpression *> GVInfo; 105*0b57cec5SDimitry Andric }; 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric struct InlineSite { 108*0b57cec5SDimitry Andric SmallVector<LocalVariable, 1> InlinedLocals; 109*0b57cec5SDimitry Andric SmallVector<const DILocation *, 1> ChildSites; 110*0b57cec5SDimitry Andric const DISubprogram *Inlinee = nullptr; 111*0b57cec5SDimitry Andric 112*0b57cec5SDimitry Andric /// The ID of the inline site or function used with .cv_loc. Not a type 113*0b57cec5SDimitry Andric /// index. 114*0b57cec5SDimitry Andric unsigned SiteFuncId = 0; 115*0b57cec5SDimitry Andric }; 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andric // Combines information from DILexicalBlock and LexicalScope. 118*0b57cec5SDimitry Andric struct LexicalBlock { 119*0b57cec5SDimitry Andric SmallVector<LocalVariable, 1> Locals; 120*0b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> Globals; 121*0b57cec5SDimitry Andric SmallVector<LexicalBlock *, 1> Children; 122*0b57cec5SDimitry Andric const MCSymbol *Begin; 123*0b57cec5SDimitry Andric const MCSymbol *End; 124*0b57cec5SDimitry Andric StringRef Name; 125*0b57cec5SDimitry Andric }; 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric // For each function, store a vector of labels to its instructions, as well as 128*0b57cec5SDimitry Andric // to the end of the function. 129*0b57cec5SDimitry Andric struct FunctionInfo { 130*0b57cec5SDimitry Andric FunctionInfo() = default; 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric // Uncopyable. 133*0b57cec5SDimitry Andric FunctionInfo(const FunctionInfo &FI) = delete; 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric /// Map from inlined call site to inlined instructions and child inlined 136*0b57cec5SDimitry Andric /// call sites. Listed in program order. 137*0b57cec5SDimitry Andric std::unordered_map<const DILocation *, InlineSite> InlineSites; 138*0b57cec5SDimitry Andric 139*0b57cec5SDimitry Andric /// Ordered list of top-level inlined call sites. 140*0b57cec5SDimitry Andric SmallVector<const DILocation *, 1> ChildSites; 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric SmallVector<LocalVariable, 1> Locals; 143*0b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> Globals; 144*0b57cec5SDimitry Andric 145*0b57cec5SDimitry Andric std::unordered_map<const DILexicalBlockBase*, LexicalBlock> LexicalBlocks; 146*0b57cec5SDimitry Andric 147*0b57cec5SDimitry Andric // Lexical blocks containing local variables. 148*0b57cec5SDimitry Andric SmallVector<LexicalBlock *, 1> ChildBlocks; 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric std::vector<std::pair<MCSymbol *, MDNode *>> Annotations; 151c14a5a88SDimitry Andric std::vector<std::tuple<const MCSymbol *, const MCSymbol *, const DIType *>> 152c14a5a88SDimitry Andric HeapAllocSites; 153*0b57cec5SDimitry Andric 154*0b57cec5SDimitry Andric const MCSymbol *Begin = nullptr; 155*0b57cec5SDimitry Andric const MCSymbol *End = nullptr; 156*0b57cec5SDimitry Andric unsigned FuncId = 0; 157*0b57cec5SDimitry Andric unsigned LastFileId = 0; 158*0b57cec5SDimitry Andric 159*0b57cec5SDimitry Andric /// Number of bytes allocated in the prologue for all local stack objects. 160*0b57cec5SDimitry Andric unsigned FrameSize = 0; 161*0b57cec5SDimitry Andric 162*0b57cec5SDimitry Andric /// Number of bytes of parameters on the stack. 163*0b57cec5SDimitry Andric unsigned ParamSize = 0; 164*0b57cec5SDimitry Andric 165*0b57cec5SDimitry Andric /// Number of bytes pushed to save CSRs. 166*0b57cec5SDimitry Andric unsigned CSRSize = 0; 167*0b57cec5SDimitry Andric 168*0b57cec5SDimitry Andric /// Adjustment to apply on x86 when using the VFRAME frame pointer. 169*0b57cec5SDimitry Andric int OffsetAdjustment = 0; 170*0b57cec5SDimitry Andric 171*0b57cec5SDimitry Andric /// Two-bit value indicating which register is the designated frame pointer 172*0b57cec5SDimitry Andric /// register for local variables. Included in S_FRAMEPROC. 173*0b57cec5SDimitry Andric codeview::EncodedFramePtrReg EncodedLocalFramePtrReg = 174*0b57cec5SDimitry Andric codeview::EncodedFramePtrReg::None; 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric /// Two-bit value indicating which register is the designated frame pointer 177*0b57cec5SDimitry Andric /// register for stack parameters. Included in S_FRAMEPROC. 178*0b57cec5SDimitry Andric codeview::EncodedFramePtrReg EncodedParamFramePtrReg = 179*0b57cec5SDimitry Andric codeview::EncodedFramePtrReg::None; 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric codeview::FrameProcedureOptions FrameProcOpts; 182*0b57cec5SDimitry Andric 183*0b57cec5SDimitry Andric bool HasStackRealignment = false; 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric bool HaveLineInfo = false; 186*0b57cec5SDimitry Andric }; 187*0b57cec5SDimitry Andric FunctionInfo *CurFn = nullptr; 188*0b57cec5SDimitry Andric 189*0b57cec5SDimitry Andric // Map used to seperate variables according to the lexical scope they belong 190*0b57cec5SDimitry Andric // in. This is populated by recordLocalVariable() before 191*0b57cec5SDimitry Andric // collectLexicalBlocks() separates the variables between the FunctionInfo 192*0b57cec5SDimitry Andric // and LexicalBlocks. 193*0b57cec5SDimitry Andric DenseMap<const LexicalScope *, SmallVector<LocalVariable, 1>> ScopeVariables; 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric // Map to separate global variables according to the lexical scope they 196*0b57cec5SDimitry Andric // belong in. A null local scope represents the global scope. 197*0b57cec5SDimitry Andric typedef SmallVector<CVGlobalVariable, 1> GlobalVariableList; 198*0b57cec5SDimitry Andric DenseMap<const DIScope*, std::unique_ptr<GlobalVariableList> > ScopeGlobals; 199*0b57cec5SDimitry Andric 200*0b57cec5SDimitry Andric // Array of global variables which need to be emitted into a COMDAT section. 201*0b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> ComdatVariables; 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric // Array of non-COMDAT global variables. 204*0b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> GlobalVariables; 205*0b57cec5SDimitry Andric 206*0b57cec5SDimitry Andric /// The set of comdat .debug$S sections that we've seen so far. Each section 207*0b57cec5SDimitry Andric /// must start with a magic version number that must only be emitted once. 208*0b57cec5SDimitry Andric /// This set tracks which sections we've already opened. 209*0b57cec5SDimitry Andric DenseSet<MCSectionCOFF *> ComdatDebugSections; 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric /// Switch to the appropriate .debug$S section for GVSym. If GVSym, the symbol 212*0b57cec5SDimitry Andric /// of an emitted global value, is in a comdat COFF section, this will switch 213*0b57cec5SDimitry Andric /// to a new .debug$S section in that comdat. This method ensures that the 214*0b57cec5SDimitry Andric /// section starts with the magic version number on first use. If GVSym is 215*0b57cec5SDimitry Andric /// null, uses the main .debug$S section. 216*0b57cec5SDimitry Andric void switchToDebugSectionForSymbol(const MCSymbol *GVSym); 217*0b57cec5SDimitry Andric 218*0b57cec5SDimitry Andric /// The next available function index for use with our .cv_* directives. Not 219*0b57cec5SDimitry Andric /// to be confused with type indices for LF_FUNC_ID records. 220*0b57cec5SDimitry Andric unsigned NextFuncId = 0; 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric InlineSite &getInlineSite(const DILocation *InlinedAt, 223*0b57cec5SDimitry Andric const DISubprogram *Inlinee); 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andric codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP); 226*0b57cec5SDimitry Andric 227*0b57cec5SDimitry Andric void calculateRanges(LocalVariable &Var, 228*0b57cec5SDimitry Andric const DbgValueHistoryMap::Entries &Entries); 229*0b57cec5SDimitry Andric 230*0b57cec5SDimitry Andric static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children, 231*0b57cec5SDimitry Andric const FunctionInfo &FI, 232*0b57cec5SDimitry Andric const InlineSite &Site); 233*0b57cec5SDimitry Andric 234*0b57cec5SDimitry Andric /// Remember some debug info about each function. Keep it in a stable order to 235*0b57cec5SDimitry Andric /// emit at the end of the TU. 236*0b57cec5SDimitry Andric MapVector<const Function *, std::unique_ptr<FunctionInfo>> FnDebugInfo; 237*0b57cec5SDimitry Andric 238*0b57cec5SDimitry Andric /// Map from full file path to .cv_file id. Full paths are built from DIFiles 239*0b57cec5SDimitry Andric /// and are stored in FileToFilepathMap; 240*0b57cec5SDimitry Andric DenseMap<StringRef, unsigned> FileIdMap; 241*0b57cec5SDimitry Andric 242*0b57cec5SDimitry Andric /// All inlined subprograms in the order they should be emitted. 243*0b57cec5SDimitry Andric SmallSetVector<const DISubprogram *, 4> InlinedSubprograms; 244*0b57cec5SDimitry Andric 245*0b57cec5SDimitry Andric /// Map from a pair of DI metadata nodes and its DI type (or scope) that can 246*0b57cec5SDimitry Andric /// be nullptr, to CodeView type indices. Primarily indexed by 247*0b57cec5SDimitry Andric /// {DIType*, DIType*} and {DISubprogram*, DIType*}. 248*0b57cec5SDimitry Andric /// 249*0b57cec5SDimitry Andric /// The second entry in the key is needed for methods as DISubroutineType 250*0b57cec5SDimitry Andric /// representing static method type are shared with non-method function type. 251*0b57cec5SDimitry Andric DenseMap<std::pair<const DINode *, const DIType *>, codeview::TypeIndex> 252*0b57cec5SDimitry Andric TypeIndices; 253*0b57cec5SDimitry Andric 254*0b57cec5SDimitry Andric /// Map from DICompositeType* to complete type index. Non-record types are 255*0b57cec5SDimitry Andric /// always looked up in the normal TypeIndices map. 256*0b57cec5SDimitry Andric DenseMap<const DICompositeType *, codeview::TypeIndex> CompleteTypeIndices; 257*0b57cec5SDimitry Andric 258*0b57cec5SDimitry Andric /// Complete record types to emit after all active type lowerings are 259*0b57cec5SDimitry Andric /// finished. 260*0b57cec5SDimitry Andric SmallVector<const DICompositeType *, 4> DeferredCompleteTypes; 261*0b57cec5SDimitry Andric 262*0b57cec5SDimitry Andric /// Number of type lowering frames active on the stack. 263*0b57cec5SDimitry Andric unsigned TypeEmissionLevel = 0; 264*0b57cec5SDimitry Andric 265*0b57cec5SDimitry Andric codeview::TypeIndex VBPType; 266*0b57cec5SDimitry Andric 267*0b57cec5SDimitry Andric const DISubprogram *CurrentSubprogram = nullptr; 268*0b57cec5SDimitry Andric 269*0b57cec5SDimitry Andric // The UDTs we have seen while processing types; each entry is a pair of type 270*0b57cec5SDimitry Andric // index and type name. 271*0b57cec5SDimitry Andric std::vector<std::pair<std::string, const DIType *>> LocalUDTs; 272*0b57cec5SDimitry Andric std::vector<std::pair<std::string, const DIType *>> GlobalUDTs; 273*0b57cec5SDimitry Andric 274*0b57cec5SDimitry Andric using FileToFilepathMapTy = std::map<const DIFile *, std::string>; 275*0b57cec5SDimitry Andric FileToFilepathMapTy FileToFilepathMap; 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andric StringRef getFullFilepath(const DIFile *File); 278*0b57cec5SDimitry Andric 279*0b57cec5SDimitry Andric unsigned maybeRecordFile(const DIFile *F); 280*0b57cec5SDimitry Andric 281*0b57cec5SDimitry Andric void maybeRecordLocation(const DebugLoc &DL, const MachineFunction *MF); 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric void clear(); 284*0b57cec5SDimitry Andric 285*0b57cec5SDimitry Andric void setCurrentSubprogram(const DISubprogram *SP) { 286*0b57cec5SDimitry Andric CurrentSubprogram = SP; 287*0b57cec5SDimitry Andric LocalUDTs.clear(); 288*0b57cec5SDimitry Andric } 289*0b57cec5SDimitry Andric 290*0b57cec5SDimitry Andric /// Emit the magic version number at the start of a CodeView type or symbol 291*0b57cec5SDimitry Andric /// section. Appears at the front of every .debug$S or .debug$T or .debug$P 292*0b57cec5SDimitry Andric /// section. 293*0b57cec5SDimitry Andric void emitCodeViewMagicVersion(); 294*0b57cec5SDimitry Andric 295*0b57cec5SDimitry Andric void emitTypeInformation(); 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andric void emitTypeGlobalHashes(); 298*0b57cec5SDimitry Andric 299*0b57cec5SDimitry Andric void emitCompilerInformation(); 300*0b57cec5SDimitry Andric 301*0b57cec5SDimitry Andric void emitBuildInfo(); 302*0b57cec5SDimitry Andric 303*0b57cec5SDimitry Andric void emitInlineeLinesSubsection(); 304*0b57cec5SDimitry Andric 305*0b57cec5SDimitry Andric void emitDebugInfoForThunk(const Function *GV, 306*0b57cec5SDimitry Andric FunctionInfo &FI, 307*0b57cec5SDimitry Andric const MCSymbol *Fn); 308*0b57cec5SDimitry Andric 309*0b57cec5SDimitry Andric void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI); 310*0b57cec5SDimitry Andric 311*0b57cec5SDimitry Andric void emitDebugInfoForRetainedTypes(); 312*0b57cec5SDimitry Andric 3135ffd83dbSDimitry Andric void emitDebugInfoForUDTs( 3145ffd83dbSDimitry Andric const std::vector<std::pair<std::string, const DIType *>> &UDTs); 315*0b57cec5SDimitry Andric 316*0b57cec5SDimitry Andric void emitDebugInfoForGlobals(); 317*0b57cec5SDimitry Andric void emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals); 318*0b57cec5SDimitry Andric void emitDebugInfoForGlobal(const CVGlobalVariable &CVGV); 319*0b57cec5SDimitry Andric 320*0b57cec5SDimitry Andric /// Opens a subsection of the given kind in a .debug$S codeview section. 321*0b57cec5SDimitry Andric /// Returns an end label for use with endCVSubsection when the subsection is 322*0b57cec5SDimitry Andric /// finished. 323*0b57cec5SDimitry Andric MCSymbol *beginCVSubsection(codeview::DebugSubsectionKind Kind); 324*0b57cec5SDimitry Andric void endCVSubsection(MCSymbol *EndLabel); 325*0b57cec5SDimitry Andric 326*0b57cec5SDimitry Andric /// Opens a symbol record of the given kind. Returns an end label for use with 327*0b57cec5SDimitry Andric /// endSymbolRecord. 328*0b57cec5SDimitry Andric MCSymbol *beginSymbolRecord(codeview::SymbolKind Kind); 329*0b57cec5SDimitry Andric void endSymbolRecord(MCSymbol *SymEnd); 330*0b57cec5SDimitry Andric 331*0b57cec5SDimitry Andric /// Emits an S_END, S_INLINESITE_END, or S_PROC_ID_END record. These records 332*0b57cec5SDimitry Andric /// are empty, so we emit them with a simpler assembly sequence that doesn't 333*0b57cec5SDimitry Andric /// involve labels. 334*0b57cec5SDimitry Andric void emitEndSymbolRecord(codeview::SymbolKind EndKind); 335*0b57cec5SDimitry Andric 336*0b57cec5SDimitry Andric void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt, 337*0b57cec5SDimitry Andric const InlineSite &Site); 338*0b57cec5SDimitry Andric 339*0b57cec5SDimitry Andric using InlinedEntity = DbgValueHistoryMap::InlinedEntity; 340*0b57cec5SDimitry Andric 341*0b57cec5SDimitry Andric void collectGlobalVariableInfo(); 342*0b57cec5SDimitry Andric void collectVariableInfo(const DISubprogram *SP); 343*0b57cec5SDimitry Andric 344*0b57cec5SDimitry Andric void collectVariableInfoFromMFTable(DenseSet<InlinedEntity> &Processed); 345*0b57cec5SDimitry Andric 346*0b57cec5SDimitry Andric // Construct the lexical block tree for a routine, pruning emptpy lexical 347*0b57cec5SDimitry Andric // scopes, and populate it with local variables. 348*0b57cec5SDimitry Andric void collectLexicalBlockInfo(SmallVectorImpl<LexicalScope *> &Scopes, 349*0b57cec5SDimitry Andric SmallVectorImpl<LexicalBlock *> &Blocks, 350*0b57cec5SDimitry Andric SmallVectorImpl<LocalVariable> &Locals, 351*0b57cec5SDimitry Andric SmallVectorImpl<CVGlobalVariable> &Globals); 352*0b57cec5SDimitry Andric void collectLexicalBlockInfo(LexicalScope &Scope, 353*0b57cec5SDimitry Andric SmallVectorImpl<LexicalBlock *> &ParentBlocks, 354*0b57cec5SDimitry Andric SmallVectorImpl<LocalVariable> &ParentLocals, 355*0b57cec5SDimitry Andric SmallVectorImpl<CVGlobalVariable> &ParentGlobals); 356*0b57cec5SDimitry Andric 357*0b57cec5SDimitry Andric /// Records information about a local variable in the appropriate scope. In 358*0b57cec5SDimitry Andric /// particular, locals from inlined code live inside the inlining site. 359*0b57cec5SDimitry Andric void recordLocalVariable(LocalVariable &&Var, const LexicalScope *LS); 360*0b57cec5SDimitry Andric 361*0b57cec5SDimitry Andric /// Emits local variables in the appropriate order. 362*0b57cec5SDimitry Andric void emitLocalVariableList(const FunctionInfo &FI, 363*0b57cec5SDimitry Andric ArrayRef<LocalVariable> Locals); 364*0b57cec5SDimitry Andric 365*0b57cec5SDimitry Andric /// Emits an S_LOCAL record and its associated defined ranges. 366*0b57cec5SDimitry Andric void emitLocalVariable(const FunctionInfo &FI, const LocalVariable &Var); 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric /// Emits a sequence of lexical block scopes and their children. 369*0b57cec5SDimitry Andric void emitLexicalBlockList(ArrayRef<LexicalBlock *> Blocks, 370*0b57cec5SDimitry Andric const FunctionInfo& FI); 371*0b57cec5SDimitry Andric 372*0b57cec5SDimitry Andric /// Emit a lexical block scope and its children. 373*0b57cec5SDimitry Andric void emitLexicalBlock(const LexicalBlock &Block, const FunctionInfo& FI); 374*0b57cec5SDimitry Andric 375*0b57cec5SDimitry Andric /// Translates the DIType to codeview if necessary and returns a type index 376*0b57cec5SDimitry Andric /// for it. 377*0b57cec5SDimitry Andric codeview::TypeIndex getTypeIndex(const DIType *Ty, 378*0b57cec5SDimitry Andric const DIType *ClassTy = nullptr); 379*0b57cec5SDimitry Andric 380*0b57cec5SDimitry Andric codeview::TypeIndex 381*0b57cec5SDimitry Andric getTypeIndexForThisPtr(const DIDerivedType *PtrTy, 382*0b57cec5SDimitry Andric const DISubroutineType *SubroutineTy); 383*0b57cec5SDimitry Andric 384*0b57cec5SDimitry Andric codeview::TypeIndex getTypeIndexForReferenceTo(const DIType *Ty); 385*0b57cec5SDimitry Andric 386*0b57cec5SDimitry Andric codeview::TypeIndex getMemberFunctionType(const DISubprogram *SP, 387*0b57cec5SDimitry Andric const DICompositeType *Class); 388*0b57cec5SDimitry Andric 389*0b57cec5SDimitry Andric codeview::TypeIndex getScopeIndex(const DIScope *Scope); 390*0b57cec5SDimitry Andric 391*0b57cec5SDimitry Andric codeview::TypeIndex getVBPTypeIndex(); 392*0b57cec5SDimitry Andric 393*0b57cec5SDimitry Andric void addToUDTs(const DIType *Ty); 394*0b57cec5SDimitry Andric 395*0b57cec5SDimitry Andric void addUDTSrcLine(const DIType *Ty, codeview::TypeIndex TI); 396*0b57cec5SDimitry Andric 397*0b57cec5SDimitry Andric codeview::TypeIndex lowerType(const DIType *Ty, const DIType *ClassTy); 398*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeAlias(const DIDerivedType *Ty); 399*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeArray(const DICompositeType *Ty); 400*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeBasic(const DIBasicType *Ty); 401*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypePointer( 402*0b57cec5SDimitry Andric const DIDerivedType *Ty, 403*0b57cec5SDimitry Andric codeview::PointerOptions PO = codeview::PointerOptions::None); 404*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeMemberPointer( 405*0b57cec5SDimitry Andric const DIDerivedType *Ty, 406*0b57cec5SDimitry Andric codeview::PointerOptions PO = codeview::PointerOptions::None); 407*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty); 408*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeFunction(const DISubroutineType *Ty); 409*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeVFTableShape(const DIDerivedType *Ty); 410*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeMemberFunction( 411*0b57cec5SDimitry Andric const DISubroutineType *Ty, const DIType *ClassTy, int ThisAdjustment, 412*0b57cec5SDimitry Andric bool IsStaticMethod, 413*0b57cec5SDimitry Andric codeview::FunctionOptions FO = codeview::FunctionOptions::None); 414*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeEnum(const DICompositeType *Ty); 415*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeClass(const DICompositeType *Ty); 416*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeUnion(const DICompositeType *Ty); 417*0b57cec5SDimitry Andric 418*0b57cec5SDimitry Andric /// Symbol records should point to complete types, but type records should 419*0b57cec5SDimitry Andric /// always point to incomplete types to avoid cycles in the type graph. Only 420*0b57cec5SDimitry Andric /// use this entry point when generating symbol records. The complete and 421*0b57cec5SDimitry Andric /// incomplete type indices only differ for record types. All other types use 422*0b57cec5SDimitry Andric /// the same index. 423*0b57cec5SDimitry Andric codeview::TypeIndex getCompleteTypeIndex(const DIType *Ty); 424*0b57cec5SDimitry Andric 425*0b57cec5SDimitry Andric codeview::TypeIndex lowerCompleteTypeClass(const DICompositeType *Ty); 426*0b57cec5SDimitry Andric codeview::TypeIndex lowerCompleteTypeUnion(const DICompositeType *Ty); 427*0b57cec5SDimitry Andric 428*0b57cec5SDimitry Andric struct TypeLoweringScope; 429*0b57cec5SDimitry Andric 430*0b57cec5SDimitry Andric void emitDeferredCompleteTypes(); 431*0b57cec5SDimitry Andric 432*0b57cec5SDimitry Andric void collectMemberInfo(ClassInfo &Info, const DIDerivedType *DDTy); 433*0b57cec5SDimitry Andric ClassInfo collectClassInfo(const DICompositeType *Ty); 434*0b57cec5SDimitry Andric 435*0b57cec5SDimitry Andric /// Common record member lowering functionality for record types, which are 436*0b57cec5SDimitry Andric /// structs, classes, and unions. Returns the field list index and the member 437*0b57cec5SDimitry Andric /// count. 438*0b57cec5SDimitry Andric std::tuple<codeview::TypeIndex, codeview::TypeIndex, unsigned, bool> 439*0b57cec5SDimitry Andric lowerRecordFieldList(const DICompositeType *Ty); 440*0b57cec5SDimitry Andric 441*0b57cec5SDimitry Andric /// Inserts {{Node, ClassTy}, TI} into TypeIndices and checks for duplicates. 442*0b57cec5SDimitry Andric codeview::TypeIndex recordTypeIndexForDINode(const DINode *Node, 443*0b57cec5SDimitry Andric codeview::TypeIndex TI, 444*0b57cec5SDimitry Andric const DIType *ClassTy = nullptr); 445*0b57cec5SDimitry Andric 4465ffd83dbSDimitry Andric /// Collect the names of parent scopes, innermost to outermost. Return the 4475ffd83dbSDimitry Andric /// innermost subprogram scope if present. Ensure that parent type scopes are 4485ffd83dbSDimitry Andric /// inserted into the type table. 4495ffd83dbSDimitry Andric const DISubprogram * 4505ffd83dbSDimitry Andric collectParentScopeNames(const DIScope *Scope, 4515ffd83dbSDimitry Andric SmallVectorImpl<StringRef> &ParentScopeNames); 4525ffd83dbSDimitry Andric std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name); 4535ffd83dbSDimitry Andric std::string getFullyQualifiedName(const DIScope *Scope); 4545ffd83dbSDimitry Andric 455*0b57cec5SDimitry Andric unsigned getPointerSizeInBytes(); 456*0b57cec5SDimitry Andric 457*0b57cec5SDimitry Andric protected: 458*0b57cec5SDimitry Andric /// Gather pre-function debug information. 459*0b57cec5SDimitry Andric void beginFunctionImpl(const MachineFunction *MF) override; 460*0b57cec5SDimitry Andric 461*0b57cec5SDimitry Andric /// Gather post-function debug information. 462*0b57cec5SDimitry Andric void endFunctionImpl(const MachineFunction *) override; 463*0b57cec5SDimitry Andric 464*0b57cec5SDimitry Andric public: 465*0b57cec5SDimitry Andric CodeViewDebug(AsmPrinter *AP); 466*0b57cec5SDimitry Andric 467*0b57cec5SDimitry Andric void setSymbolSize(const MCSymbol *, uint64_t) override {} 468*0b57cec5SDimitry Andric 469*0b57cec5SDimitry Andric /// Emit the COFF section that holds the line table information. 470*0b57cec5SDimitry Andric void endModule() override; 471*0b57cec5SDimitry Andric 472*0b57cec5SDimitry Andric /// Process beginning of an instruction. 473*0b57cec5SDimitry Andric void beginInstruction(const MachineInstr *MI) override; 474*0b57cec5SDimitry Andric }; 475*0b57cec5SDimitry Andric 476*0b57cec5SDimitry Andric } // end namespace llvm 477*0b57cec5SDimitry Andric 478*0b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H 479