blob: ce1d8b51c40a405190fe636e399bcda5cc51658f [file] [log] [blame]
Reid Kleckner70f5bc92016-01-14 19:25:04 +00001//===-- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h ----*- C++ -*--===//
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Reid Kleckner70f5bc92016-01-14 19:25:04 +000010// This file contains support for writing Microsoft CodeView debug info.
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000011//
12//===----------------------------------------------------------------------===//
13
Reid Kleckner70f5bc92016-01-14 19:25:04 +000014#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
15#define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000016
Reid Klecknerf9c275f2016-02-10 20:55:49 +000017#include "DebugHandlerBase.h"
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000018#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/StringMap.h"
20#include "llvm/ADT/StringRef.h"
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000021#include "llvm/CodeGen/AsmPrinter.h"
22#include "llvm/CodeGen/MachineFunction.h"
23#include "llvm/CodeGen/MachineModuleInfo.h"
Reid Klecknerf3b9ba42016-01-29 18:16:43 +000024#include "llvm/DebugInfo/CodeView/TypeIndex.h"
Chandler Carruth9a4c9e52014-03-06 00:46:21 +000025#include "llvm/IR/DebugInfo.h"
Chandler Carruth92051402014-03-05 10:30:38 +000026#include "llvm/IR/DebugLoc.h"
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000027#include "llvm/MC/MCStreamer.h"
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000028#include "llvm/Target/TargetLoweringObjectFile.h"
29
30namespace llvm {
Reid Klecknerf9c275f2016-02-10 20:55:49 +000031
32class LexicalScope;
33
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000034/// \brief Collects and handles line tables information in a CodeView format.
Reid Klecknerf9c275f2016-02-10 20:55:49 +000035class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
Reid Klecknerdac21b42016-02-03 21:15:48 +000036 MCStreamer &OS;
Reid Klecknerf9c275f2016-02-10 20:55:49 +000037
Reid Kleckner876330d2016-02-12 21:48:30 +000038 /// Represents the most general definition range.
39 struct LocalVarDefRange {
40 /// Indicates that variable data is stored in memory relative to the
41 /// specified register.
42 int InMemory : 1;
43
44 /// Offset of variable data in memory.
45 int DataOffset : 31;
46
47 /// Offset of the data into the user level struct. If zero, no splitting
48 /// occurred.
49 uint16_t StructOffset;
50
51 /// Register containing the data or the register base of the memory
52 /// location containing the data.
53 uint16_t CVRegister;
54
55 /// Compares all location fields. This includes all fields except the label
56 /// ranges.
57 bool isDifferentLocation(LocalVarDefRange &O) {
58 return InMemory != O.InMemory || DataOffset != O.DataOffset ||
59 StructOffset != O.StructOffset || CVRegister != O.CVRegister;
60 }
61
62 SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1> Ranges;
63 };
64
65 static LocalVarDefRange createDefRangeMem(uint16_t CVRegister, int Offset);
66 static LocalVarDefRange createDefRangeReg(uint16_t CVRegister);
67
Reid Klecknerf9c275f2016-02-10 20:55:49 +000068 /// Similar to DbgVariable in DwarfDebug, but not dwarf-specific.
69 struct LocalVariable {
70 const DILocalVariable *DIVar = nullptr;
Reid Kleckner876330d2016-02-12 21:48:30 +000071 SmallVector<LocalVarDefRange, 1> DefRanges;
Reid Klecknerf9c275f2016-02-10 20:55:49 +000072 };
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000073
Reid Klecknerf3b9ba42016-01-29 18:16:43 +000074 struct InlineSite {
Reid Klecknerf9c275f2016-02-10 20:55:49 +000075 SmallVector<LocalVariable, 1> InlinedLocals;
76 SmallVector<const DILocation *, 1> ChildSites;
Reid Klecknerf3b9ba42016-01-29 18:16:43 +000077 const DISubprogram *Inlinee = nullptr;
78 unsigned SiteFuncId = 0;
79 };
80
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000081 // For each function, store a vector of labels to its instructions, as well as
82 // to the end of the function.
83 struct FunctionInfo {
Reid Klecknerf3b9ba42016-01-29 18:16:43 +000084 /// Map from inlined call site to inlined instructions and child inlined
85 /// call sites. Listed in program order.
Reid Klecknerf9c275f2016-02-10 20:55:49 +000086 std::unordered_map<const DILocation *, InlineSite> InlineSites;
87
88 /// Ordered list of top-level inlined call sites.
89 SmallVector<const DILocation *, 1> ChildSites;
90
91 SmallVector<LocalVariable, 1> Locals;
Reid Klecknerf3b9ba42016-01-29 18:16:43 +000092
Reid Kleckner9533af42016-01-16 00:09:09 +000093 DebugLoc LastLoc;
Reid Kleckner1fcd6102016-02-02 17:41:18 +000094 const MCSymbol *Begin = nullptr;
95 const MCSymbol *End = nullptr;
Reid Kleckner2214ed82016-01-29 00:49:42 +000096 unsigned FuncId = 0;
Reid Klecknerf3b9ba42016-01-29 18:16:43 +000097 unsigned LastFileId = 0;
Reid Kleckner2214ed82016-01-29 00:49:42 +000098 bool HaveLineInfo = false;
Reid Kleckner9533af42016-01-16 00:09:09 +000099 };
100 FunctionInfo *CurFn;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000101
Reid Kleckner2214ed82016-01-29 00:49:42 +0000102 unsigned NextFuncId = 0;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000103
Reid Kleckner876330d2016-02-12 21:48:30 +0000104 InlineSite &getInlineSite(const DILocation *InlinedAt,
105 const DISubprogram *Inlinee);
Reid Klecknerf3b9ba42016-01-29 18:16:43 +0000106
Reid Kleckner1fcd6102016-02-02 17:41:18 +0000107 static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children,
108 const FunctionInfo &FI,
109 const InlineSite &Site);
110
Reid Kleckner2214ed82016-01-29 00:49:42 +0000111 /// Remember some debug info about each function. Keep it in a stable order to
112 /// emit at the end of the TU.
113 MapVector<const Function *, FunctionInfo> FnDebugInfo;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000114
Reid Kleckner2214ed82016-01-29 00:49:42 +0000115 /// Map from DIFile to .cv_file id.
116 DenseMap<const DIFile *, unsigned> FileIdMap;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000117
Reid Kleckner1fcd6102016-02-02 17:41:18 +0000118 SmallSetVector<const DISubprogram *, 4> InlinedSubprograms;
119
Reid Klecknerf3b9ba42016-01-29 18:16:43 +0000120 DenseMap<const DISubprogram *, codeview::TypeIndex> SubprogramToFuncId;
121
122 unsigned TypeCount = 0;
123
124 /// Gets the next type index and increments the count of types streamed so
125 /// far.
126 codeview::TypeIndex getNextTypeIndex() {
127 return codeview::TypeIndex(codeview::TypeIndex::FirstNonSimpleIndex + TypeCount++);
128 }
129
Reid Kleckner9533af42016-01-16 00:09:09 +0000130 typedef std::map<const DIFile *, std::string> FileToFilepathMapTy;
131 FileToFilepathMapTy FileToFilepathMap;
132 StringRef getFullFilepath(const DIFile *S);
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000133
Reid Kleckner2214ed82016-01-29 00:49:42 +0000134 unsigned maybeRecordFile(const DIFile *F);
135
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000136 void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF);
137
138 void clear() {
Craig Toppere73658d2014-04-28 04:05:08 +0000139 assert(CurFn == nullptr);
Reid Kleckner2214ed82016-01-29 00:49:42 +0000140 FileIdMap.clear();
141 FnDebugInfo.clear();
142 FileToFilepathMap.clear();
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000143 }
144
Reid Klecknerf3b9ba42016-01-29 18:16:43 +0000145 void emitTypeInformation();
146
Reid Kleckner1fcd6102016-02-02 17:41:18 +0000147 void emitInlineeLinesSubsection();
148
Reid Kleckner2214ed82016-01-29 00:49:42 +0000149 void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI);
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000150
Reid Klecknerf3b9ba42016-01-29 18:16:43 +0000151 void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt,
152 const InlineSite &Site);
153
Reid Kleckner876330d2016-02-12 21:48:30 +0000154 typedef DbgValueHistoryMap::InlinedVariable InlinedVariable;
155
156 void collectVariableInfo(const DISubprogram *SP);
157
158 void collectVariableInfoFromMMITable(DenseSet<InlinedVariable> &Processed);
159
160 /// Records information about a local variable in the appropriate scope. In
161 /// particular, locals from inlined code live inside the inlining site.
162 void recordLocalVariable(LocalVariable &&Var, const DILocation *Loc);
Reid Klecknerf9c275f2016-02-10 20:55:49 +0000163
164 void emitLocalVariable(const LocalVariable &Var);
165
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000166public:
Reid Kleckner70f5bc92016-01-14 19:25:04 +0000167 CodeViewDebug(AsmPrinter *Asm);
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000168
Craig Topper7b883b32014-03-08 06:31:39 +0000169 void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {}
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000170
171 /// \brief Emit the COFF section that holds the line table information.
Craig Topper7b883b32014-03-08 06:31:39 +0000172 void endModule() override;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000173
174 /// \brief Gather pre-function debug information.
Craig Topper7b883b32014-03-08 06:31:39 +0000175 void beginFunction(const MachineFunction *MF) override;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000176
177 /// \brief Gather post-function debug information.
Craig Topper7b883b32014-03-08 06:31:39 +0000178 void endFunction(const MachineFunction *) override;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000179
180 /// \brief Process beginning of an instruction.
Craig Topper7b883b32014-03-08 06:31:39 +0000181 void beginInstruction(const MachineInstr *MI) override;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000182};
183} // End of namespace llvm
184
185#endif