Skip to content
DwarfDebug.cpp 99 KiB
Newer Older
//===-- llvm/CodeGen/DwarfDebug.cpp - Dwarf Debug Framework ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing dwarf debug info into asm files.
//
//===----------------------------------------------------------------------===//
Devang Patel's avatar
Devang Patel committed
#define DEBUG_TYPE "dwarfdebug"
#include "DwarfDebug.h"
#include "llvm/Module.h"
David Greene's avatar
 
David Greene committed
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/StringExtras.h"
Daniel Dunbar's avatar
Daniel Dunbar committed
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/Timer.h"
#include "llvm/System/Path.h"
using namespace llvm;

//===----------------------------------------------------------------------===//

/// Configuration values for initial hash set sizes (log2).
///
static const unsigned InitAbbreviationsSetSize = 9; // log2(512)

namespace llvm {

//===----------------------------------------------------------------------===//
/// CompileUnit - This dwarf writer support class manages information associate
/// with a source file.
Nick Lewycky's avatar
Nick Lewycky committed
class CompileUnit {
  /// ID - File identifier for source.
  ///
  unsigned ID;

  /// Die - Compile unit debug information entry.
  ///
  /// IndexTyDie - An anonymous type for index type.
  DIE *IndexTyDie;

  /// GVToDieMap - Tracks the mapping of unit level debug informaton
  /// variables to debug information entries.
Devang Patel's avatar
Devang Patel committed
  /// FIXME : Rename GVToDieMap -> NodeToDieMap
  ValueMap<MDNode *, DIE *> GVToDieMap;

  /// GVToDIEEntryMap - Tracks the mapping of unit level debug informaton
  /// descriptors to debug information entries using a DIEEntry proxy.
Devang Patel's avatar
Devang Patel committed
  /// FIXME : Rename
  ValueMap<MDNode *, DIEEntry *> GVToDIEEntryMap;

  /// Globals - A map of globally visible named entities for this unit.
  ///
  StringMap<DIE*> Globals;

Devang Patel's avatar
Devang Patel committed
  /// GlobalTypes - A map of globally visible types for this unit.
  ///
  StringMap<DIE*> GlobalTypes;

public:
  CompileUnit(unsigned I, DIE *D)
    : ID(I), CUDie(D), IndexTyDie(0) {}
  ~CompileUnit() { delete CUDie; delete IndexTyDie; }
Devang Patel's avatar
Devang Patel committed
  unsigned getID()                  const { return ID; }
  DIE* getCUDie()                   const { return CUDie; }
  const StringMap<DIE*> &getGlobals()     const { return Globals; }
  const StringMap<DIE*> &getGlobalTypes() const { return GlobalTypes; }

  /// hasContent - Return true if this compile unit has something to write out.
  ///
  bool hasContent() const { return !CUDie->getChildren().empty(); }
  /// addGlobal - Add a new global entity to the compile unit.
  void addGlobal(const std::string &Name, DIE *Die) { Globals[Name] = Die; }
Devang Patel's avatar
Devang Patel committed
  /// addGlobalType - Add a new global type to the compile unit.
  ///
  void addGlobalType(const std::string &Name, DIE *Die) { 
    GlobalTypes[Name] = Die; 
  }

  /// getDIE - Returns the debug information entry map slot for the
  /// specified debug variable.
  DIE *getDIE(MDNode *N) { return GVToDieMap.lookup(N); }
  /// insertDIE - Insert DIE into the map.
  void insertDIE(MDNode *N, DIE *D) {
    GVToDieMap.insert(std::make_pair(N, D));
  }

