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; 151*0b57cec5SDimitry Andric std::vector<std::tuple<MCSymbol *, MCSymbol *, DIType *>> HeapAllocSites; 152*0b57cec5SDimitry Andric 153*0b57cec5SDimitry Andric const MCSymbol *Begin = nullptr; 154*0b57cec5SDimitry Andric const MCSymbol *End = nullptr; 155*0b57cec5SDimitry Andric unsigned FuncId = 0; 156*0b57cec5SDimitry Andric unsigned LastFileId = 0; 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric /// Number of bytes allocated in the prologue for all local stack objects. 159*0b57cec5SDimitry Andric unsigned FrameSize = 0; 160*0b57cec5SDimitry Andric 161*0b57cec5SDimitry Andric /// Number of bytes of parameters on the stack. 162*0b57cec5SDimitry Andric unsigned ParamSize = 0; 163*0b57cec5SDimitry Andric 164*0b57cec5SDimitry Andric /// Number of bytes pushed to save CSRs. 165*0b57cec5SDimitry Andric unsigned CSRSize = 0; 166*0b57cec5SDimitry Andric 167*0b57cec5SDimitry Andric /// Adjustment to apply on x86 when using the VFRAME frame pointer. 168*0b57cec5SDimitry Andric int OffsetAdjustment = 0; 169*0b57cec5SDimitry Andric 170*0b57cec5SDimitry Andric /// Two-bit value indicating which register is the designated frame pointer 171*0b57cec5SDimitry Andric /// register for local variables. Included in S_FRAMEPROC. 172*0b57cec5SDimitry Andric codeview::EncodedFramePtrReg EncodedLocalFramePtrReg = 173*0b57cec5SDimitry Andric codeview::EncodedFramePtrReg::None; 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric /// Two-bit value indicating which register is the designated frame pointer 176*0b57cec5SDimitry Andric /// register for stack parameters. Included in S_FRAMEPROC. 177*0b57cec5SDimitry Andric codeview::EncodedFramePtrReg EncodedParamFramePtrReg = 178*0b57cec5SDimitry Andric codeview::EncodedFramePtrReg::None; 179*0b57cec5SDimitry Andric 180*0b57cec5SDimitry Andric codeview::FrameProcedureOptions FrameProcOpts; 181*0b57cec5SDimitry Andric 182*0b57cec5SDimitry Andric bool HasStackRealignment = false; 183*0b57cec5SDimitry Andric 184*0b57cec5SDimitry Andric bool HaveLineInfo = false; 185*0b57cec5SDimitry Andric }; 186*0b57cec5SDimitry Andric FunctionInfo *CurFn = nullptr; 187*0b57cec5SDimitry Andric 188*0b57cec5SDimitry Andric // Map used to seperate variables according to the lexical scope they belong 189*0b57cec5SDimitry Andric // in. This is populated by recordLocalVariable() before 190*0b57cec5SDimitry Andric // collectLexicalBlocks() separates the variables between the FunctionInfo 191*0b57cec5SDimitry Andric // and LexicalBlocks. 192*0b57cec5SDimitry Andric DenseMap<const LexicalScope *, SmallVector<LocalVariable, 1>> ScopeVariables; 193*0b57cec5SDimitry Andric 194*0b57cec5SDimitry Andric // Map to separate global variables according to the lexical scope they 195*0b57cec5SDimitry Andric // belong in. A null local scope represents the global scope. 196*0b57cec5SDimitry Andric typedef SmallVector<CVGlobalVariable, 1> GlobalVariableList; 197*0b57cec5SDimitry Andric DenseMap<const DIScope*, std::unique_ptr<GlobalVariableList> > ScopeGlobals; 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric // Array of global variables which need to be emitted into a COMDAT section. 200*0b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> ComdatVariables; 201*0b57cec5SDimitry Andric 202*0b57cec5SDimitry Andric // Array of non-COMDAT global variables. 203*0b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> GlobalVariables; 204*0b57cec5SDimitry Andric 205*0b57cec5SDimitry Andric /// The set of comdat .debug$S sections that we've seen so far. Each section 206*0b57cec5SDimitry Andric /// must start with a magic version number that must only be emitted once. 207*0b57cec5SDimitry Andric /// This set tracks which sections we've already opened. 208*0b57cec5SDimitry Andric DenseSet<MCSectionCOFF *> ComdatDebugSections; 209*0b57cec5SDimitry Andric 210*0b57cec5SDimitry Andric /// Switch to the appropriate .debug$S section for GVSym. If GVSym, the symbol 211*0b57cec5SDimitry Andric /// of an emitted global value, is in a comdat COFF section, this will switch 212*0b57cec5SDimitry Andric /// to a new .debug$S section in that comdat. This method ensures that the 213*0b57cec5SDimitry Andric /// section starts with the magic version number on first use. If GVSym is 214*0b57cec5SDimitry Andric /// null, uses the main .debug$S section. 215*0b57cec5SDimitry Andric void switchToDebugSectionForSymbol(const MCSymbol *GVSym); 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric /// The next available function index for use with our .cv_* directives. Not 218*0b57cec5SDimitry Andric /// to be confused with type indices for LF_FUNC_ID records. 219*0b57cec5SDimitry Andric unsigned NextFuncId = 0; 220*0b57cec5SDimitry Andric 221*0b57cec5SDimitry Andric InlineSite &getInlineSite(const DILocation *InlinedAt, 222*0b57cec5SDimitry Andric const DISubprogram *Inlinee); 223*0b57cec5SDimitry Andric 224*0b57cec5SDimitry Andric codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP); 225*0b57cec5SDimitry Andric 226*0b57cec5SDimitry Andric void calculateRanges(LocalVariable &Var, 227*0b57cec5SDimitry Andric const DbgValueHistoryMap::Entries &Entries); 228*0b57cec5SDimitry Andric 229*0b57cec5SDimitry Andric static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children, 230*0b57cec5SDimitry Andric const FunctionInfo &FI, 231*0b57cec5SDimitry Andric const InlineSite &Site); 232*0b57cec5SDimitry Andric 233*0b57cec5SDimitry Andric /// Remember some debug info about each function. Keep it in a stable order to 234*0b57cec5SDimitry Andric /// emit at the end of the TU. 235*0b57cec5SDimitry Andric MapVector<const Function *, std::unique_ptr<FunctionInfo>> FnDebugInfo; 236*0b57cec5SDimitry Andric 237*0b57cec5SDimitry Andric /// Map from full file path to .cv_file id. Full paths are built from DIFiles 238*0b57cec5SDimitry Andric /// and are stored in FileToFilepathMap; 239*0b57cec5SDimitry Andric DenseMap<StringRef, unsigned> FileIdMap; 240*0b57cec5SDimitry Andric 241*0b57cec5SDimitry Andric /// All inlined subprograms in the order they should be emitted. 242*0b57cec5SDimitry Andric SmallSetVector<const DISubprogram *, 4> InlinedSubprograms; 243*0b57cec5SDimitry Andric 244*0b57cec5SDimitry Andric /// Map from a pair of DI metadata nodes and its DI type (or scope) that can 245*0b57cec5SDimitry Andric /// be nullptr, to CodeView type indices. Primarily indexed by 246*0b57cec5SDimitry Andric /// {DIType*, DIType*} and {DISubprogram*, DIType*}. 247*0b57cec5SDimitry Andric /// 248*0b57cec5SDimitry Andric /// The second entry in the key is needed for methods as DISubroutineType 249*0b57cec5SDimitry Andric /// representing static method type are shared with non-method function type. 250*0b57cec5SDimitry Andric DenseMap<std::pair<const DINode *, const DIType *>, codeview::TypeIndex> 251*0b57cec5SDimitry Andric TypeIndices; 252*0b57cec5SDimitry Andric 253*0b57cec5SDimitry Andric /// Map from DICompositeType* to complete type index. Non-record types are 254*0b57cec5SDimitry Andric /// always looked up in the normal TypeIndices map. 255*0b57cec5SDimitry Andric DenseMap<const DICompositeType *, codeview::TypeIndex> CompleteTypeIndices; 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andric /// Complete record types to emit after all active type lowerings are 258*0b57cec5SDimitry Andric /// finished. 259*0b57cec5SDimitry Andric SmallVector<const DICompositeType *, 4> DeferredCompleteTypes; 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric /// Number of type lowering frames active on the stack. 262*0b57cec5SDimitry Andric unsigned TypeEmissionLevel = 0; 263*0b57cec5SDimitry Andric 264*0b57cec5SDimitry Andric codeview::TypeIndex VBPType; 265*0b57cec5SDimitry Andric 266*0b57cec5SDimitry Andric const DISubprogram *CurrentSubprogram = nullptr; 267*0b57cec5SDimitry Andric 268*0b57cec5SDimitry Andric // The UDTs we have seen while processing types; each entry is a pair of type 269*0b57cec5SDimitry Andric // index and type name. 270*0b57cec5SDimitry Andric std::vector<std::pair<std::string, const DIType *>> LocalUDTs; 271*0b57cec5SDimitry Andric std::vector<std::pair<std::string, const DIType *>> GlobalUDTs; 272*0b57cec5SDimitry Andric 273*0b57cec5SDimitry Andric using FileToFilepathMapTy = std::map<const DIFile *, std::string>; 274*0b57cec5SDimitry Andric FileToFilepathMapTy FileToFilepathMap; 275*0b57cec5SDimitry Andric 276*0b57cec5SDimitry Andric StringRef getFullFilepath(const DIFile *File); 277*0b57cec5SDimitry Andric 278*0b57cec5SDimitry Andric unsigned maybeRecordFile(const DIFile *F); 279*0b57cec5SDimitry Andric 280*0b57cec5SDimitry Andric void maybeRecordLocation(const DebugLoc &DL, const MachineFunction *MF); 281*0b57cec5SDimitry Andric 282*0b57cec5SDimitry Andric void clear(); 283*0b57cec5SDimitry Andric 284*0b57cec5SDimitry Andric void setCurrentSubprogram(const DISubprogram *SP) { 285*0b57cec5SDimitry Andric CurrentSubprogram = SP; 286*0b57cec5SDimitry Andric LocalUDTs.clear(); 287*0b57cec5SDimitry Andric } 288*0b57cec5SDimitry Andric 289*0b57cec5SDimitry Andric /// Emit the magic version number at the start of a CodeView type or symbol 290*0b57cec5SDimitry Andric /// section. Appears at the front of every .debug$S or .debug$T or .debug$P 291*0b57cec5SDimitry Andric /// section. 292*0b57cec5SDimitry Andric void emitCodeViewMagicVersion(); 293*0b57cec5SDimitry Andric 294*0b57cec5SDimitry Andric void emitTypeInformation(); 295*0b57cec5SDimitry Andric 296*0b57cec5SDimitry Andric void emitTypeGlobalHashes(); 297*0b57cec5SDimitry Andric 298*0b57cec5SDimitry Andric void emitCompilerInformation(); 299*0b57cec5SDimitry Andric 300*0b57cec5SDimitry Andric void emitBuildInfo(); 301*0b57cec5SDimitry Andric 302*0b57cec5SDimitry Andric void emitInlineeLinesSubsection(); 303*0b57cec5SDimitry Andric 304*0b57cec5SDimitry Andric void emitDebugInfoForThunk(const Function *GV, 305*0b57cec5SDimitry Andric FunctionInfo &FI, 306*0b57cec5SDimitry Andric const MCSymbol *Fn); 307*0b57cec5SDimitry Andric 308*0b57cec5SDimitry Andric void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI); 309*0b57cec5SDimitry Andric 310*0b57cec5SDimitry Andric void emitDebugInfoForRetainedTypes(); 311*0b57cec5SDimitry Andric 312*0b57cec5SDimitry Andric void 313*0b57cec5SDimitry Andric emitDebugInfoForUDTs(ArrayRef<std::pair<std::string, const DIType *>> UDTs); 314*0b57cec5SDimitry Andric 315*0b57cec5SDimitry Andric void emitDebugInfoForGlobals(); 316*0b57cec5SDimitry Andric void emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals); 317*0b57cec5SDimitry Andric void emitDebugInfoForGlobal(const CVGlobalVariable &CVGV); 318*0b57cec5SDimitry Andric 319*0b57cec5SDimitry Andric /// Opens a subsection of the given kind in a .debug$S codeview section. 320*0b57cec5SDimitry Andric /// Returns an end label for use with endCVSubsection when the subsection is 321*0b57cec5SDimitry Andric /// finished. 322*0b57cec5SDimitry Andric MCSymbol *beginCVSubsection(codeview::DebugSubsectionKind Kind); 323*0b57cec5SDimitry Andric void endCVSubsection(MCSymbol *EndLabel); 324*0b57cec5SDimitry Andric 325*0b57cec5SDimitry Andric /// Opens a symbol record of the given kind. Returns an end label for use with 326*0b57cec5SDimitry Andric /// endSymbolRecord. 327*0b57cec5SDimitry Andric MCSymbol *beginSymbolRecord(codeview::SymbolKind Kind); 328*0b57cec5SDimitry Andric void endSymbolRecord(MCSymbol *SymEnd); 329*0b57cec5SDimitry Andric 330*0b57cec5SDimitry Andric /// Emits an S_END, S_INLINESITE_END, or S_PROC_ID_END record. These records 331*0b57cec5SDimitry Andric /// are empty, so we emit them with a simpler assembly sequence that doesn't 332*0b57cec5SDimitry Andric /// involve labels. 333*0b57cec5SDimitry Andric void emitEndSymbolRecord(codeview::SymbolKind EndKind); 334*0b57cec5SDimitry Andric 335*0b57cec5SDimitry Andric void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt, 336*0b57cec5SDimitry Andric const InlineSite &Site); 337*0b57cec5SDimitry Andric 338*0b57cec5SDimitry Andric using InlinedEntity = DbgValueHistoryMap::InlinedEntity; 339*0b57cec5SDimitry Andric 340*0b57cec5SDimitry Andric void collectGlobalVariableInfo(); 341*0b57cec5SDimitry Andric void collectVariableInfo(const DISubprogram *SP); 342*0b57cec5SDimitry Andric 343*0b57cec5SDimitry Andric void collectVariableInfoFromMFTable(DenseSet<InlinedEntity> &Processed); 344*0b57cec5SDimitry Andric 345*0b57cec5SDimitry Andric // Construct the lexical block tree for a routine, pruning emptpy lexical 346*0b57cec5SDimitry Andric // scopes, and populate it with local variables. 347*0b57cec5SDimitry Andric void collectLexicalBlockInfo(SmallVectorImpl<LexicalScope *> &Scopes, 348*0b57cec5SDimitry Andric SmallVectorImpl<LexicalBlock *> &Blocks, 349*0b57cec5SDimitry Andric SmallVectorImpl<LocalVariable> &Locals, 350*0b57cec5SDimitry Andric SmallVectorImpl<CVGlobalVariable> &Globals); 351*0b57cec5SDimitry Andric void collectLexicalBlockInfo(LexicalScope &Scope, 352*0b57cec5SDimitry Andric SmallVectorImpl<LexicalBlock *> &ParentBlocks, 353*0b57cec5SDimitry Andric SmallVectorImpl<LocalVariable> &ParentLocals, 354*0b57cec5SDimitry Andric SmallVectorImpl<CVGlobalVariable> &ParentGlobals); 355*0b57cec5SDimitry Andric 356*0b57cec5SDimitry Andric /// Records information about a local variable in the appropriate scope. In 357*0b57cec5SDimitry Andric /// particular, locals from inlined code live inside the inlining site. 358*0b57cec5SDimitry Andric void recordLocalVariable(LocalVariable &&Var, const LexicalScope *LS); 359*0b57cec5SDimitry Andric 360*0b57cec5SDimitry Andric /// Emits local variables in the appropriate order. 361*0b57cec5SDimitry Andric void emitLocalVariableList(const FunctionInfo &FI, 362*0b57cec5SDimitry Andric ArrayRef<LocalVariable> Locals); 363*0b57cec5SDimitry Andric 364*0b57cec5SDimitry Andric /// Emits an S_LOCAL record and its associated defined ranges. 365*0b57cec5SDimitry Andric void emitLocalVariable(const FunctionInfo &FI, const LocalVariable &Var); 366*0b57cec5SDimitry Andric 367*0b57cec5SDimitry Andric /// Emits a sequence of lexical block scopes and their children. 368*0b57cec5SDimitry Andric void emitLexicalBlockList(ArrayRef<LexicalBlock *> Blocks, 369*0b57cec5SDimitry Andric const FunctionInfo& FI); 370*0b57cec5SDimitry Andric 371*0b57cec5SDimitry Andric /// Emit a lexical block scope and its children. 372*0b57cec5SDimitry Andric void emitLexicalBlock(const LexicalBlock &Block, const FunctionInfo& FI); 373*0b57cec5SDimitry Andric 374*0b57cec5SDimitry Andric /// Translates the DIType to codeview if necessary and returns a type index 375*0b57cec5SDimitry Andric /// for it. 376*0b57cec5SDimitry Andric codeview::TypeIndex getTypeIndex(const DIType *Ty, 377*0b57cec5SDimitry Andric const DIType *ClassTy = nullptr); 378*0b57cec5SDimitry Andric 379*0b57cec5SDimitry Andric codeview::TypeIndex 380*0b57cec5SDimitry Andric getTypeIndexForThisPtr(const DIDerivedType *PtrTy, 381*0b57cec5SDimitry Andric const DISubroutineType *SubroutineTy); 382*0b57cec5SDimitry Andric 383*0b57cec5SDimitry Andric codeview::TypeIndex getTypeIndexForReferenceTo(const DIType *Ty); 384*0b57cec5SDimitry Andric 385*0b57cec5SDimitry Andric codeview::TypeIndex getMemberFunctionType(const DISubprogram *SP, 386*0b57cec5SDimitry Andric const DICompositeType *Class); 387*0b57cec5SDimitry Andric 388*0b57cec5SDimitry Andric codeview::TypeIndex getScopeIndex(const DIScope *Scope); 389*0b57cec5SDimitry Andric 390*0b57cec5SDimitry Andric codeview::TypeIndex getVBPTypeIndex(); 391*0b57cec5SDimitry Andric 392*0b57cec5SDimitry Andric void addToUDTs(const DIType *Ty); 393*0b57cec5SDimitry Andric 394*0b57cec5SDimitry Andric void addUDTSrcLine(const DIType *Ty, codeview::TypeIndex TI); 395*0b57cec5SDimitry Andric 396*0b57cec5SDimitry Andric codeview::TypeIndex lowerType(const DIType *Ty, const DIType *ClassTy); 397*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeAlias(const DIDerivedType *Ty); 398*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeArray(const DICompositeType *Ty); 399*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeBasic(const DIBasicType *Ty); 400*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypePointer( 401*0b57cec5SDimitry Andric const DIDerivedType *Ty, 402*0b57cec5SDimitry Andric codeview::PointerOptions PO = codeview::PointerOptions::None); 403*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeMemberPointer( 404*0b57cec5SDimitry Andric const DIDerivedType *Ty, 405*0b57cec5SDimitry Andric codeview::PointerOptions PO = codeview::PointerOptions::None); 406*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty); 407*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeFunction(const DISubroutineType *Ty); 408*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeVFTableShape(const DIDerivedType *Ty); 409*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeMemberFunction( 410*0b57cec5SDimitry Andric const DISubroutineType *Ty, const DIType *ClassTy, int ThisAdjustment, 411*0b57cec5SDimitry Andric bool IsStaticMethod, 412*0b57cec5SDimitry Andric codeview::FunctionOptions FO = codeview::FunctionOptions::None); 413*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeEnum(const DICompositeType *Ty); 414*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeClass(const DICompositeType *Ty); 415*0b57cec5SDimitry Andric codeview::TypeIndex lowerTypeUnion(const DICompositeType *Ty); 416*0b57cec5SDimitry Andric 417*0b57cec5SDimitry Andric /// Symbol records should point to complete types, but type records should 418*0b57cec5SDimitry Andric /// always point to incomplete types to avoid cycles in the type graph. Only 419*0b57cec5SDimitry Andric /// use this entry point when generating symbol records. The complete and 420*0b57cec5SDimitry Andric /// incomplete type indices only differ for record types. All other types use 421*0b57cec5SDimitry Andric /// the same index. 422*0b57cec5SDimitry Andric codeview::TypeIndex getCompleteTypeIndex(const DIType *Ty); 423*0b57cec5SDimitry Andric 424*0b57cec5SDimitry Andric codeview::TypeIndex lowerCompleteTypeClass(const DICompositeType *Ty); 425*0b57cec5SDimitry Andric codeview::TypeIndex lowerCompleteTypeUnion(const DICompositeType *Ty); 426*0b57cec5SDimitry Andric 427*0b57cec5SDimitry Andric struct TypeLoweringScope; 428*0b57cec5SDimitry Andric 429*0b57cec5SDimitry Andric void emitDeferredCompleteTypes(); 430*0b57cec5SDimitry Andric 431*0b57cec5SDimitry Andric void collectMemberInfo(ClassInfo &Info, const DIDerivedType *DDTy); 432*0b57cec5SDimitry Andric ClassInfo collectClassInfo(const DICompositeType *Ty); 433*0b57cec5SDimitry Andric 434*0b57cec5SDimitry Andric /// Common record member lowering functionality for record types, which are 435*0b57cec5SDimitry Andric /// structs, classes, and unions. Returns the field list index and the member 436*0b57cec5SDimitry Andric /// count. 437*0b57cec5SDimitry Andric std::tuple<codeview::TypeIndex, codeview::TypeIndex, unsigned, bool> 438*0b57cec5SDimitry Andric lowerRecordFieldList(const DICompositeType *Ty); 439*0b57cec5SDimitry Andric 440*0b57cec5SDimitry Andric /// Inserts {{Node, ClassTy}, TI} into TypeIndices and checks for duplicates. 441*0b57cec5SDimitry Andric codeview::TypeIndex recordTypeIndexForDINode(const DINode *Node, 442*0b57cec5SDimitry Andric codeview::TypeIndex TI, 443*0b57cec5SDimitry Andric const DIType *ClassTy = nullptr); 444*0b57cec5SDimitry Andric 445*0b57cec5SDimitry Andric unsigned getPointerSizeInBytes(); 446*0b57cec5SDimitry Andric 447*0b57cec5SDimitry Andric protected: 448*0b57cec5SDimitry Andric /// Gather pre-function debug information. 449*0b57cec5SDimitry Andric void beginFunctionImpl(const MachineFunction *MF) override; 450*0b57cec5SDimitry Andric 451*0b57cec5SDimitry Andric /// Gather post-function debug information. 452*0b57cec5SDimitry Andric void endFunctionImpl(const MachineFunction *) override; 453*0b57cec5SDimitry Andric 454*0b57cec5SDimitry Andric public: 455*0b57cec5SDimitry Andric CodeViewDebug(AsmPrinter *AP); 456*0b57cec5SDimitry Andric 457*0b57cec5SDimitry Andric void setSymbolSize(const MCSymbol *, uint64_t) override {} 458*0b57cec5SDimitry Andric 459*0b57cec5SDimitry Andric /// Emit the COFF section that holds the line table information. 460*0b57cec5SDimitry Andric void endModule() override; 461*0b57cec5SDimitry Andric 462*0b57cec5SDimitry Andric /// Process beginning of an instruction. 463*0b57cec5SDimitry Andric void beginInstruction(const MachineInstr *MI) override; 464*0b57cec5SDimitry Andric }; 465*0b57cec5SDimitry Andric 466*0b57cec5SDimitry Andric } // end namespace llvm 467*0b57cec5SDimitry Andric 468*0b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H 469