Reland 196270 "Generalize debug info / EH emission in AsmPrinter"
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DwarfDebug.h
index 7405fe12a97b19a3ccba40100554ba265fbaf905..2931eca4bc40f89bee7fb4da0c887d3d1e65f704 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef CODEGEN_ASMPRINTER_DWARFDEBUG_H__
 #define CODEGEN_ASMPRINTER_DWARFDEBUG_H__
 
+#include "AsmPrinterHandler.h"
 #include "DIE.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -29,6 +30,7 @@
 
 namespace llvm {
 
+class Unit;
 class CompileUnit;
 class ConstantInt;
 class ConstantFP;
@@ -37,6 +39,7 @@ class MachineFrameInfo;
 class MachineModuleInfo;
 class MachineOperand;
 class MCAsmInfo;
+class MCObjectFileInfo;
 class DIEAbbrev;
 class DIE;
 class DIEBlock;
@@ -209,6 +212,11 @@ public:
     return Var.getAddrElement(i);
   }
   DIType getType() const;
+
+private:
+  /// resolve - Look in the DwarfDebug map for the MDNode that
+  /// corresponds to the reference.
+  template <typename T> T resolve(DIRef<T> Ref) const;
 };
 
 /// \brief Collects and handles information specific to a particular
@@ -221,10 +229,10 @@ class DwarfUnits {
   FoldingSet<DIEAbbrev> *AbbreviationsSet;
 
   // A list of all the unique abbreviations in use.
-  std::vector<DIEAbbrev *> *Abbreviations;
+  std::vector<DIEAbbrev *> &Abbreviations;
 
   // A pointer to all units in the section.
-  SmallVector<CompileUnit *, 1> CUs;
+  SmallVector<Unit *, 1> CUs;
 
   // Collection of strings for this unit and assorted symbols.
   // A String->Symbol mapping of strings used by indirect
@@ -244,12 +252,16 @@ class DwarfUnits {
 
 public:
   DwarfUnits(AsmPrinter *AP, FoldingSet<DIEAbbrev> *AS,
-             std::vector<DIEAbbrev *> *A, const char *Pref,
+             std::vector<DIEAbbrev *> &A, const char *Pref,
              BumpPtrAllocator &DA)
       : Asm(AP), AbbreviationsSet(AS), Abbreviations(A), StringPool(DA),
         NextStringPoolNumber(0), StringPref(Pref), AddressPool(),
         NextAddrPoolNumber(0) {}
 
+  ~DwarfUnits();
+
+  const SmallVectorImpl<Unit *> &getUnits() { return CUs; }
+
   /// \brief Compute the size and offset of a DIE given an incoming Offset.
   unsigned computeSizeAndOffset(DIE *Die, unsigned Offset);
 
@@ -260,7 +272,7 @@ public:
   void assignAbbrevNumber(DIEAbbrev &Abbrev);
 
   /// \brief Add a unit to the list of CUs.
-  void addUnit(CompileUnit *CU) { CUs.push_back(CU); }
+  void addUnit(Unit *CU) { CUs.push_back(CU); }
 
   /// \brief Emit all of the units to the section listed with the given
   /// abbreviation section.
@@ -295,20 +307,17 @@ public:
 
   /// \brief Returns the address pool.
   AddrPool *getAddrPool() { return &AddressPool; }
-
-  /// \brief for a given compile unit DIE, returns offset from beginning of
-  /// debug info.
-  unsigned getCUOffset(DIE *Die);
 };
 
-/// \brief Helper used to pair up a symbol and it's DWARF compile unit.
+/// \brief Helper used to pair up a symbol and its DWARF compile unit.
 struct SymbolCU {
+  SymbolCU(CompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {}
   const MCSymbol *Sym;
   CompileUnit *CU;
 };
 
 /// \brief Collects and handles dwarf debug information.
-class DwarfDebug {
+class DwarfDebug : public AsmPrinterHandler {
   // Target of Dwarf emission.
   AsmPrinter *Asm;
 
@@ -327,29 +336,13 @@ class DwarfDebug {
   // Maps subprogram MDNode with its corresponding CompileUnit.
   DenseMap <const MDNode *, CompileUnit *> SPMap;
 
-  /// Maps type MDNode with its corresponding DIE. These DIEs can be
-  /// shared across CUs, that is why we keep the map here instead
+  // Maps a CU DIE with its corresponding CompileUnit.
+  DenseMap <const DIE *, CompileUnit *> CUDieMap;
+
+  /// Maps MDNodes for type sysstem with the corresponding DIEs. These DIEs can
+  /// be shared across CUs, that is why we keep the map here instead
   /// of in CompileUnit.
   DenseMap<const MDNode *, DIE *> MDTypeNodeToDieMap;
-  /// Maps subprogram MDNode with its corresponding DIE.
-  DenseMap<const MDNode *, DIE *> MDSPNodeToDieMap;
-  /// Maps static member MDNode with its corresponding DIE.
-  DenseMap<const MDNode *, DIE *> MDStaticMemberNodeToDieMap;
-
-  /// Specifies a worklist item. Sometimes, when we try to add an attribute to
-  /// a DIE, the DIE is not yet added to its owner yet, so we don't know whether
-  /// we should use ref_addr or ref4. We create a worklist that will be
-  /// processed during finalization to add attributes with the correct form
-  /// (ref_addr or ref4).
-  struct DIEEntryWorkItem {
-    DIE *Die;
-    uint16_t Attribute;
-    DIEEntry *Entry;
-    DIEEntryWorkItem(DIE *D, uint16_t A, DIEEntry *E) :
-      Die(D), Attribute(A), Entry(E) {
-    }
-  };
-  SmallVector<DIEEntryWorkItem, 64> DIEEntryWorklist;
 
   // Used to uniquely define abbreviations.
   FoldingSet<DIEAbbrev> AbbreviationsSet;
@@ -363,8 +356,8 @@ class DwarfDebug {
   // separated by a zero byte, mapped to a unique id.
   StringMap<unsigned, BumpPtrAllocator&> SourceIdMap;
 
-  // List of all labels used in the output.
-  std::vector<SymbolCU> Labels;
+  // List of all labels used in aranges generation.
+  std::vector<SymbolCU> ArangeLabels;
 
   // Size of each symbol emitted (for those symbols that have a specific size).
   DenseMap <const MCSymbol *, uint64_t> SymSize;
@@ -417,8 +410,6 @@ class DwarfDebug {
     DbgValueHistoryMap;
   DbgValueHistoryMap DbgValues;
 
-  SmallVector<const MCSymbol *, 8> DebugRangeSymbols;
-
   // Previous instruction's location information. This is used to determine
   // label location to indicate scope boundries in dwarf debug info.
   DebugLoc PrevInstLoc;
@@ -428,6 +419,12 @@ class DwarfDebug {
   // body.
   DebugLoc PrologEndLoc;
 
+  // If nonnull, stores the current machine function we're processing.
+  const MachineFunction *CurFn;
+
+  // If nonnull, stores the current machine instruction we're processing.
+  const MachineInstr *CurMI;
+
   // Section Symbols: these are assembler temporary labels that are emitted at
   // the beginning of each supported dwarf section.  These are used to form
   // section offsets and are created by EmitSectionLabels.
@@ -445,22 +442,27 @@ class DwarfDebug {
   // Counter for assigning globally unique IDs for CUs.
   unsigned GlobalCUIndexCount;
 
+  // Counter for assigning globally unique IDs for ranges.
+  unsigned GlobalRangeCount;
+
   // Holder for the file specific debug information.
   DwarfUnits InfoHolder;
 
   // Holders for the various debug information flags that we might need to
   // have exposed. See accessor functions below for description.
 
-  // Whether or not we're emitting info for older versions of gdb on darwin.
-  bool IsDarwinGDBCompat;
-
   // Holder for imported entities.
   typedef SmallVector<std::pair<const MDNode *, const MDNode *>, 32>
     ImportedEntityMap;
   ImportedEntityMap ScopesWithImportedEntities;
 
-  // Holder for types that are going to be extracted out into a type unit.
-  std::vector<DIE *> TypeUnits;
+  // Map from type MDNodes to a pair used as a union. If the pointer is
+  // non-null, proxy DIEs in CUs meant to reference this type should be stored
+  // in the vector. The hash will be added to these DIEs once it is computed. If
+  // the pointer is null, the hash is immediately available in the uint64_t and
+  // should be directly used for proxy DIEs.
+  DenseMap<const MDNode *, std::pair<uint64_t, SmallVectorImpl<DIE *> *> >
+  TypeUnits;
 
   // Whether to emit the pubnames/pubtypes sections.
   bool HasDwarfPubSections;
@@ -468,6 +470,9 @@ class DwarfDebug {
   // Version of dwarf we're emitting.
   unsigned DwarfVersion;
 
+  // Maps from a type identifier to the actual MDNode.
+  DITypeIdentifierMap TypeIdentifierMap;
+
   // DWARF5 Experimental Options
   bool HasDwarfAccelTables;
   bool HasSplitDwarf;
@@ -477,9 +482,6 @@ class DwarfDebug {
   // original object file, rather than things that are meant
   // to be in the .dwo sections.
 
-  // The CUs left in the original object file for separated debug info.
-  SmallVector<CompileUnit *, 1> SkeletonCUs;
-
   // Used to uniquely define abbreviations for the skeleton emission.
   FoldingSet<DIEAbbrev> SkeletonAbbrevSet;
 
@@ -489,13 +491,10 @@ class DwarfDebug {
   // Holder for the skeleton information.
   DwarfUnits SkeletonHolder;
 
-  // Maps from a type identifier to the actual MDNode.
-  DITypeIdentifierMap TypeIdentifierMap;
-
-private:
-
   void addScopeVariable(LexicalScope *LS, DbgVariable *Var);
 
+  const SmallVectorImpl<Unit *> &getUnits() { return InfoHolder.getUnits(); }
+
   /// \brief Find abstract variable associated with Var.
   DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc);
 
@@ -503,14 +502,20 @@ private:
   /// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global
   /// variables in this scope then create and insert DIEs for these
   /// variables.
-  DIE *updateSubprogramScopeDIE(CompileUnit *SPCU, const MDNode *SPNode);
+  DIE *updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP);
+
+  /// \brief A helper function to check whether the DIE for a given Scope is
+  /// going to be null.
+  bool isLexicalScopeDIENull(LexicalScope *Scope);
+
+  /// \brief A helper function to construct a RangeSpanList for a given
+  /// lexical scope.
+  void addScopeRangeList(CompileUnit *TheCU, DIE *ScopeDIE,
+                         const SmallVectorImpl<InsnRange> &Range);
 
   /// \brief Construct new DW_TAG_lexical_block for this scope and
   /// attach DW_AT_low_pc/DW_AT_high_pc labels.
   DIE *constructLexicalScopeDIE(CompileUnit *TheCU, LexicalScope *Scope);
-  /// A helper function to check whether the DIE for a given Scope is going
-  /// to be null.
-  bool isLexicalScopeDIENull(LexicalScope *Scope);
 
   /// \brief This scope represents inlined body of a function. Construct
   /// DIE to represent this concrete inlined copy of the function.
@@ -621,7 +626,7 @@ private:
 
   /// \brief Create new CompileUnit for the given metadata node with tag
   /// DW_TAG_compile_unit.
-  CompileUnit *constructCompileUnit(const MDNode *N);
+  CompileUnit *constructCompileUnit(DICompileUnit DIUnit);
 
   /// \brief Construct subprogram DIE.
   void constructSubprogramDIE(CompileUnit *TheCU, const MDNode *N);
@@ -650,17 +655,14 @@ private:
 
   /// \brief If Var is an current function argument that add it in
   /// CurrentFnArguments list.
-  bool addCurrentFnArgument(const MachineFunction *MF,
-                            DbgVariable *Var, LexicalScope *Scope);
+  bool addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope);
 
   /// \brief Populate LexicalScope entries with variables' info.
-  void collectVariableInfo(const MachineFunction *,
-                           SmallPtrSet<const MDNode *, 16> &ProcessedVars);
+  void collectVariableInfo(SmallPtrSet<const MDNode *, 16> &ProcessedVars);
 
   /// \brief Collect variable information from the side table maintained
   /// by MMI.
-  void collectVariableInfoFromMMITable(const MachineFunction * MF,
-                                       SmallPtrSet<const MDNode *, 16> &P);
+  void collectVariableInfoFromMMITable(SmallPtrSet<const MDNode *, 16> &P);
 
   /// \brief Ensure that a label will be emitted before MI.
   void requestLabelBeforeInsn(const MachineInstr *MI) {
@@ -683,29 +685,13 @@ public:
   // Main entry points.
   //
   DwarfDebug(AsmPrinter *A, Module *M);
-  ~DwarfDebug();
 
-  void insertTypeDIE(const MDNode *TypeMD, DIE *Die) {
+  void insertDIE(const MDNode *TypeMD, DIE *Die) {
     MDTypeNodeToDieMap.insert(std::make_pair(TypeMD, Die));
   }
-  DIE *getTypeDIE(const MDNode *TypeMD) {
+  DIE *getDIE(const MDNode *TypeMD) {
     return MDTypeNodeToDieMap.lookup(TypeMD);
   }
-  void insertSPDIE(const MDNode *SPMD, DIE *Die) {
-    MDSPNodeToDieMap.insert(std::make_pair(SPMD, Die));
-  }
-  DIE *getSPDIE(const MDNode *SPMD) {
-    return MDSPNodeToDieMap.lookup(SPMD);
-  }
-  void insertStaticMemberDIE(const MDNode *StaticMD, DIE *Die) {
-    MDStaticMemberNodeToDieMap.insert(std::make_pair(StaticMD, Die));
-  }
-  DIE *getStaticMemberDIE(const MDNode *StaticMD) {
-    return MDStaticMemberNodeToDieMap.lookup(StaticMD);
-  }
-  void insertDIEEntryWorklist(DIE *Die, uint16_t Attribute, DIEEntry *Entry) {
-    DIEEntryWorklist.push_back(DIEEntryWorkItem(Die, Attribute, Entry));
-  }
 
   /// \brief Emit all Dwarf sections that should come prior to the
   /// content.
@@ -724,14 +710,14 @@ public:
   void beginInstruction(const MachineInstr *MI);
 
   /// \brief Process end of an instruction.
-  void endInstruction(const MachineInstr *MI);
+  void endInstruction();
 
   /// \brief Add a DIE to the set of types that we're going to pull into
   /// type units.
-  void addTypeUnitType(DIE *Die) { TypeUnits.push_back(Die); }
+  void addTypeUnitType(uint16_t Language, DIE *Die, DICompositeType CTy);
 
   /// \brief Add a label so that arange data can be generated for it.
-  void addLabel(SymbolCU SCU) { Labels.push_back(SCU); }
+  void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(SCU); }
 
   /// \brief For symbols that have a size designated (e.g. common symbols),
   /// this tracks that size.
@@ -744,11 +730,7 @@ public:
                                unsigned CUID);
 
   /// \brief Recursively Emits a debug information entry.
-  void emitDIE(DIE *Die, std::vector<DIEAbbrev *> *Abbrevs);
-
-  /// \brief Returns whether or not to limit some of our debug
-  /// output to the limitations of darwin gdb.
-  bool useDarwinGDBCompat() { return IsDarwinGDBCompat; }
+  void emitDIE(DIE *Die, ArrayRef<DIEAbbrev *> Abbrevs);
 
   // Experimental DWARF5 features.
 
@@ -763,17 +745,11 @@ public:
   /// Returns the Dwarf Version.
   unsigned getDwarfVersion() const { return DwarfVersion; }
 
-  /// Find the MDNode for the given scope reference.
-  template <typename T>
-  T resolve(DIRef<T> Ref) const {
+  /// Find the MDNode for the given reference.
+  template <typename T> T resolve(DIRef<T> Ref) const {
     return Ref.resolve(TypeIdentifierMap);
   }
 
-  /// When we don't know whether the correct form is ref4 or ref_addr, we create
-  /// a worklist item and insert it to DIEEntryWorklist.
-  void addDIEEntry(DIE *Die, uint16_t Attribute, uint16_t Form,
-                   DIEEntry *Entry);
-
   /// isSubprogramContext - Return true if Context is either a subprogram
   /// or another context nested inside a subprogram.
   bool isSubprogramContext(const MDNode *Context);