Skip to content
DwarfDebug.cpp 109 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/Target/Mangler.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/ValueHandle.h"
#include "llvm/Support/FormattedStream.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.  Owned by CUDie.
  /// 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

  /// 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
  DenseMap<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) {}
Devang Patel's avatar
Devang Patel committed
  unsigned getID()                  const { return ID; }
  DIE* getCUDie()                   const { return CUDie.get(); }
Devang Patel's avatar
Devang Patel committed
  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) { 
    DenseMap<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.
  // DbgValueLabel - DBG_VALUE is effective from this label.
  MCSymbol *DbgValueLabel;
  DbgVariable *const AbstractVar;    // Abstract variable for this variable.
  // AbsVar may be NULL.
  DbgVariable(DIVariable V, unsigned I, DbgVariable *AbsVar)
    : Var(V), FrameIndex(I), DbgValueMInsn(0), 
      DbgValueLabel(0), AbstractVar(AbsVar), TheDIE(0) {}
  DbgVariable(DIVariable V, const MachineInstr *MI, DbgVariable *AbsVar)
    : Var(V), FrameIndex(0), DbgValueMInsn(MI), DbgValueLabel(0),
      AbstractVar(AbsVar), TheDIE(0)
  DIVariable getVariable()           const { return Var; }
  unsigned getFrameIndex()           const { return FrameIndex; }
  const MachineInstr *getDbgValue()  const { return DbgValueMInsn; }
  MCSymbol *getDbgValueLabel()       const { return DbgValueLabel; }
  void setDbgValueLabel(MCSymbol *L)       { DbgValueLabel = L; }
  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.
  // Location at which this scope is inlined.
  AssertingVH<MDNode> InlinedAtLocation;  
  bool AbstractScope;                 // Abstract Scope
  MCSymbol *StartLabel;               // Label ID of the beginning of scope.
  MCSymbol *EndLabel;                 // Label ID of the end of scope.
  const MachineInstr *LastInsn;       // Last instruction of this scope.
  const MachineInstr *FirstInsn;      // First instruction of this scope.
  // Scopes defined in scope.  Contents not owned.
  SmallVector<DbgScope *, 4> Scopes;
  // Variables declared in scope.  Contents owned.
  SmallVector<DbgVariable *, 8> Variables;
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),
Loading
Loading full blame...