  /// getDIEEntry - Returns the debug information entry for the speciefied
  /// debug variable.
  DIEEntry *getDIEEntry(MDNode *N) { 
    ValueMap<MDNode *, DIEEntry *>::iterator I = GVToDIEEntryMap.find(N);
    if (I == GVToDIEEntryMap.end())
      return NULL;
    return I->second;
  }
  /// insertDIEEntry - Insert debug information entry into the map.
  void insertDIEEntry(MDNode *N, DIEEntry *E) {
    GVToDIEEntryMap.insert(std::make_pair(N, E));
  /// addDie - Adds or interns the DIE to the compile unit.
  void addDie(DIE *Buffer) {
    this->CUDie->addChild(Buffer);
  // getIndexTyDie - Get an anonymous type for index type.
  DIE *getIndexTyDie() {
    return IndexTyDie;
Jim Grosbach's avatar
Jim Grosbach committed
  // setIndexTyDie - Set D as anonymous type for index which can be reused
  // later.
  void setIndexTyDie(DIE *D) {
    IndexTyDie = D;
  }

};

//===----------------------------------------------------------------------===//
/// DbgVariable - This class is used to track local variable information.
///
Devang Patel's avatar
Devang Patel committed
class DbgVariable {
  DIVariable Var;                    // Variable Descriptor.
  unsigned FrameIndex;               // Variable frame index.
  DbgVariable *AbstractVar;          // Abstract variable for this variable.
  DIE *TheDIE;
  DbgVariable(DIVariable V, unsigned I)
    : Var(V), FrameIndex(I), AbstractVar(0), TheDIE(0)  {}
  DIVariable getVariable()           const { return Var; }
  unsigned getFrameIndex()           const { return FrameIndex; }
  void setAbstractVariable(DbgVariable *V) { AbstractVar = V; }
  DbgVariable *getAbstractVariable() const { return AbstractVar; }
  void setDIE(DIE *D)                      { TheDIE = D; }
  DIE *getDIE()                      const { return TheDIE; }
};

//===----------------------------------------------------------------------===//
/// DbgScope - This class is used to track scope information.
///
Devang Patel's avatar
Devang Patel committed
class DbgScope {
  DbgScope *Parent;                   // Parent to this scope.
Jim Grosbach's avatar
Jim Grosbach committed
  DIDescriptor Desc;                  // Debug info descriptor for scope.
  WeakVH InlinedAtLocation;           // Location at which scope is inlined.
  bool AbstractScope;                 // Abstract Scope
  unsigned StartLabelID;              // Label ID of the beginning of scope.
  unsigned EndLabelID;                // Label ID of the end of scope.
  const MachineInstr *LastInsn;       // Last instruction of this scope.
  const MachineInstr *FirstInsn;      // First instruction of this scope.
  SmallVector<DbgScope *, 4> Scopes;  // Scopes defined in scope.
  SmallVector<DbgVariable *, 8> Variables;// Variables declared in scope.
Owen Anderson's avatar
Owen Anderson committed
  // Private state for dump()
  mutable unsigned IndentLevel;
  DbgScope(DbgScope *P, DIDescriptor D, MDNode *I = 0)
    : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false),
Jim Grosbach's avatar
Jim Grosbach committed
      StartLabelID(0), EndLabelID(0),
      LastInsn(0), FirstInsn(0), IndentLevel(0) {}
  virtual ~DbgScope();

  // Accessors.
  DbgScope *getParent()          const { return Parent; }
  void setParent(DbgScope *P)          { Parent = P; }
  DIDescriptor getDesc()         const { return Desc; }
Jim Grosbach's avatar
Jim Grosbach committed
  MDNode *getInlinedAt()         const {
    return dyn_cast_or_null<MDNode>(InlinedAtLocation);
  MDNode *getScopeNode()         const { return Desc.getNode(); }
  unsigned getStartLabelID()     const { return StartLabelID; }
  unsigned getEndLabelID()       const { return EndLabelID; }
  SmallVector<DbgScope *, 4> &getScopes() { return Scopes; }
  SmallVector<DbgVariable *, 8> &getVariables() { return Variables; }
  void setStartLabelID(unsigned S) { StartLabelID = S; }
  void setEndLabelID(unsigned E)   { EndLabelID = E; }
  void setLastInsn(const MachineInstr *MI) { LastInsn = MI; }
Loading
Loading full blame...