LLVM: lib/CodeGen/AsmPrinter/CodeViewDebug.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
14#define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
15
34#include
35#include
36#include
37#include
38#include <unordered_map>
39#include
40#include
41
42namespace llvm {
43
44struct ClassInfo;
45class StringRef;
46class AsmPrinter;
48class GlobalVariable;
49class MCSectionCOFF;
50class MCStreamer;
52class MachineFunction;
53
54
56public:
58
59
61
62
64
65
67
68
70
71
72
74
77 std::memcpy(&Val, &DR, sizeof(Val));
78 return Val;
79 }
80
83 std::memcpy(&DR, &Val, sizeof(Val));
84 return DR;
85 }
86 };
87
88 static_assert(sizeof(uint64_t) == sizeof(LocalVarDef));
89
90private:
94
95
96 bool EmitDebugGlobalHashes = false;
97
98
100
101 static LocalVarDef createDefRangeMem(uint16_t CVRegister, int Offset);
102
103
104 struct LocalVariable {
108 DefRanges;
109 bool UseReferenceType = false;
110 std::optional ConstantValue;
111 };
112
113 struct CVGlobalVariable {
114 const DIGlobalVariable *DIGV;
115 PointerUnion<const GlobalVariable *, const DIExpression *> GVInfo;
116 };
117
119 SmallVector<LocalVariable, 1> InlinedLocals;
120 SmallVector<const DILocation *, 1> ChildSites;
121 const DISubprogram *Inlinee = nullptr;
122
123
124
125 unsigned SiteFuncId = 0;
126 };
127
128
129 struct LexicalBlock {
130 SmallVector<LocalVariable, 1> Locals;
131 SmallVector<CVGlobalVariable, 1> Globals;
132 SmallVector<LexicalBlock *, 1> Children;
135 StringRef Name;
136 };
137
138 struct JumpTableInfo {
139 codeview::JumpTableEntrySize EntrySize;
144 size_t TableSize;
145 };
146
147
148
149 struct FunctionInfo {
150 FunctionInfo() = default;
151
152
153 FunctionInfo(const FunctionInfo &FI) = delete;
154
155
156
157 std::unordered_map<const DILocation *, InlineSite> InlineSites;
158
159
160 SmallVector<const DILocation *, 1> ChildSites;
161
162
163 SmallSet<codeview::TypeIndex, 1> Inlinees;
164
165 SmallVector<LocalVariable, 1> Locals;
166 SmallVector<CVGlobalVariable, 1> Globals;
167
168 std::unordered_map<const DILexicalBlockBase*, LexicalBlock> LexicalBlocks;
169
170
171 SmallVector<LexicalBlock *, 1> ChildBlocks;
172
173 std::vector<std::pair<MCSymbol *, MDNode *>> Annotations;
174 std::vector<std::tuple<const MCSymbol *, const MCSymbol *, const DIType *>>
175 HeapAllocSites;
176
177 std::vector JumpTables;
178
179 const MCSymbol *Begin = nullptr;
182 unsigned LastFileId = 0;
183
184
185 unsigned FrameSize = 0;
186
187
188 unsigned ParamSize = 0;
189
190
191 unsigned CSRSize = 0;
192
193
194 int OffsetAdjustment = 0;
195
196
197
198 codeview::EncodedFramePtrReg EncodedLocalFramePtrReg =
199 codeview::EncodedFramePtrReg::None;
200
201
202
203 codeview::EncodedFramePtrReg EncodedParamFramePtrReg =
204 codeview::EncodedFramePtrReg::None;
205
206 codeview::FrameProcedureOptions FrameProcOpts;
207
208 bool HasStackRealignment = false;
209
210 bool HaveLineInfo = false;
211
212 bool HasFramePointer = false;
213 };
214 FunctionInfo *CurFn = nullptr;
215
216 codeview::SourceLanguage CurrentSourceLanguage =
217 codeview::SourceLanguage::Masm;
218
219
220
221 DenseMap<const DIGlobalVariable *, uint64_t> CVGlobalVariableOffsets;
222
223
224
225
226
227 DenseMap<const LexicalScope *, SmallVector<LocalVariable, 1>> ScopeVariables;
228
229
230
231 typedef SmallVector<CVGlobalVariable, 1> GlobalVariableList;
232 DenseMap<const DIScope*, std::unique_ptr > ScopeGlobals;
233
234
235 SmallVector<CVGlobalVariable, 1> ComdatVariables;
236
237
238 SmallVector<CVGlobalVariable, 1> GlobalVariables;
239
240
241 SmallVector<const DIDerivedType *, 4> StaticConstMembers;
242
243
244
245
246 DenseSet<MCSectionCOFF *> ComdatDebugSections;
247
248
249
250
251
252
253 void switchToDebugSectionForSymbol(const MCSymbol *GVSym);
254
255
256
257 unsigned NextFuncId = 0;
258
259 InlineSite &getInlineSite(const DILocation *InlinedAt,
260 const DISubprogram *Inlinee);
261
262 codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP);
263
264 void calculateRanges(LocalVariable &Var,
265 const DbgValueHistoryMap::Entries &Entries);
266
267
268
269 MapVector<const Function *, std::unique_ptr> FnDebugInfo;
270
271
272
273 DenseMap<StringRef, unsigned> FileIdMap;
274
275
276 SmallSetVector<const DISubprogram *, 4> InlinedSubprograms;
277
278
279
280
281
282
283
284 DenseMap<std::pair<const DINode *, const DIType *>, codeview::TypeIndex>
285 TypeIndices;
286
287
288
289 DenseMap<const DICompositeType *, codeview::TypeIndex> CompleteTypeIndices;
290
291
292
293 SmallVector<const DICompositeType *, 4> DeferredCompleteTypes;
294
295
296 unsigned TypeEmissionLevel = 0;
297
298 codeview::TypeIndex VBPType;
299
300 const DISubprogram *CurrentSubprogram = nullptr;
301
302
303
304 std::vector<std::pair<std::string, const DIType *>> LocalUDTs;
305 std::vector<std::pair<std::string, const DIType *>> GlobalUDTs;
306
307 using FileToFilepathMapTy = std::map<const DIFile *, std::string>;
308 FileToFilepathMapTy FileToFilepathMap;
309
310 StringRef getFullFilepath(const DIFile *File);
311
312 unsigned maybeRecordFile(const DIFile *F);
313
314 void maybeRecordLocation(const DebugLoc &DL, const MachineFunction *MF);
315
316 void clear();
317
318 void setCurrentSubprogram(const DISubprogram *SP) {
319 CurrentSubprogram = SP;
320 LocalUDTs.clear();
321 }
322
323
324
325
326 void emitCodeViewMagicVersion();
327
328 void emitTypeInformation();
329
330 void emitTypeGlobalHashes();
331
332 void emitObjName();
333
334 void emitCompilerInformation();
335
336 void emitBuildInfo();
337
338 void emitInlineeLinesSubsection();
339
340 void emitDebugInfoForThunk(const Function *GV,
341 FunctionInfo &FI,
342 const MCSymbol *Fn);
343
344 void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI);
345
346 void emitDebugInfoForRetainedTypes();
347
348 void emitDebugInfoForUDTs(
349 const std::vector<std::pair<std::string, const DIType *>> &UDTs);
350
351 void collectDebugInfoForGlobals();
352 void emitDebugInfoForGlobals();
353 void emitGlobalVariableList(ArrayRef Globals);
354 void emitConstantSymbolRecord(const DIType *DTy, APSInt &Value,
356 void emitDebugInfoForGlobal(const CVGlobalVariable &CVGV);
357 void emitStaticConstMemberList();
358
359
360
361
362 MCSymbol *beginCVSubsection(codeview::DebugSubsectionKind Kind);
363 void endCVSubsection(MCSymbol *EndLabel);
364
365
366
367 MCSymbol *beginSymbolRecord(codeview::SymbolKind Kind);
368 void endSymbolRecord(MCSymbol *SymEnd);
369
370
371
372
373 void emitEndSymbolRecord(codeview::SymbolKind EndKind);
374
375 void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt,
376 const InlineSite &Site);
377
378 void emitInlinees(const SmallSet<codeview::TypeIndex, 1> &Inlinees);
379
380 using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
381
382 void collectGlobalVariableInfo();
383 void collectVariableInfo(const DISubprogram *SP);
384
385 void collectVariableInfoFromMFTable(DenseSet &Processed);
386
387
388
389 void collectLexicalBlockInfo(SmallVectorImpl<LexicalScope *> &Scopes,
390 SmallVectorImpl<LexicalBlock *> &Blocks,
391 SmallVectorImpl &Locals,
392 SmallVectorImpl &Globals);
393 void collectLexicalBlockInfo(LexicalScope &Scope,
394 SmallVectorImpl<LexicalBlock *> &ParentBlocks,
395 SmallVectorImpl &ParentLocals,
396 SmallVectorImpl &ParentGlobals);
397
398
399
400 void recordLocalVariable(LocalVariable &&Var, const LexicalScope *LS);
401
402
403 void emitLocalVariableList(const FunctionInfo &FI,
404 ArrayRef Locals);
405
406
407 void emitLocalVariable(const FunctionInfo &FI, const LocalVariable &Var);
408
409
410 void emitLexicalBlockList(ArrayRef<LexicalBlock *> Blocks,
411 const FunctionInfo& FI);
412
413
414 void emitLexicalBlock(const LexicalBlock &Block, const FunctionInfo& FI);
415
416
417
418 codeview::TypeIndex getTypeIndex(const DIType *Ty,
419 const DIType *ClassTy = nullptr);
420
421 codeview::TypeIndex
422 getTypeIndexForThisPtr(const DIDerivedType *PtrTy,
423 const DISubroutineType *SubroutineTy);
424
425 codeview::TypeIndex getTypeIndexForReferenceTo(const DIType *Ty);
426
427 codeview::TypeIndex getMemberFunctionType(const DISubprogram *SP,
428 const DICompositeType *Class);
429
430 codeview::TypeIndex getScopeIndex(const DIScope *Scope);
431
432 codeview::TypeIndex getVBPTypeIndex();
433
434 void addToUDTs(const DIType *Ty);
435
436 void addUDTSrcLine(const DIType *Ty, codeview::TypeIndex TI);
437
438 codeview::TypeIndex lowerType(const DIType *Ty, const DIType *ClassTy);
439 codeview::TypeIndex lowerTypeAlias(const DIDerivedType *Ty);
440 codeview::TypeIndex lowerTypeArray(const DICompositeType *Ty);
441 codeview::TypeIndex lowerTypeString(const DIStringType *Ty);
442 codeview::TypeIndex lowerTypeBasic(const DIBasicType *Ty);
443 codeview::TypeIndex lowerTypePointer(
444 const DIDerivedType *Ty,
445 codeview::PointerOptions PO = codeview::PointerOptions::None);
446 codeview::TypeIndex lowerTypeMemberPointer(
447 const DIDerivedType *Ty,
448 codeview::PointerOptions PO = codeview::PointerOptions::None);
449 codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty);
450 codeview::TypeIndex lowerTypeFunction(const DISubroutineType *Ty);
451 codeview::TypeIndex lowerTypeVFTableShape(const DIDerivedType *Ty);
452 codeview::TypeIndex lowerTypeMemberFunction(
453 const DISubroutineType *Ty, const DIType *ClassTy, int ThisAdjustment,
454 bool IsStaticMethod,
455 codeview::FunctionOptions FO = codeview::FunctionOptions::None);
456 codeview::TypeIndex lowerTypeEnum(const DICompositeType *Ty);
457 codeview::TypeIndex lowerTypeClass(const DICompositeType *Ty);
458 codeview::TypeIndex lowerTypeUnion(const DICompositeType *Ty);
459
460
461
462
463
464
465 codeview::TypeIndex getCompleteTypeIndex(const DIType *Ty);
466
467 codeview::TypeIndex lowerCompleteTypeClass(const DICompositeType *Ty);
468 codeview::TypeIndex lowerCompleteTypeUnion(const DICompositeType *Ty);
469
470 struct TypeLoweringScope;
471
472 void emitDeferredCompleteTypes();
473
474 void collectMemberInfo(ClassInfo &Info, const DIDerivedType *DDTy);
475 ClassInfo collectClassInfo(const DICompositeType *Ty);
476
477
478
479
480 std::tuple<codeview::TypeIndex, codeview::TypeIndex, unsigned, bool>
481 lowerRecordFieldList(const DICompositeType *Ty);
482
483
484 codeview::TypeIndex recordTypeIndexForDINode(const DINode *Node,
485 codeview::TypeIndex TI,
486 const DIType *ClassTy = nullptr);
487
488
489
490
491 const DISubprogram *
492 collectParentScopeNames(const DIScope *Scope,
493 SmallVectorImpl &ParentScopeNames);
494 std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name);
495 std::string getFullyQualifiedName(const DIScope *Scope);
496
497 unsigned getPointerSizeInBytes();
498
499 void discoverJumpTableBranches(const MachineFunction *MF, bool isThumb);
500 void collectDebugInfoForJumpTables(const MachineFunction *MF, bool isThumb);
501 void emitDebugInfoForJumpTables(const FunctionInfo &FI);
502
503protected:
504
505 void beginFunctionImpl(const MachineFunction *MF) override;
506
507
508 void endFunctionImpl(const MachineFunction *) override;
509
510
512 return CurrentSourceLanguage == codeview::SourceLanguage::Fortran;
513 }
514
515public:
517
518 void beginModule(Module *M) override;
519
520
521 void endModule() override;
522
523
524 void beginInstruction(const MachineInstr *MI) override;
525};
526
528
531 }
532
535 }
536
539 }
540
545 }
546};
547
548}
549
550#endif
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isThumb(const MCSubtargetInfo &STI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the BumpPtrAllocator interface.
Analysis containing CSE Info
#define LLVM_LIBRARY_VISIBILITY
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
DenseMap< Block *, BlockRelaxAux > Blocks
This file implements a map that provides insertion order iteration.
This file defines the PointerUnion class, which is a discriminated union of pointer types.
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
This file defines the SmallVector class.
This class is intended to be used as a driving class for all asm writers.
Allocate memory in an ever growing pool, as if by bump-pointer.
Collects and handles line tables information in a CodeView format.
bool moduleIsInFortran()
Check if the current module is in Fortran.
Base class for debug information backends.
Streaming machine code generation interface.
Representation of each machine instruction.
This class implements a map that also provides access to all stored values in a deterministic order.
A Module instance is used to store all the information related to an LLVM module.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
This is an optimization pass for GlobalISel generic memory operations.
std::tuple< uint64_t, uint32_t > InlineSite
int DataOffset
Offset of variable data in memory.
static uint64_t toOpaqueValue(const LocalVarDef DR)
int InMemory
Indicates that variable data is stored in memory relative to the specified register.
static LocalVarDef createFromOpaqueValue(uint64_t Val)
uint16_t CVRegister
Register containing the data or the register base of the memory location containing the data.
uint16_t StructOffset
Offset into aggregate.
uint16_t IsSubfield
Non-zero if this is a piece of an aggregate.
static bool isEqual(const CodeViewDebug::LocalVarDef &LHS, const CodeViewDebug::LocalVarDef &RHS)
static CodeViewDebug::LocalVarDef getEmptyKey()
static unsigned getHashValue(const CodeViewDebug::LocalVarDef &DR)
static CodeViewDebug::LocalVarDef getTombstoneKey()
An information struct used to provide DenseMap with the various necessary components for a given valu...