WinCodeViewLineTables.h revision 280031
1204431Sraj//===-- llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h ----*- C++ -*--===//
2204431Sraj//
3204431Sraj//                     The LLVM Compiler Infrastructure
4204431Sraj//
5204431Sraj// This file is distributed under the University of Illinois Open Source
6204431Sraj// License. See LICENSE.TXT for details.
7204431Sraj//
8204431Sraj//===----------------------------------------------------------------------===//
9204431Sraj//
10204431Sraj// This file contains support for writing line tables info into COFF files.
11204431Sraj//
12204431Sraj//===----------------------------------------------------------------------===//
13204431Sraj
14204431Sraj#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H
15204431Sraj#define LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H
16204431Sraj
17204431Sraj#include "AsmPrinterHandler.h"
18204431Sraj#include "llvm/ADT/DenseMap.h"
19204431Sraj#include "llvm/ADT/StringMap.h"
20204431Sraj#include "llvm/ADT/StringRef.h"
21204431Sraj#include "llvm/CodeGen/AsmPrinter.h"
22204431Sraj#include "llvm/CodeGen/LexicalScopes.h"
23204431Sraj#include "llvm/CodeGen/MachineFunction.h"
24204431Sraj#include "llvm/CodeGen/MachineModuleInfo.h"
25204431Sraj#include "llvm/IR/DebugInfo.h"
26204431Sraj#include "llvm/IR/DebugLoc.h"
27238742Simp#include "llvm/MC/MCStreamer.h"
28204431Sraj#include "llvm/Target/TargetLoweringObjectFile.h"
29238742Simp
30238742Simpnamespace llvm {
31238742Simp/// \brief Collects and handles line tables information in a CodeView format.
32238742Simpclass WinCodeViewLineTables : public AsmPrinterHandler {
33238742Simp  AsmPrinter *Asm;
34238742Simp  DebugLoc PrevInstLoc;
35238742Simp
36238742Simp  // For each function, store a vector of labels to its instructions, as well as
37238742Simp  // to the end of the function.
38238742Simp  struct FunctionInfo {
39238742Simp    SmallVector<MCSymbol *, 10> Instrs;
40238742Simp    MCSymbol *End;
41238742Simp    FunctionInfo() : End(nullptr) {}
42238742Simp  } *CurFn;
43238742Simp
44204431Sraj  typedef DenseMap<const Function *, FunctionInfo> FnDebugInfoTy;
45204431Sraj  FnDebugInfoTy FnDebugInfo;
46238742Simp  // Store the functions we've visited in a vector so we can maintain a stable
47238742Simp  // order while emitting subsections.
48204431Sraj  SmallVector<const Function *, 10> VisitedFunctions;
49204431Sraj
50204431Sraj  // InstrInfoTy - Holds the Filename:LineNumber information for every
51204431Sraj  // instruction with a unique debug location.
52204431Sraj  struct InstrInfoTy {
53204431Sraj    StringRef Filename;
54204431Sraj    unsigned LineNumber;
55204431Sraj
56204431Sraj    InstrInfoTy() : LineNumber(0) {}
57204431Sraj
58204431Sraj    InstrInfoTy(StringRef Filename, unsigned LineNumber)
59204431Sraj        : Filename(Filename), LineNumber(LineNumber) {}
60204431Sraj  };
61204431Sraj  DenseMap<MCSymbol *, InstrInfoTy> InstrInfo;
62204431Sraj
63204431Sraj  // FileNameRegistry - Manages filenames observed while generating debug info
64204431Sraj  // by filtering out duplicates and bookkeeping the offsets in the string
65204431Sraj  // table to be generated.
66204431Sraj  struct FileNameRegistryTy {
67204431Sraj    SmallVector<StringRef, 10> Filenames;
68204431Sraj    struct PerFileInfo {
69204431Sraj      size_t FilenameID, StartOffset;
70204431Sraj    };
71204431Sraj    StringMap<PerFileInfo> Infos;
72204431Sraj
73204431Sraj    // The offset in the string table where we'll write the next unique
74204431Sraj    // filename.
75204431Sraj    size_t LastOffset;
76204431Sraj
77204431Sraj    FileNameRegistryTy() {
78204431Sraj      clear();
79204431Sraj    }
80204431Sraj
81204431Sraj    // Add Filename to the registry, if it was not observed before.
82204431Sraj    void add(StringRef Filename) {
83204431Sraj      if (Infos.count(Filename))
84204431Sraj        return;
85204431Sraj      size_t OldSize = Infos.size();
86204431Sraj      Infos[Filename].FilenameID = OldSize;
87204431Sraj      Infos[Filename].StartOffset = LastOffset;
88204431Sraj      LastOffset += Filename.size() + 1;
89204431Sraj      Filenames.push_back(Filename);
90204431Sraj    }
91204431Sraj
92204431Sraj    void clear() {
93204431Sraj      LastOffset = 1;
94238742Simp      Infos.clear();
95204431Sraj      Filenames.clear();
96204431Sraj    }
97204431Sraj  } FileNameRegistry;
98204431Sraj
99204431Sraj  typedef std::map<std::pair<StringRef, StringRef>, char *>
100204431Sraj      DirAndFilenameToFilepathMapTy;
101204431Sraj  DirAndFilenameToFilepathMapTy DirAndFilenameToFilepathMap;
102204431Sraj  StringRef getFullFilepath(const MDNode *S);
103238742Simp
104238742Simp  void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF);
105238742Simp
106238742Simp  void clear() {
107238742Simp    assert(CurFn == nullptr);
108238742Simp    FileNameRegistry.clear();
109238742Simp    InstrInfo.clear();
110238742Simp  }
111238742Simp
112238742Simp  void emitDebugInfoForFunction(const Function *GV);
113238742Simp
114238742Simppublic:
115238742Simp  WinCodeViewLineTables(AsmPrinter *Asm);
116238742Simp
117238742Simp  ~WinCodeViewLineTables() {
118238742Simp    for (DirAndFilenameToFilepathMapTy::iterator
119238742Simp             I = DirAndFilenameToFilepathMap.begin(),
120238742Simp             E = DirAndFilenameToFilepathMap.end();
121238742Simp         I != E; ++I)
122238742Simp      free(I->second);
123238742Simp  }
124238742Simp
125238742Simp  void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {}
126238742Simp
127238742Simp  /// \brief Emit the COFF section that holds the line table information.
128238742Simp  void endModule() override;
129238742Simp
130238742Simp  /// \brief Gather pre-function debug information.
131238742Simp  void beginFunction(const MachineFunction *MF) override;
132238742Simp
133238742Simp  /// \brief Gather post-function debug information.
134238742Simp  void endFunction(const MachineFunction *) override;
135238742Simp
136238742Simp  /// \brief Process beginning of an instruction.
137238742Simp  void beginInstruction(const MachineInstr *MI) override;
138238742Simp
139238742Simp  /// \brief Process end of an instruction.
140238742Simp  void endInstruction() override {}
141238742Simp};
142238742Simp} // End of namespace llvm
143238742Simp
144238742Simp#endif
145238742Simp