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