1 //===-- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.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 Microsoft CodeView debug info.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
15 #define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_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 LLVM_LIBRARY_VISIBILITY CodeViewDebug : 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     DebugLoc LastLoc;
40     SmallVector<MCSymbol *, 10> Instrs;
41     MCSymbol *End;
42     FunctionInfo() : End(nullptr) {}
43   };
44   FunctionInfo *CurFn;
45 
46   typedef DenseMap<const Function *, FunctionInfo> FnDebugInfoTy;
47   FnDebugInfoTy FnDebugInfo;
48   // Store the functions we've visited in a vector so we can maintain a stable
49   // order while emitting subsections.
50   SmallVector<const Function *, 10> VisitedFunctions;
51 
52   DenseMap<MCSymbol *, DebugLoc> LabelsAndLocs;
53 
54   // FileNameRegistry - Manages filenames observed while generating debug info
55   // by filtering out duplicates and bookkeeping the offsets in the string
56   // table to be generated.
57   struct FileNameRegistryTy {
58     SmallVector<StringRef, 10> Filenames;
59     struct PerFileInfo {
60       size_t FilenameID, StartOffset;
61     };
62     StringMap<PerFileInfo> Infos;
63 
64     // The offset in the string table where we'll write the next unique
65     // filename.
66     size_t LastOffset;
67 
68     FileNameRegistryTy() {
69       clear();
70     }
71 
72     // Add Filename to the registry, if it was not observed before.
73     size_t add(StringRef Filename) {
74       size_t OldSize = Infos.size();
75       bool Inserted;
76       StringMap<PerFileInfo>::iterator It;
77       std::tie(It, Inserted) = Infos.insert(
78           std::make_pair(Filename, PerFileInfo{OldSize, LastOffset}));
79       if (Inserted) {
80         LastOffset += Filename.size() + 1;
81         Filenames.push_back(Filename);
82       }
83       return It->second.FilenameID;
84     }
85 
86     void clear() {
87       LastOffset = 1;
88       Infos.clear();
89       Filenames.clear();
90     }
91   } FileNameRegistry;
92 
93   typedef std::map<const DIFile *, std::string> FileToFilepathMapTy;
94   FileToFilepathMapTy FileToFilepathMap;
95   StringRef getFullFilepath(const DIFile *S);
96 
97   void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF);
98 
99   void clear() {
100     assert(CurFn == nullptr);
101     FileNameRegistry.clear();
102     LabelsAndLocs.clear();
103   }
104 
105   void emitDebugInfoForFunction(const Function *GV);
106 
107 public:
108   CodeViewDebug(AsmPrinter *Asm);
109 
110   void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {}
111 
112   /// \brief Emit the COFF section that holds the line table information.
113   void endModule() override;
114 
115   /// \brief Gather pre-function debug information.
116   void beginFunction(const MachineFunction *MF) override;
117 
118   /// \brief Gather post-function debug information.
119   void endFunction(const MachineFunction *) override;
120 
121   /// \brief Process beginning of an instruction.
122   void beginInstruction(const MachineInstr *MI) override;
123 
124   /// \brief Process end of an instruction.
125   void endInstruction() override {}
126 };
127 } // End of namespace llvm
128 
129 #endif
130