Skip to content
DwarfDebug.cpp 126 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"
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/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Analysis/DebugInfo.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"
static cl::opt<bool> PrintDbgScope("print-dbgscope", cl::Hidden,
     cl::desc("Print DbgScope information for each machine instruction"));

static cl::opt<bool> DisableDebugInfoPrinting("disable-debug-info-print",
Devang Patel's avatar
Devang Patel committed
                                              cl::Hidden,
static cl::opt<bool> UnknownLocations("use-unknown-locations", cl::Hidden,
     cl::desc("Make an absense of debug location information explicit."),
     cl::init(false));

STATISTIC(BlocksWithoutLineNo, "Number of blocks without any line number");
namespace {
  const char *DWARFGroupName = "DWARF Emission";
  const char *DbgTimerName = "DWARF Debug Writer";
} // end anonymous namespace

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

/// 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.
Devang Patel's avatar
Devang Patel committed
  /// MDNodeToDieMap - Tracks the mapping of unit level debug informaton
  /// variables to debug information entries.
Devang Patel's avatar
Devang Patel committed
  DenseMap<const MDNode *, DIE *> MDNodeToDieMap;
Devang Patel's avatar
Devang Patel committed
  /// MDNodeToDIEEntryMap - Tracks the mapping of unit level debug informaton
  /// descriptors to debug information entries using a DIEEntry proxy.
Devang Patel's avatar
Devang Patel committed
  DenseMap<const MDNode *, DIEEntry *> MDNodeToDIEEntryMap;

  /// 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.
Benjamin Kramer's avatar
Benjamin Kramer committed
  void addGlobal(StringRef 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(StringRef Name, DIE *Die) {
    GlobalTypes[Name] = Die;
Devang Patel's avatar
Devang Patel committed
  }

  /// getDIE - Returns the debug information entry map slot for the
  /// specified debug variable.
Devang Patel's avatar
Devang Patel committed
  DIE *getDIE(const MDNode *N) { return MDNodeToDieMap.lookup(N); }
  /// insertDIE - Insert DIE into the map.
  void insertDIE(const MDNode *N, DIE *D) {
Devang Patel's avatar
Devang Patel committed
    MDNodeToDieMap.insert(std::make_pair(N, D));
  }

  /// getDIEEntry - Returns the debug information entry for the speciefied
  /// debug variable.
  DIEEntry *getDIEEntry(const MDNode *N) {
    DenseMap<const MDNode *, DIEEntry *>::iterator I =
      MDNodeToDIEEntryMap.find(N);
Devang Patel's avatar
Devang Patel committed
    if (I == MDNodeToDIEEntryMap.end())
      return NULL;
    return I->second;
  }
  /// insertDIEEntry - Insert debug information entry into the map.
  void insertDIEEntry(const MDNode *N, DIEEntry *E) {
Devang Patel's avatar
Devang Patel committed
    MDNodeToDIEEntryMap.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.
  DIE *TheDIE;                       // Variable DIE.
  unsigned DotDebugLocOffset;        // Offset in DotDebugLocEntries.
  DbgVariable(DIVariable V) : Var(V), TheDIE(0), DotDebugLocOffset(~0U) {}
  DIVariable getVariable()           const { return Var; }
  void setDIE(DIE *D)                      { TheDIE = D; }
  DIE *getDIE()                      const { return TheDIE; }
  void setDotDebugLocOffset(unsigned O)    { DotDebugLocOffset = O; }
  unsigned getDotDebugLocOffset()    const { return DotDebugLocOffset; }
  StringRef getName()                const { return Var.getName(); }
  unsigned getTag()                  const { return Var.getTag(); }
  bool variableHasComplexAddress()   const {
    assert(Var.Verify() && "Invalid complex DbgVariable!");
    return Var.hasComplexAddress();
  }
  bool isBlockByrefVariable()        const {
    assert(Var.Verify() && "Invalid complex DbgVariable!");
    return Var.isBlockByrefVariable();
  }
  unsigned getNumAddrElements()      const { 
    assert(Var.Verify() && "Invalid complex DbgVariable!");
    return Var.getNumAddrElements();
Loading
Loading full blame...