1 //===-- 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 
14 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H
15 #define LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H
16 
17 #include "AsmPrinterHandler.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/StringMap.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/CodeGen/AsmPrinter.h"
22 #include "llvm/CodeGen/LexicalScopes.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineModuleInfo.h"
25 #include "llvm/IR/DebugInfo.h"
26 #include "llvm/IR/DebugLoc.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/Target/TargetLoweringObjectFile.h"
29 
30 namespace llvm {
31 /// \brief Collects and handles line tables information in a CodeView format.
32 class WinCodeViewLineTables : public AsmPrinterHandler {
33   AsmPrinter *Asm;
34   DebugLoc PrevInstLoc;
35 
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;
FunctionInfoFunctionInfo41     FunctionInfo() : End(nullptr) {}
42   } *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;
55 
InstrInfoTyInstrInfoTy56     InstrInfoTy() : LineNumber(0) {}
57 
InstrInfoTyInstrInfoTy58     InstrInfoTy(StringRef Filename, unsigned LineNumber)
59         : Filename(Filename), LineNumber(LineNumber) {}
60   };
61   DenseMap<MCSymbol *, InstrInfoTy> InstrInfo;
62 
63   // FileNameRegistry - Manages filenames observed while generating debug info
64   // by filtering out duplicates and bookkeeping the offsets in the string
65   // table to be generated.
66   struct FileNameRegistryTy {
67     SmallVector<StringRef, 10> Filenames;
68     struct PerFileInfo {
69       size_t FilenameID, StartOffset;
70     };
71     StringMap<PerFileInfo> Infos;
72 
73     // The offset in the string table where we'll write the next unique
74     // filename.
75     size_t LastOffset;
76 
FileNameRegistryTyFileNameRegistryTy77     FileNameRegistryTy() {
78       clear();
79     }
80 
81     // Add Filename to the registry, if it was not observed before.
addFileNameRegistryTy82     void add(StringRef Filename) {
83       if (Infos.count(Filename))
84         return;
85       size_t OldSize = Infos.size();
86       Infos[Filename].FilenameID = OldSize;
87       Infos[Filename].StartOffset = LastOffset;
88       LastOffset += Filename.size() + 1;
89       Filenames.push_back(Filename);
90     }
91 
clearFileNameRegistryTy92     void clear() {
93       LastOffset = 1;
94       Infos.clear();
95       Filenames.clear();
96     }
97   } FileNameRegistry;
98 
99   typedef std::map<std::pair<StringRef, StringRef>, char *>
100       DirAndFilenameToFilepathMapTy;
101   DirAndFilenameToFilepathMapTy DirAndFilenameToFilepathMap;
102   StringRef getFullFilepath(const MDNode *S);
103 
104   void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF);
105 
clear()106   void clear() {
107     assert(CurFn == nullptr);
108     FileNameRegistry.clear();
109     InstrInfo.clear();
110   }
111 
112   void emitDebugInfoForFunction(const Function *GV);
113 
114 public:
115   WinCodeViewLineTables(AsmPrinter *Asm);
116 
~WinCodeViewLineTables()117   ~WinCodeViewLineTables() override {
118     for (DirAndFilenameToFilepathMapTy::iterator
119              I = DirAndFilenameToFilepathMap.begin(),
120              E = DirAndFilenameToFilepathMap.end();
121          I != E; ++I)
122       free(I->second);
123   }
124 
setSymbolSize(const llvm::MCSymbol *,uint64_t)125   void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {}
126 
127   /// \brief Emit the COFF section that holds the line table information.
128   void endModule() override;
129 
130   /// \brief Gather pre-function debug information.
131   void beginFunction(const MachineFunction *MF) override;
132 
133   /// \brief Gather post-function debug information.
134   void endFunction(const MachineFunction *) override;
135 
136   /// \brief Process beginning of an instruction.
137   void beginInstruction(const MachineInstr *MI) override;
138 
139   /// \brief Process end of an instruction.
endInstruction()140   void endInstruction() override {}
141 };
142 } // End of namespace llvm
143 
144 #endif
145