1274955Ssvnmir//===-- llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h ----*- C++ -*--===//
2274955Ssvnmir//
3274955Ssvnmir//                     The LLVM Compiler Infrastructure
4274955Ssvnmir//
5274955Ssvnmir// This file is distributed under the University of Illinois Open Source
6274955Ssvnmir// License. See LICENSE.TXT for details.
7274955Ssvnmir//
8274955Ssvnmir//===----------------------------------------------------------------------===//
9274955Ssvnmir//
10274955Ssvnmir// This file contains support for writing line tables info into COFF files.
11274955Ssvnmir//
12274955Ssvnmir//===----------------------------------------------------------------------===//
13274955Ssvnmir
14280031Sdim#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H
15280031Sdim#define LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H
16274955Ssvnmir
17274955Ssvnmir#include "AsmPrinterHandler.h"
18274955Ssvnmir#include "llvm/ADT/DenseMap.h"
19274955Ssvnmir#include "llvm/ADT/StringMap.h"
20274955Ssvnmir#include "llvm/ADT/StringRef.h"
21274955Ssvnmir#include "llvm/CodeGen/AsmPrinter.h"
22274955Ssvnmir#include "llvm/CodeGen/LexicalScopes.h"
23274955Ssvnmir#include "llvm/CodeGen/MachineFunction.h"
24274955Ssvnmir#include "llvm/CodeGen/MachineModuleInfo.h"
25274955Ssvnmir#include "llvm/IR/DebugInfo.h"
26274955Ssvnmir#include "llvm/IR/DebugLoc.h"
27274955Ssvnmir#include "llvm/MC/MCStreamer.h"
28274955Ssvnmir#include "llvm/Target/TargetLoweringObjectFile.h"
29274955Ssvnmir
30274955Ssvnmirnamespace llvm {
31274955Ssvnmir/// \brief Collects and handles line tables information in a CodeView format.
32288943Sdimclass LLVM_LIBRARY_VISIBILITY WinCodeViewLineTables : public AsmPrinterHandler {
33274955Ssvnmir  AsmPrinter *Asm;
34274955Ssvnmir  DebugLoc PrevInstLoc;
35274955Ssvnmir
36274955Ssvnmir  // For each function, store a vector of labels to its instructions, as well as
37274955Ssvnmir  // to the end of the function.
38274955Ssvnmir  struct FunctionInfo {
39274955Ssvnmir    SmallVector<MCSymbol *, 10> Instrs;
40274955Ssvnmir    MCSymbol *End;
41274955Ssvnmir    FunctionInfo() : End(nullptr) {}
42274955Ssvnmir  } *CurFn;
43274955Ssvnmir
44274955Ssvnmir  typedef DenseMap<const Function *, FunctionInfo> FnDebugInfoTy;
45274955Ssvnmir  FnDebugInfoTy FnDebugInfo;
46274955Ssvnmir  // Store the functions we've visited in a vector so we can maintain a stable
47274955Ssvnmir  // order while emitting subsections.
48274955Ssvnmir  SmallVector<const Function *, 10> VisitedFunctions;
49274955Ssvnmir
50274955Ssvnmir  // InstrInfoTy - Holds the Filename:LineNumber information for every
51274955Ssvnmir  // instruction with a unique debug location.
52274955Ssvnmir  struct InstrInfoTy {
53274955Ssvnmir    StringRef Filename;
54274955Ssvnmir    unsigned LineNumber;
55288943Sdim    unsigned ColumnNumber;
56274955Ssvnmir
57288943Sdim    InstrInfoTy() : LineNumber(0), ColumnNumber(0) {}
58274955Ssvnmir
59288943Sdim    InstrInfoTy(StringRef Filename, unsigned LineNumber, unsigned ColumnNumber)
60288943Sdim        : Filename(Filename), LineNumber(LineNumber),
61288943Sdim          ColumnNumber(ColumnNumber) {}
62274955Ssvnmir  };
63274955Ssvnmir  DenseMap<MCSymbol *, InstrInfoTy> InstrInfo;
64274955Ssvnmir
65274955Ssvnmir  // FileNameRegistry - Manages filenames observed while generating debug info
66274955Ssvnmir  // by filtering out duplicates and bookkeeping the offsets in the string
67274955Ssvnmir  // table to be generated.
68274955Ssvnmir  struct FileNameRegistryTy {
69274955Ssvnmir    SmallVector<StringRef, 10> Filenames;
70274955Ssvnmir    struct PerFileInfo {
71274955Ssvnmir      size_t FilenameID, StartOffset;
72274955Ssvnmir    };
73274955Ssvnmir    StringMap<PerFileInfo> Infos;
74274955Ssvnmir
75274955Ssvnmir    // The offset in the string table where we'll write the next unique
76274955Ssvnmir    // filename.
77274955Ssvnmir    size_t LastOffset;
78274955Ssvnmir
79274955Ssvnmir    FileNameRegistryTy() {
80274955Ssvnmir      clear();
81274955Ssvnmir    }
82274955Ssvnmir
83274955Ssvnmir    // Add Filename to the registry, if it was not observed before.
84274955Ssvnmir    void add(StringRef Filename) {
85274955Ssvnmir      if (Infos.count(Filename))
86274955Ssvnmir        return;
87274955Ssvnmir      size_t OldSize = Infos.size();
88274955Ssvnmir      Infos[Filename].FilenameID = OldSize;
89274955Ssvnmir      Infos[Filename].StartOffset = LastOffset;
90274955Ssvnmir      LastOffset += Filename.size() + 1;
91274955Ssvnmir      Filenames.push_back(Filename);
92274955Ssvnmir    }
93274955Ssvnmir
94274955Ssvnmir    void clear() {
95274955Ssvnmir      LastOffset = 1;
96274955Ssvnmir      Infos.clear();
97274955Ssvnmir      Filenames.clear();
98274955Ssvnmir    }
99274955Ssvnmir  } FileNameRegistry;
100274955Ssvnmir
101296417Sdim  typedef std::map<std::pair<StringRef, StringRef>, std::string>
102274955Ssvnmir      DirAndFilenameToFilepathMapTy;
103274955Ssvnmir  DirAndFilenameToFilepathMapTy DirAndFilenameToFilepathMap;
104274955Ssvnmir  StringRef getFullFilepath(const MDNode *S);
105274955Ssvnmir
106274955Ssvnmir  void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF);
107274955Ssvnmir
108274955Ssvnmir  void clear() {
109274955Ssvnmir    assert(CurFn == nullptr);
110274955Ssvnmir    FileNameRegistry.clear();
111274955Ssvnmir    InstrInfo.clear();
112274955Ssvnmir  }
113274955Ssvnmir
114274955Ssvnmir  void emitDebugInfoForFunction(const Function *GV);
115274955Ssvnmir
116274955Ssvnmirpublic:
117274955Ssvnmir  WinCodeViewLineTables(AsmPrinter *Asm);
118274955Ssvnmir
119274955Ssvnmir  void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {}
120274955Ssvnmir
121274955Ssvnmir  /// \brief Emit the COFF section that holds the line table information.
122274955Ssvnmir  void endModule() override;
123274955Ssvnmir
124274955Ssvnmir  /// \brief Gather pre-function debug information.
125274955Ssvnmir  void beginFunction(const MachineFunction *MF) override;
126274955Ssvnmir
127274955Ssvnmir  /// \brief Gather post-function debug information.
128274955Ssvnmir  void endFunction(const MachineFunction *) override;
129274955Ssvnmir
130274955Ssvnmir  /// \brief Process beginning of an instruction.
131274955Ssvnmir  void beginInstruction(const MachineInstr *MI) override;
132274955Ssvnmir
133274955Ssvnmir  /// \brief Process end of an instruction.
134274955Ssvnmir  void endInstruction() override {}
135274955Ssvnmir};
136274955Ssvnmir} // End of namespace llvm
137274955Ssvnmir
138274955Ssvnmir#endif
139