Home | History | Annotate | Download | only in AsmPrinter
      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 CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H__
     15 #define 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;
     41     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 
     56     InstrInfoTy() : LineNumber(0) {}
     57 
     58     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 
     77     FileNameRegistryTy() {
     78       clear();
     79     }
     80 
     81     // Add Filename to the registry, if it was not observed before.
     82     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 
     92     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 
    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 
    117   ~WinCodeViewLineTables() {
    118     for (DirAndFilenameToFilepathMapTy::iterator
    119              I = DirAndFilenameToFilepathMap.begin(),
    120              E = DirAndFilenameToFilepathMap.end();
    121          I != E; ++I)
    122       free(I->second);
    123   }
    124 
    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.
    140   void endInstruction() override {}
    141 };
    142 } // End of namespace llvm
    143 
    144 #endif
    145