13#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
14#define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
38#include <unordered_map>
77 std::memcpy(&Val, &DR,
sizeof(Val));
83 std::memcpy(&DR, &Val,
sizeof(Val));
88 static_assert(
sizeof(
uint64_t) ==
sizeof(LocalVarDef));
96 bool EmitDebugGlobalHashes =
false;
101 static LocalVarDef createDefRangeMem(
uint16_t CVRegister,
int Offset);
104 struct LocalVariable {
109 bool UseReferenceType =
false;
110 std::optional<APSInt> ConstantValue;
113 struct CVGlobalVariable {
114 const DIGlobalVariable *DIGV;
115 PointerUnion<const GlobalVariable *, const DIExpression *> GVInfo;
119 SmallVector<LocalVariable, 1> InlinedLocals;
120 SmallVector<const DILocation *, 1> ChildSites;
121 const DISubprogram *
Inlinee =
nullptr;
125 unsigned SiteFuncId = 0;
129 struct LexicalBlock {
130 SmallVector<LocalVariable, 1>
Locals;
131 SmallVector<CVGlobalVariable, 1> Globals;
132 SmallVector<LexicalBlock *, 1>
Children;
138 struct JumpTableInfo {
139 codeview::JumpTableEntrySize EntrySize;
149 struct FunctionInfo {
150 FunctionInfo() =
default;
153 FunctionInfo(
const FunctionInfo &FI) =
delete;
157 std::unordered_map<const DILocation *, InlineSite> InlineSites;
160 SmallVector<const DILocation *, 1> ChildSites;
163 SmallSet<codeview::TypeIndex, 1> Inlinees;
165 SmallVector<LocalVariable, 1>
Locals;
166 SmallVector<CVGlobalVariable, 1> Globals;
168 std::unordered_map<const DILexicalBlockBase*, LexicalBlock> LexicalBlocks;
171 SmallVector<LexicalBlock *, 1> ChildBlocks;
173 std::vector<std::pair<MCSymbol *, MDNode *>> Annotations;
174 std::vector<std::tuple<const MCSymbol *, const MCSymbol *, const DIType *>>
177 std::vector<JumpTableInfo> JumpTables;
182 unsigned LastFileId = 0;
185 unsigned FrameSize = 0;
188 unsigned ParamSize = 0;
191 unsigned CSRSize = 0;
194 int OffsetAdjustment = 0;
198 codeview::EncodedFramePtrReg EncodedLocalFramePtrReg =
199 codeview::EncodedFramePtrReg::None;
203 codeview::EncodedFramePtrReg EncodedParamFramePtrReg =
204 codeview::EncodedFramePtrReg::None;
206 codeview::FrameProcedureOptions FrameProcOpts;
208 bool HasStackRealignment =
false;
210 bool HaveLineInfo =
false;
212 bool HasFramePointer =
false;
214 FunctionInfo *CurFn =
nullptr;
216 codeview::SourceLanguage CurrentSourceLanguage =
217 codeview::SourceLanguage::Masm;
221 DenseMap<const DIGlobalVariable *, uint64_t> CVGlobalVariableOffsets;
227 DenseMap<const LexicalScope *, SmallVector<LocalVariable, 1>> ScopeVariables;
231 typedef SmallVector<CVGlobalVariable, 1> GlobalVariableList;
232 DenseMap<const DIScope*, std::unique_ptr<GlobalVariableList> > ScopeGlobals;
235 SmallVector<CVGlobalVariable, 1> ComdatVariables;
238 SmallVector<CVGlobalVariable, 1> GlobalVariables;
241 SmallVector<const DIDerivedType *, 4> StaticConstMembers;
246 DenseSet<MCSectionCOFF *> ComdatDebugSections;
253 void switchToDebugSectionForSymbol(
const MCSymbol *GVSym);
257 unsigned NextFuncId = 0;
259 InlineSite &getInlineSite(
const DILocation *InlinedAt,
260 const DISubprogram *Inlinee);
262 codeview::TypeIndex getFuncIdForSubprogram(
const DISubprogram *SP);
264 void calculateRanges(LocalVariable &Var,
265 const DbgValueHistoryMap::Entries &Entries);
269 MapVector<const Function *, std::unique_ptr<FunctionInfo>> FnDebugInfo;
273 DenseMap<StringRef, unsigned> FileIdMap;
276 SmallSetVector<const DISubprogram *, 4> InlinedSubprograms;
284 DenseMap<std::pair<const DINode *, const DIType *>, codeview::TypeIndex>
289 DenseMap<const DICompositeType *, codeview::TypeIndex> CompleteTypeIndices;
293 SmallVector<const DICompositeType *, 4> DeferredCompleteTypes;
296 unsigned TypeEmissionLevel = 0;
298 codeview::TypeIndex VBPType;
300 const DISubprogram *CurrentSubprogram =
nullptr;
304 std::vector<std::pair<std::string, const DIType *>> LocalUDTs;
305 std::vector<std::pair<std::string, const DIType *>> GlobalUDTs;
307 using FileToFilepathMapTy = std::map<const DIFile *, std::string>;
308 FileToFilepathMapTy FileToFilepathMap;
310 StringRef getFullFilepath(
const DIFile *File);
312 unsigned maybeRecordFile(
const DIFile *
F);
314 void maybeRecordLocation(
const DebugLoc &
DL,
const MachineFunction *MF);
318 void setCurrentSubprogram(
const DISubprogram *SP) {
319 CurrentSubprogram = SP;
326 void emitCodeViewMagicVersion();
328 void emitTypeInformation();
330 void emitTypeGlobalHashes();
334 void emitCompilerInformation();
336 void emitBuildInfo();
338 void emitInlineeLinesSubsection();
340 void emitDebugInfoForThunk(
const Function *GV,
344 void emitDebugInfoForFunction(
const Function *GV, FunctionInfo &FI);
346 void emitDebugInfoForRetainedTypes();
348 void emitDebugInfoForUDTs(
349 const std::vector<std::pair<std::string, const DIType *>> &UDTs);
351 void collectDebugInfoForGlobals();
352 void emitDebugInfoForGlobals();
353 void emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals);
354 void emitConstantSymbolRecord(
const DIType *DTy, APSInt &Value,
356 void emitDebugInfoForGlobal(
const CVGlobalVariable &CVGV);
357 void emitStaticConstMemberList();
362 MCSymbol *beginCVSubsection(codeview::DebugSubsectionKind Kind);
363 void endCVSubsection(MCSymbol *EndLabel);
367 MCSymbol *beginSymbolRecord(codeview::SymbolKind Kind);
368 void endSymbolRecord(MCSymbol *SymEnd);
373 void emitEndSymbolRecord(codeview::SymbolKind EndKind);
375 void emitInlinedCallSite(
const FunctionInfo &FI,
const DILocation *InlinedAt,
376 const InlineSite &Site);
378 void emitInlinees(
const SmallSet<codeview::TypeIndex, 1> &Inlinees);
380 using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
382 void collectGlobalVariableInfo();
383 void collectVariableInfo(
const DISubprogram *SP);
385 void collectVariableInfoFromMFTable(DenseSet<InlinedEntity> &Processed);
389 void collectLexicalBlockInfo(SmallVectorImpl<LexicalScope *> &Scopes,
390 SmallVectorImpl<LexicalBlock *> &
Blocks,
391 SmallVectorImpl<LocalVariable> &Locals,
392 SmallVectorImpl<CVGlobalVariable> &Globals);
393 void collectLexicalBlockInfo(LexicalScope &Scope,
394 SmallVectorImpl<LexicalBlock *> &ParentBlocks,
395 SmallVectorImpl<LocalVariable> &ParentLocals,
396 SmallVectorImpl<CVGlobalVariable> &ParentGlobals);
400 void recordLocalVariable(LocalVariable &&Var,
const LexicalScope *LS);
403 void emitLocalVariableList(
const FunctionInfo &FI,
404 ArrayRef<LocalVariable> Locals);
407 void emitLocalVariable(
const FunctionInfo &FI,
const LocalVariable &Var);
410 void emitLexicalBlockList(ArrayRef<LexicalBlock *>
Blocks,
411 const FunctionInfo& FI);
414 void emitLexicalBlock(
const LexicalBlock &Block,
const FunctionInfo& FI);
418 codeview::TypeIndex getTypeIndex(
const DIType *Ty,
419 const DIType *ClassTy =
nullptr);
422 getTypeIndexForThisPtr(
const DIDerivedType *PtrTy,
423 const DISubroutineType *SubroutineTy);
425 codeview::TypeIndex getTypeIndexForReferenceTo(
const DIType *Ty);
427 codeview::TypeIndex getMemberFunctionType(
const DISubprogram *SP,
428 const DICompositeType *Class);
430 codeview::TypeIndex getScopeIndex(
const DIScope *Scope);
432 codeview::TypeIndex getVBPTypeIndex();
434 void addToUDTs(
const DIType *Ty);
436 void addUDTSrcLine(
const DIType *Ty, codeview::TypeIndex TI);
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,
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);
465 codeview::TypeIndex getCompleteTypeIndex(
const DIType *Ty);
467 codeview::TypeIndex lowerCompleteTypeClass(
const DICompositeType *Ty);
468 codeview::TypeIndex lowerCompleteTypeUnion(
const DICompositeType *Ty);
470 struct TypeLoweringScope;
472 void emitDeferredCompleteTypes();
474 void collectMemberInfo(ClassInfo &
Info,
const DIDerivedType *DDTy);
475 ClassInfo collectClassInfo(
const DICompositeType *Ty);
480 std::tuple<codeview::TypeIndex, codeview::TypeIndex, unsigned, bool>
481 lowerRecordFieldList(
const DICompositeType *Ty);
484 codeview::TypeIndex recordTypeIndexForDINode(
const DINode *
Node,
485 codeview::TypeIndex TI,
486 const DIType *ClassTy =
nullptr);
492 collectParentScopeNames(
const DIScope *Scope,
493 SmallVectorImpl<StringRef> &ParentScopeNames);
494 std::string getFullyQualifiedName(
const DIScope *Scope, StringRef
Name);
495 std::string getFullyQualifiedName(
const DIScope *Scope);
497 unsigned getPointerSizeInBytes();
499 void discoverJumpTableBranches(
const MachineFunction *MF,
bool isThumb);
500 void collectDebugInfoForJumpTables(
const MachineFunction *MF,
bool isThumb);
501 void emitDebugInfoForJumpTables(
const FunctionInfo &FI);
505 void beginFunctionImpl(
const MachineFunction *MF)
override;
508 void endFunctionImpl(
const MachineFunction *)
override;
512 return CurrentSourceLanguage == codeview::SourceLanguage::Fortran;
518 void beginModule(
Module *M)
override;
521 void endModule()
override;
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...