blob: 43d1a432712eb8c914b43c159f60bfa42a018d74 [file] [log] [blame]
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +00001//===-- llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h ----*- C++ -*--===//
2//
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//
10// This file contains support for writing line tables info into COFF files.
11//
12//===----------------------------------------------------------------------===//
13
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000014#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H
15#define LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000016
17#include "AsmPrinterHandler.h"
18#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"
Chandler Carruth442f7842014-03-04 10:07:28 +000022#include "llvm/CodeGen/LexicalScopes.h"
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000023#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/MachineModuleInfo.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 {
31/// \brief Collects and handles line tables information in a CodeView format.
Benjamin Kramer286d4662015-07-01 16:18:16 +000032class LLVM_LIBRARY_VISIBILITY WinCodeViewLineTables : public AsmPrinterHandler {
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000033 AsmPrinter *Asm;
34 DebugLoc PrevInstLoc;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000035
36 // For each function, store a vector of labels to its instructions, as well as
37 // to the end of the function.
38 struct FunctionInfo {
39 SmallVector<MCSymbol *, 10> Instrs;
40 MCSymbol *End;
Craig Toppere73658d2014-04-28 04:05:08 +000041 FunctionInfo() : End(nullptr) {}
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000042 } *CurFn;
43
44 typedef DenseMap<const Function *, FunctionInfo> FnDebugInfoTy;
45 FnDebugInfoTy FnDebugInfo;
46 // Store the functions we've visited in a vector so we can maintain a stable
47 // order while emitting subsections.
48 SmallVector<const Function *, 10> VisitedFunctions;
49
50 // InstrInfoTy - Holds the Filename:LineNumber information for every
51 // instruction with a unique debug location.
52 struct InstrInfoTy {
53 StringRef Filename;
54 unsigned LineNumber;
David Majnemer3f49e662015-07-09 00:19:51 +000055 unsigned ColumnNumber;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000056
David Majnemer3f49e662015-07-09 00:19:51 +000057 InstrInfoTy() : LineNumber(0), ColumnNumber(0) {}
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000058
David Majnemer3f49e662015-07-09 00:19:51 +000059 InstrInfoTy(StringRef Filename, unsigned LineNumber, unsigned ColumnNumber)
60 : Filename(Filename), LineNumber(LineNumber),
61 ColumnNumber(ColumnNumber) {}
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +000062 };
63 DenseMap<MCSymbol *, InstrInfoTy> InstrInfo;
64
65 // FileNameRegistry - Manages filenames observed while generating debug info
66 // by filtering out duplicates and bookkeeping the offsets in the string
67 // table to be generated.
68 struct FileNameRegistryTy {
69 SmallVector<StringRef, 10> Filenames;
70 struct PerFileInfo {
71 size_t FilenameID, StartOffset;
72 };
73 StringMap<PerFileInfo> Infos;
74
75 // The offset in the string table where we'll write the next unique
76 // filename.
77 size_t LastOffset;
78
79 FileNameRegistryTy() {
80 clear();
81 }
82
83 // Add Filename to the registry, if it was not observed before.
84 void add(StringRef Filename) {
85 if (Infos.count(Filename))
86 return;
87 size_t OldSize = Infos.size();
88 Infos[Filename].FilenameID = OldSize;
89 Infos[Filename].StartOffset = LastOffset;
90 LastOffset += Filename.size() + 1;
91 Filenames.push_back(Filename);
92 }
93
94 void clear() {
95 LastOffset = 1;
96 Infos.clear();
97 Filenames.clear();
98 }
99 } FileNameRegistry;
100
101 typedef std::map<std::pair<StringRef, StringRef>, char *>
102 DirAndFilenameToFilepathMapTy;
103 DirAndFilenameToFilepathMapTy DirAndFilenameToFilepathMap;
104 StringRef getFullFilepath(const MDNode *S);
105
106 void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF);
107
108 void clear() {
Craig Toppere73658d2014-04-28 04:05:08 +0000109 assert(CurFn == nullptr);
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000110 FileNameRegistry.clear();
111 InstrInfo.clear();
112 }
113
114 void emitDebugInfoForFunction(const Function *GV);
115
116public:
117 WinCodeViewLineTables(AsmPrinter *Asm);
118
Alexander Kornienkof817c1c2015-04-11 02:11:45 +0000119 ~WinCodeViewLineTables() override {
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000120 for (DirAndFilenameToFilepathMapTy::iterator
121 I = DirAndFilenameToFilepathMap.begin(),
122 E = DirAndFilenameToFilepathMap.end();
123 I != E; ++I)
124 free(I->second);
125 }
126
Craig Topper7b883b32014-03-08 06:31:39 +0000127 void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {}
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000128
129 /// \brief Emit the COFF section that holds the line table information.
Craig Topper7b883b32014-03-08 06:31:39 +0000130 void endModule() override;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000131
132 /// \brief Gather pre-function debug information.
Craig Topper7b883b32014-03-08 06:31:39 +0000133 void beginFunction(const MachineFunction *MF) override;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000134
135 /// \brief Gather post-function debug information.
Craig Topper7b883b32014-03-08 06:31:39 +0000136 void endFunction(const MachineFunction *) override;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000137
138 /// \brief Process beginning of an instruction.
Craig Topper7b883b32014-03-08 06:31:39 +0000139 void beginInstruction(const MachineInstr *MI) override;
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000140
141 /// \brief Process end of an instruction.
Craig Topper7b883b32014-03-08 06:31:39 +0000142 void endInstruction() override {}
Timur Iskhodzhanovf166f6c2014-01-30 01:39:17 +0000143};
144} // End of namespace llvm
145
146#endif