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 { 530b57cec5SDimitry Andric MCStreamer &OS; 540b57cec5SDimitry Andric BumpPtrAllocator Allocator; 550b57cec5SDimitry Andric codeview::GlobalTypeTableBuilder TypeTable; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric /// Whether to emit type record hashes into .debug$H. 580b57cec5SDimitry Andric bool EmitDebugGlobalHashes = false; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric /// The codeview CPU type used by the translation unit. 610b57cec5SDimitry Andric codeview::CPUType TheCPU; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric /// Represents the most general definition range. 640b57cec5SDimitry Andric struct LocalVarDefRange { 650b57cec5SDimitry Andric /// Indicates that variable data is stored in memory relative to the 660b57cec5SDimitry Andric /// specified register. 670b57cec5SDimitry Andric int InMemory : 1; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric /// Offset of variable data in memory. 700b57cec5SDimitry Andric int DataOffset : 31; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric /// Non-zero if this is a piece of an aggregate. 730b57cec5SDimitry Andric uint16_t IsSubfield : 1; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric /// Offset into aggregate. 760b57cec5SDimitry Andric uint16_t StructOffset : 15; 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric /// Register containing the data or the register base of the memory 790b57cec5SDimitry Andric /// location containing the data. 800b57cec5SDimitry Andric uint16_t CVRegister; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric /// Compares all location fields. This includes all fields except the label 830b57cec5SDimitry Andric /// ranges. 840b57cec5SDimitry Andric bool isDifferentLocation(LocalVarDefRange &O) { 850b57cec5SDimitry Andric return InMemory != O.InMemory || DataOffset != O.DataOffset || 860b57cec5SDimitry Andric IsSubfield != O.IsSubfield || StructOffset != O.StructOffset || 870b57cec5SDimitry Andric CVRegister != O.CVRegister; 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1> Ranges; 910b57cec5SDimitry Andric }; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric static LocalVarDefRange createDefRangeMem(uint16_t CVRegister, int Offset); 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric /// Similar to DbgVariable in DwarfDebug, but not dwarf-specific. 960b57cec5SDimitry Andric struct LocalVariable { 970b57cec5SDimitry Andric const DILocalVariable *DIVar = nullptr; 980b57cec5SDimitry Andric SmallVector<LocalVarDefRange, 1> DefRanges; 990b57cec5SDimitry Andric bool UseReferenceType = false; 1000b57cec5SDimitry Andric }; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric struct CVGlobalVariable { 1030b57cec5SDimitry Andric const DIGlobalVariable *DIGV; 1040b57cec5SDimitry Andric PointerUnion<const GlobalVariable *, const DIExpression *> GVInfo; 1050b57cec5SDimitry Andric }; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric struct InlineSite { 1080b57cec5SDimitry Andric SmallVector<LocalVariable, 1> InlinedLocals; 1090b57cec5SDimitry Andric SmallVector<const DILocation *, 1> ChildSites; 1100b57cec5SDimitry Andric const DISubprogram *Inlinee = nullptr; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric /// The ID of the inline site or function used with .cv_loc. Not a type 1130b57cec5SDimitry Andric /// index. 1140b57cec5SDimitry Andric unsigned SiteFuncId = 0; 1150b57cec5SDimitry Andric }; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric // Combines information from DILexicalBlock and LexicalScope. 1180b57cec5SDimitry Andric struct LexicalBlock { 1190b57cec5SDimitry Andric SmallVector<LocalVariable, 1> Locals; 1200b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> Globals; 1210b57cec5SDimitry Andric SmallVector<LexicalBlock *, 1> Children; 1220b57cec5SDimitry Andric const MCSymbol *Begin; 1230b57cec5SDimitry Andric const MCSymbol *End; 1240b57cec5SDimitry Andric StringRef Name; 1250b57cec5SDimitry Andric }; 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric // For each function, store a vector of labels to its instructions, as well as 1280b57cec5SDimitry Andric // to the end of the function. 1290b57cec5SDimitry Andric struct FunctionInfo { 1300b57cec5SDimitry Andric FunctionInfo() = default; 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric // Uncopyable. 1330b57cec5SDimitry Andric FunctionInfo(const FunctionInfo &FI) = delete; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric /// Map from inlined call site to inlined instructions and child inlined 1360b57cec5SDimitry Andric /// call sites. Listed in program order. 1370b57cec5SDimitry Andric std::unordered_map<const DILocation *, InlineSite> InlineSites; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric /// Ordered list of top-level inlined call sites. 1400b57cec5SDimitry Andric SmallVector<const DILocation *, 1> ChildSites; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric SmallVector<LocalVariable, 1> Locals; 1430b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> Globals; 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric std::unordered_map<const DILexicalBlockBase*, LexicalBlock> LexicalBlocks; 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric // Lexical blocks containing local variables. 1480b57cec5SDimitry Andric SmallVector<LexicalBlock *, 1> ChildBlocks; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric std::vector<std::pair<MCSymbol *, MDNode *>> Annotations; 151*c14a5a88SDimitry Andric std::vector<std::tuple<const MCSymbol *, const MCSymbol *, const DIType *>> 152*c14a5a88SDimitry Andric HeapAllocSites; 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric const MCSymbol *Begin = nullptr; 1550b57cec5SDimitry Andric const MCSymbol *End = nullptr; 1560b57cec5SDimitry Andric unsigned FuncId = 0; 1570b57cec5SDimitry Andric unsigned LastFileId = 0; 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric /// Number of bytes allocated in the prologue for all local stack objects. 1600b57cec5SDimitry Andric unsigned FrameSize = 0; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric /// Number of bytes of parameters on the stack. 1630b57cec5SDimitry Andric unsigned ParamSize = 0; 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric /// Number of bytes pushed to save CSRs. 1660b57cec5SDimitry Andric unsigned CSRSize = 0; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric /// Adjustment to apply on x86 when using the VFRAME frame pointer. 1690b57cec5SDimitry Andric int OffsetAdjustment = 0; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric /// Two-bit value indicating which register is the designated frame pointer 1720b57cec5SDimitry Andric /// register for local variables. Included in S_FRAMEPROC. 1730b57cec5SDimitry Andric codeview::EncodedFramePtrReg EncodedLocalFramePtrReg = 1740b57cec5SDimitry Andric codeview::EncodedFramePtrReg::None; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric /// Two-bit value indicating which register is the designated frame pointer 1770b57cec5SDimitry Andric /// register for stack parameters. Included in S_FRAMEPROC. 1780b57cec5SDimitry Andric codeview::EncodedFramePtrReg EncodedParamFramePtrReg = 1790b57cec5SDimitry Andric codeview::EncodedFramePtrReg::None; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric codeview::FrameProcedureOptions FrameProcOpts; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric bool HasStackRealignment = false; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric bool HaveLineInfo = false; 1860b57cec5SDimitry Andric }; 1870b57cec5SDimitry Andric FunctionInfo *CurFn = nullptr; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric // Map used to seperate variables according to the lexical scope they belong 1900b57cec5SDimitry Andric // in. This is populated by recordLocalVariable() before 1910b57cec5SDimitry Andric // collectLexicalBlocks() separates the variables between the FunctionInfo 1920b57cec5SDimitry Andric // and LexicalBlocks. 1930b57cec5SDimitry Andric DenseMap<const LexicalScope *, SmallVector<LocalVariable, 1>> ScopeVariables; 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric // Map to separate global variables according to the lexical scope they 1960b57cec5SDimitry Andric // belong in. A null local scope represents the global scope. 1970b57cec5SDimitry Andric typedef SmallVector<CVGlobalVariable, 1> GlobalVariableList; 1980b57cec5SDimitry Andric DenseMap<const DIScope*, std::unique_ptr<GlobalVariableList> > ScopeGlobals; 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric // Array of global variables which need to be emitted into a COMDAT section. 2010b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> ComdatVariables; 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric // Array of non-COMDAT global variables. 2040b57cec5SDimitry Andric SmallVector<CVGlobalVariable, 1> GlobalVariables; 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric /// The set of comdat .debug$S sections that we've seen so far. Each section 2070b57cec5SDimitry Andric /// must start with a magic version number that must only be emitted once. 2080b57cec5SDimitry Andric /// This set tracks which sections we've already opened. 2090b57cec5SDimitry Andric DenseSet<MCSectionCOFF *> ComdatDebugSections; 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric /// Switch to the appropriate .debug$S section for GVSym. If GVSym, the symbol 2120b57cec5SDimitry Andric /// of an emitted global value, is in a comdat COFF section, this will switch 2130b57cec5SDimitry Andric /// to a new .debug$S section in that comdat. This method ensures that the 2140b57cec5SDimitry Andric /// section starts with the magic version number on first use. If GVSym is 2150b57cec5SDimitry Andric /// null, uses the main .debug$S section. 2160b57cec5SDimitry Andric void switchToDebugSectionForSymbol(const MCSymbol *GVSym); 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric /// The next available function index for use with our .cv_* directives. Not 2190b57cec5SDimitry Andric /// to be confused with type indices for LF_FUNC_ID records. 2200b57cec5SDimitry Andric unsigned NextFuncId = 0; 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric InlineSite &getInlineSite(const DILocation *InlinedAt, 2230b57cec5SDimitry Andric const DISubprogram *Inlinee); 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP); 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric void calculateRanges(LocalVariable &Var, 2280b57cec5SDimitry Andric const DbgValueHistoryMap::Entries &Entries); 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children, 2310b57cec5SDimitry Andric const FunctionInfo &FI, 2320b57cec5SDimitry Andric const InlineSite &Site); 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric /// Remember some debug info about each function. Keep it in a stable order to 2350b57cec5SDimitry Andric /// emit at the end of the TU. 2360b57cec5SDimitry Andric MapVector<const Function *, std::unique_ptr<FunctionInfo>> FnDebugInfo; 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric /// Map from full file path to .cv_file id. Full paths are built from DIFiles 2390b57cec5SDimitry Andric /// and are stored in FileToFilepathMap; 2400b57cec5SDimitry Andric DenseMap<StringRef, unsigned> FileIdMap; 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric /// All inlined subprograms in the order they should be emitted. 2430b57cec5SDimitry Andric SmallSetVector<const DISubprogram *, 4> InlinedSubprograms; 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric /// Map from a pair of DI metadata nodes and its DI type (or scope) that can 2460b57cec5SDimitry Andric /// be nullptr, to CodeView type indices. Primarily indexed by 2470b57cec5SDimitry Andric /// {DIType*, DIType*} and {DISubprogram*, DIType*}. 2480b57cec5SDimitry Andric /// 2490b57cec5SDimitry Andric /// The second entry in the key is needed for methods as DISubroutineType 2500b57cec5SDimitry Andric /// representing static method type are shared with non-method function type. 2510b57cec5SDimitry Andric DenseMap<std::pair<const DINode *, const DIType *>, codeview::TypeIndex> 2520b57cec5SDimitry Andric TypeIndices; 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric /// Map from DICompositeType* to complete type index. Non-record types are 2550b57cec5SDimitry Andric /// always looked up in the normal TypeIndices map. 2560b57cec5SDimitry Andric DenseMap<const DICompositeType *, codeview::TypeIndex> CompleteTypeIndices; 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric /// Complete record types to emit after all active type lowerings are 2590b57cec5SDimitry Andric /// finished. 2600b57cec5SDimitry Andric SmallVector<const DICompositeType *, 4> DeferredCompleteTypes; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric /// Number of type lowering frames active on the stack. 2630b57cec5SDimitry Andric unsigned TypeEmissionLevel = 0; 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric codeview::TypeIndex VBPType; 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric const DISubprogram *CurrentSubprogram = nullptr; 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric // The UDTs we have seen while processing types; each entry is a pair of type 2700b57cec5SDimitry Andric // index and type name. 2710b57cec5SDimitry Andric std::vector<std::pair<std::string, const DIType *>> LocalUDTs; 2720b57cec5SDimitry Andric std::vector<std::pair<std::string, const DIType *>> GlobalUDTs; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric using FileToFilepathMapTy = std::map<const DIFile *, std::string>; 2750b57cec5SDimitry Andric FileToFilepathMapTy FileToFilepathMap; 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric StringRef getFullFilepath(const DIFile *File); 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric unsigned maybeRecordFile(const DIFile *F); 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric void maybeRecordLocation(const DebugLoc &DL, const MachineFunction *MF); 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric void clear(); 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric void setCurrentSubprogram(const DISubprogram *SP) { 2860b57cec5SDimitry Andric CurrentSubprogram = SP; 2870b57cec5SDimitry Andric LocalUDTs.clear(); 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric /// Emit the magic version number at the start of a CodeView type or symbol 2910b57cec5SDimitry Andric /// section. Appears at the front of every .debug$S or .debug$T or .debug$P 2920b57cec5SDimitry Andric /// section. 2930b57cec5SDimitry Andric void emitCodeViewMagicVersion(); 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric void emitTypeInformation(); 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric void emitTypeGlobalHashes(); 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric void emitCompilerInformation(); 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric void emitBuildInfo(); 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric void emitInlineeLinesSubsection(); 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric void emitDebugInfoForThunk(const Function *GV, 3060b57cec5SDimitry Andric FunctionInfo &FI, 3070b57cec5SDimitry Andric const MCSymbol *Fn); 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI); 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric void emitDebugInfoForRetainedTypes(); 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric void 3140b57cec5SDimitry Andric emitDebugInfoForUDTs(ArrayRef<std::pair<std::string, const DIType *>> UDTs); 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric void emitDebugInfoForGlobals(); 3170b57cec5SDimitry Andric void emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals); 3180b57cec5SDimitry Andric void emitDebugInfoForGlobal(const CVGlobalVariable &CVGV); 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric /// Opens a subsection of the given kind in a .debug$S codeview section. 3210b57cec5SDimitry Andric /// Returns an end label for use with endCVSubsection when the subsection is 3220b57cec5SDimitry Andric /// finished. 3230b57cec5SDimitry Andric MCSymbol *beginCVSubsection(codeview::DebugSubsectionKind Kind); 3240b57cec5SDimitry Andric void endCVSubsection(MCSymbol *EndLabel); 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric /// Opens a symbol record of the given kind. Returns an end label for use with 3270b57cec5SDimitry Andric /// endSymbolRecord. 3280b57cec5SDimitry Andric MCSymbol *beginSymbolRecord(codeview::SymbolKind Kind); 3290b57cec5SDimitry Andric void endSymbolRecord(MCSymbol *SymEnd); 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric /// Emits an S_END, S_INLINESITE_END, or S_PROC_ID_END record. These records 3320b57cec5SDimitry Andric /// are empty, so we emit them with a simpler assembly sequence that doesn't 3330b57cec5SDimitry Andric /// involve labels. 3340b57cec5SDimitry Andric void emitEndSymbolRecord(codeview::SymbolKind EndKind); 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt, 3370b57cec5SDimitry Andric const InlineSite &Site); 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric using InlinedEntity = DbgValueHistoryMap::InlinedEntity; 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric void collectGlobalVariableInfo(); 3420b57cec5SDimitry Andric void collectVariableInfo(const DISubprogram *SP); 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric void collectVariableInfoFromMFTable(DenseSet<InlinedEntity> &Processed); 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric // Construct the lexical block tree for a routine, pruning emptpy lexical 3470b57cec5SDimitry Andric // scopes, and populate it with local variables. 3480b57cec5SDimitry Andric void collectLexicalBlockInfo(SmallVectorImpl<LexicalScope *> &Scopes, 3490b57cec5SDimitry Andric SmallVectorImpl<LexicalBlock *> &Blocks, 3500b57cec5SDimitry Andric SmallVectorImpl<LocalVariable> &Locals, 3510b57cec5SDimitry Andric SmallVectorImpl<CVGlobalVariable> &Globals); 3520b57cec5SDimitry Andric void collectLexicalBlockInfo(LexicalScope &Scope, 3530b57cec5SDimitry Andric SmallVectorImpl<LexicalBlock *> &ParentBlocks, 3540b57cec5SDimitry Andric SmallVectorImpl<LocalVariable> &ParentLocals, 3550b57cec5SDimitry Andric SmallVectorImpl<CVGlobalVariable> &ParentGlobals); 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric /// Records information about a local variable in the appropriate scope. In 3580b57cec5SDimitry Andric /// particular, locals from inlined code live inside the inlining site. 3590b57cec5SDimitry Andric void recordLocalVariable(LocalVariable &&Var, const LexicalScope *LS); 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric /// Emits local variables in the appropriate order. 3620b57cec5SDimitry Andric void emitLocalVariableList(const FunctionInfo &FI, 3630b57cec5SDimitry Andric ArrayRef<LocalVariable> Locals); 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric /// Emits an S_LOCAL record and its associated defined ranges. 3660b57cec5SDimitry Andric void emitLocalVariable(const FunctionInfo &FI, const LocalVariable &Var); 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric /// Emits a sequence of lexical block scopes and their children. 3690b57cec5SDimitry Andric void emitLexicalBlockList(ArrayRef<LexicalBlock *> Blocks, 3700b57cec5SDimitry Andric const FunctionInfo& FI); 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric /// Emit a lexical block scope and its children. 3730b57cec5SDimitry Andric void emitLexicalBlock(const LexicalBlock &Block, const FunctionInfo& FI); 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric /// Translates the DIType to codeview if necessary and returns a type index 3760b57cec5SDimitry Andric /// for it. 3770b57cec5SDimitry Andric codeview::TypeIndex getTypeIndex(const DIType *Ty, 3780b57cec5SDimitry Andric const DIType *ClassTy = nullptr); 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric codeview::TypeIndex 3810b57cec5SDimitry Andric getTypeIndexForThisPtr(const DIDerivedType *PtrTy, 3820b57cec5SDimitry Andric const DISubroutineType *SubroutineTy); 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric codeview::TypeIndex getTypeIndexForReferenceTo(const DIType *Ty); 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric codeview::TypeIndex getMemberFunctionType(const DISubprogram *SP, 3870b57cec5SDimitry Andric const DICompositeType *Class); 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric codeview::TypeIndex getScopeIndex(const DIScope *Scope); 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric codeview::TypeIndex getVBPTypeIndex(); 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric void addToUDTs(const DIType *Ty); 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric void addUDTSrcLine(const DIType *Ty, codeview::TypeIndex TI); 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric codeview::TypeIndex lowerType(const DIType *Ty, const DIType *ClassTy); 3980b57cec5SDimitry Andric codeview::TypeIndex lowerTypeAlias(const DIDerivedType *Ty); 3990b57cec5SDimitry Andric codeview::TypeIndex lowerTypeArray(const DICompositeType *Ty); 4000b57cec5SDimitry Andric codeview::TypeIndex lowerTypeBasic(const DIBasicType *Ty); 4010b57cec5SDimitry Andric codeview::TypeIndex lowerTypePointer( 4020b57cec5SDimitry Andric const DIDerivedType *Ty, 4030b57cec5SDimitry Andric codeview::PointerOptions PO = codeview::PointerOptions::None); 4040b57cec5SDimitry Andric codeview::TypeIndex lowerTypeMemberPointer( 4050b57cec5SDimitry Andric const DIDerivedType *Ty, 4060b57cec5SDimitry Andric codeview::PointerOptions PO = codeview::PointerOptions::None); 4070b57cec5SDimitry Andric codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty); 4080b57cec5SDimitry Andric codeview::TypeIndex lowerTypeFunction(const DISubroutineType *Ty); 4090b57cec5SDimitry Andric codeview::TypeIndex lowerTypeVFTableShape(const DIDerivedType *Ty); 4100b57cec5SDimitry Andric codeview::TypeIndex lowerTypeMemberFunction( 4110b57cec5SDimitry Andric const DISubroutineType *Ty, const DIType *ClassTy, int ThisAdjustment, 4120b57cec5SDimitry Andric bool IsStaticMethod, 4130b57cec5SDimitry Andric codeview::FunctionOptions FO = codeview::FunctionOptions::None); 4140b57cec5SDimitry Andric codeview::TypeIndex lowerTypeEnum(const DICompositeType *Ty); 4150b57cec5SDimitry Andric codeview::TypeIndex lowerTypeClass(const DICompositeType *Ty); 4160b57cec5SDimitry Andric codeview::TypeIndex lowerTypeUnion(const DICompositeType *Ty); 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric /// Symbol records should point to complete types, but type records should 4190b57cec5SDimitry Andric /// always point to incomplete types to avoid cycles in the type graph. Only 4200b57cec5SDimitry Andric /// use this entry point when generating symbol records. The complete and 4210b57cec5SDimitry Andric /// incomplete type indices only differ for record types. All other types use 4220b57cec5SDimitry Andric /// the same index. 4230b57cec5SDimitry Andric codeview::TypeIndex getCompleteTypeIndex(const DIType *Ty); 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric codeview::TypeIndex lowerCompleteTypeClass(const DICompositeType *Ty); 4260b57cec5SDimitry Andric codeview::TypeIndex lowerCompleteTypeUnion(const DICompositeType *Ty); 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric struct TypeLoweringScope; 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric void emitDeferredCompleteTypes(); 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric void collectMemberInfo(ClassInfo &Info, const DIDerivedType *DDTy); 4330b57cec5SDimitry Andric ClassInfo collectClassInfo(const DICompositeType *Ty); 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric /// Common record member lowering functionality for record types, which are 4360b57cec5SDimitry Andric /// structs, classes, and unions. Returns the field list index and the member 4370b57cec5SDimitry Andric /// count. 4380b57cec5SDimitry Andric std::tuple<codeview::TypeIndex, codeview::TypeIndex, unsigned, bool> 4390b57cec5SDimitry Andric lowerRecordFieldList(const DICompositeType *Ty); 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric /// Inserts {{Node, ClassTy}, TI} into TypeIndices and checks for duplicates. 4420b57cec5SDimitry Andric codeview::TypeIndex recordTypeIndexForDINode(const DINode *Node, 4430b57cec5SDimitry Andric codeview::TypeIndex TI, 4440b57cec5SDimitry Andric const DIType *ClassTy = nullptr); 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric unsigned getPointerSizeInBytes(); 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric protected: 4490b57cec5SDimitry Andric /// Gather pre-function debug information. 4500b57cec5SDimitry Andric void beginFunctionImpl(const MachineFunction *MF) override; 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric /// Gather post-function debug information. 4530b57cec5SDimitry Andric void endFunctionImpl(const MachineFunction *) override; 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric public: 4560b57cec5SDimitry Andric CodeViewDebug(AsmPrinter *AP); 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric void setSymbolSize(const MCSymbol *, uint64_t) override {} 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric /// Emit the COFF section that holds the line table information. 4610b57cec5SDimitry Andric void endModule() override; 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric /// Process beginning of an instruction. 4640b57cec5SDimitry Andric void beginInstruction(const MachineInstr *MI) override; 4650b57cec5SDimitry Andric }; 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric } // end namespace llvm 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H 470