136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===-- llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h ----*- C++ -*--===//
236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//                     The LLVM Compiler Infrastructure
436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source
636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details.
736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file contains support for writing line tables info into COFF files.
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifndef CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H__
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H__
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "AsmPrinterHandler.h"
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/DenseMap.h"
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/StringMap.h"
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/StringRef.h"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/AsmPrinter.h"
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/LexicalScopes.h"
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineFunction.h"
2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineModuleInfo.h"
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugInfo.h"
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugLoc.h"
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCStreamer.h"
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Target/TargetLoweringObjectFile.h"
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm {
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Collects and handles line tables information in a CodeView format.
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass WinCodeViewLineTables : public AsmPrinterHandler {
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  AsmPrinter *Asm;
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DebugLoc PrevInstLoc;
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // For each function, store a vector of labels to its instructions, as well as
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // to the end of the function.
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct FunctionInfo {
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SmallVector<MCSymbol *, 10> Instrs;
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MCSymbol *End;
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    FunctionInfo() : End(nullptr) {}
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } *CurFn;
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  typedef DenseMap<const Function *, FunctionInfo> FnDebugInfoTy;
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FnDebugInfoTy FnDebugInfo;
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Store the functions we've visited in a vector so we can maintain a stable
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // order while emitting subsections.
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<const Function *, 10> VisitedFunctions;
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // InstrInfoTy - Holds the Filename:LineNumber information for every
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // instruction with a unique debug location.
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct InstrInfoTy {
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StringRef Filename;
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned LineNumber;
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    InstrInfoTy() : LineNumber(0) {}
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    InstrInfoTy(StringRef Filename, unsigned LineNumber)
5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        : Filename(Filename), LineNumber(LineNumber) {}
6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DenseMap<MCSymbol *, InstrInfoTy> InstrInfo;
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FileNameRegistry - Manages filenames observed while generating debug info
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // by filtering out duplicates and bookkeeping the offsets in the string
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // table to be generated.
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct FileNameRegistryTy {
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SmallVector<StringRef, 10> Filenames;
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    struct PerFileInfo {
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      size_t FilenameID, StartOffset;
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    };
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StringMap<PerFileInfo> Infos;
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // The offset in the string table where we'll write the next unique
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // filename.
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    size_t LastOffset;
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    FileNameRegistryTy() {
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      clear();
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Add Filename to the registry, if it was not observed before.
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void add(StringRef Filename) {
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Infos.count(Filename))
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return;
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      size_t OldSize = Infos.size();
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Infos[Filename].FilenameID = OldSize;
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Infos[Filename].StartOffset = LastOffset;
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      LastOffset += Filename.size() + 1;
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Filenames.push_back(Filename);
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void clear() {
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      LastOffset = 1;
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Infos.clear();
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Filenames.clear();
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } FileNameRegistry;
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  typedef std::map<std::pair<StringRef, StringRef>, char *>
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DirAndFilenameToFilepathMapTy;
10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DirAndFilenameToFilepathMapTy DirAndFilenameToFilepathMap;
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef getFullFilepath(const MDNode *S);
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF);
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void clear() {
107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(CurFn == nullptr);
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    FileNameRegistry.clear();
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    InstrInfo.clear();
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitDebugInfoForFunction(const Function *GV);
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  WinCodeViewLineTables(AsmPrinter *Asm);
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ~WinCodeViewLineTables() {
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (DirAndFilenameToFilepathMapTy::iterator
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             I = DirAndFilenameToFilepathMap.begin(),
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             E = DirAndFilenameToFilepathMap.end();
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         I != E; ++I)
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      free(I->second);
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {}
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Emit the COFF section that holds the line table information.
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void endModule() override;
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Gather pre-function debug information.
13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void beginFunction(const MachineFunction *MF) override;
13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Gather post-function debug information.
13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void endFunction(const MachineFunction *) override;
13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Process beginning of an instruction.
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void beginInstruction(const MachineInstr *MI) override;
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Process end of an instruction.
14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void endInstruction() override {}
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines};
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // End of namespace llvm
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif
145