diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
| -rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 1999 | 
1 files changed, 556 insertions, 1443 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 780fa405ef51..26da8006b30e 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -14,6 +14,7 @@  #define DEBUG_TYPE "dwarfdebug"  #include "DwarfDebug.h"  #include "DIE.h" +#include "DwarfCompileUnit.h"  #include "llvm/Constants.h"  #include "llvm/Module.h"  #include "llvm/Instructions.h" @@ -52,7 +53,7 @@ static cl::opt<bool> DisableDebugInfoPrinting("disable-debug-info-print",       cl::desc("Disable debug info printing"));  static cl::opt<bool> UnknownLocations("use-unknown-locations", cl::Hidden, -     cl::desc("Make an absense of debug location information explicit."), +     cl::desc("Make an absence of debug location information explicit."),       cl::init(false));  #ifndef NDEBUG @@ -72,189 +73,56 @@ static const unsigned InitAbbreviationsSetSize = 9; // log2(512)  namespace llvm { -//===----------------------------------------------------------------------===// -/// CompileUnit - This dwarf writer support class manages information associate -/// with a source file. -class CompileUnit { -  /// ID - File identifier for source. -  /// -  unsigned ID; - -  /// Die - Compile unit debug information entry. -  /// -  const OwningPtr<DIE> CUDie; - -  /// IndexTyDie - An anonymous type for index type.  Owned by CUDie. -  DIE *IndexTyDie; - -  /// MDNodeToDieMap - Tracks the mapping of unit level debug informaton -  /// variables to debug information entries. -  DenseMap<const MDNode *, DIE *> MDNodeToDieMap; - -  /// MDNodeToDIEEntryMap - Tracks the mapping of unit level debug informaton -  /// descriptors to debug information entries using a DIEEntry proxy. -  DenseMap<const MDNode *, DIEEntry *> MDNodeToDIEEntryMap; - -  /// Globals - A map of globally visible named entities for this unit. -  /// -  StringMap<DIE*> Globals; - -  /// 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) {} - -  // Accessors. -  unsigned getID()                  const { return ID; } -  DIE* getCUDie()                   const { return CUDie.get(); } -  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(StringRef Name, DIE *Die) { Globals[Name] = Die; } - -  /// addGlobalType - Add a new global type to the compile unit. -  /// -  void addGlobalType(StringRef Name, DIE *Die) { -    GlobalTypes[Name] = Die; -  } - -  /// getDIE - Returns the debug information entry map slot for the -  /// specified debug variable. -  DIE *getDIE(const MDNode *N) { return MDNodeToDieMap.lookup(N); } - -  /// insertDIE - Insert DIE into the map. -  void insertDIE(const MDNode *N, DIE *D) { -    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); -    if (I == MDNodeToDIEEntryMap.end()) -      return NULL; -    return I->second; -  } - -  /// insertDIEEntry - Insert debug information entry into the map. -  void insertDIEEntry(const MDNode *N, DIEEntry *E) { -    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; -  } - -  // 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. -/// -class DbgVariable { -  DIVariable Var;                    // Variable Descriptor. -  DIE *TheDIE;                       // Variable DIE. -  unsigned DotDebugLocOffset;        // Offset in DotDebugLocEntries. -public: -  // AbsVar may be NULL. -  DbgVariable(DIVariable V) : Var(V), TheDIE(0), DotDebugLocOffset(~0U) {} - -  // Accessors. -  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(); -  } -  uint64_t getAddrElement(unsigned i) const { -    return Var.getAddrElement(i); -  } -  DIType getType()               const { -    DIType Ty = Var.getType(); -    // FIXME: isBlockByrefVariable should be reformulated in terms of complex -    // addresses instead. -    if (Var.isBlockByrefVariable()) { -      /* Byref variables, in Blocks, are declared by the programmer as -         "SomeType VarName;", but the compiler creates a -         __Block_byref_x_VarName struct, and gives the variable VarName -         either the struct, or a pointer to the struct, as its type.  This -         is necessary for various behind-the-scenes things the compiler -         needs to do with by-reference variables in blocks. -          -         However, as far as the original *programmer* is concerned, the -         variable should still have type 'SomeType', as originally declared. -          -         The following function dives into the __Block_byref_x_VarName -         struct to find the original type of the variable.  This will be -         passed back to the code generating the type for the Debug -         Information Entry for the variable 'VarName'.  'VarName' will then -         have the original type 'SomeType' in its debug information. -          -         The original type 'SomeType' will be the type of the field named -         'VarName' inside the __Block_byref_x_VarName struct. -          -         NOTE: In order for this to not completely fail on the debugger -         side, the Debug Information Entry for the variable VarName needs to -         have a DW_AT_location that tells the debugger how to unwind through -         the pointers and __Block_byref_x_VarName struct to find the actual -         value of the variable.  The function addBlockByrefType does this.  */ -      DIType subType = Ty; -      unsigned tag = Ty.getTag(); -       -      if (tag == dwarf::DW_TAG_pointer_type) { -        DIDerivedType DTy = DIDerivedType(Ty); -        subType = DTy.getTypeDerivedFrom(); -      } -       -      DICompositeType blockStruct = DICompositeType(subType); -      DIArray Elements = blockStruct.getTypeArray(); -       -      for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { -        DIDescriptor Element = Elements.getElement(i); -        DIDerivedType DT = DIDerivedType(Element); -        if (getName() == DT.getName()) -          return (DT.getTypeDerivedFrom()); -      } -      return Ty; +DIType DbgVariable::getType()               const { +  DIType Ty = Var.getType(); +  // FIXME: isBlockByrefVariable should be reformulated in terms of complex +  // addresses instead. +  if (Var.isBlockByrefVariable()) { +    /* Byref variables, in Blocks, are declared by the programmer as +       "SomeType VarName;", but the compiler creates a +       __Block_byref_x_VarName struct, and gives the variable VarName +       either the struct, or a pointer to the struct, as its type.  This +       is necessary for various behind-the-scenes things the compiler +       needs to do with by-reference variables in blocks. +        +       However, as far as the original *programmer* is concerned, the +       variable should still have type 'SomeType', as originally declared. +        +       The following function dives into the __Block_byref_x_VarName +       struct to find the original type of the variable.  This will be +       passed back to the code generating the type for the Debug +       Information Entry for the variable 'VarName'.  'VarName' will then +       have the original type 'SomeType' in its debug information. +        +       The original type 'SomeType' will be the type of the field named +       'VarName' inside the __Block_byref_x_VarName struct. +        +       NOTE: In order for this to not completely fail on the debugger +       side, the Debug Information Entry for the variable VarName needs to +       have a DW_AT_location that tells the debugger how to unwind through +       the pointers and __Block_byref_x_VarName struct to find the actual +       value of the variable.  The function addBlockByrefType does this.  */ +    DIType subType = Ty; +    unsigned tag = Ty.getTag(); +     +    if (tag == dwarf::DW_TAG_pointer_type) { +      DIDerivedType DTy = DIDerivedType(Ty); +      subType = DTy.getTypeDerivedFrom(); +    } +     +    DICompositeType blockStruct = DICompositeType(subType); +    DIArray Elements = blockStruct.getTypeArray(); +     +    for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { +      DIDescriptor Element = Elements.getElement(i); +      DIDerivedType DT = DIDerivedType(Element); +      if (getName() == DT.getName()) +        return (DT.getTypeDerivedFrom());      }      return Ty;    } -}; +  return Ty; +}  //===----------------------------------------------------------------------===//  /// DbgRange - This is used to track range of instructions with identical @@ -396,15 +264,12 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)    DwarfStrSectionSym = TextSectionSym = 0;    DwarfDebugRangeSectionSym = DwarfDebugLocSectionSym = 0;    FunctionBeginSym = FunctionEndSym = 0; -  DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);    {      NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);      beginModule(M);    }  }  DwarfDebug::~DwarfDebug() { -  for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j) -    DIEBlocks[j]->~DIEBlock();  }  MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) { @@ -439,852 +304,6 @@ void DwarfDebug::assignAbbrevNumber(DIEAbbrev &Abbrev) {    }  } -/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug -/// information entry. -DIEEntry *DwarfDebug::createDIEEntry(DIE *Entry) { -  DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry); -  return Value; -} - -/// addUInt - Add an unsigned integer attribute data and value. -/// -void DwarfDebug::addUInt(DIE *Die, unsigned Attribute, -                         unsigned Form, uint64_t Integer) { -  if (!Form) Form = DIEInteger::BestForm(false, Integer); -  DIEValue *Value = Integer == 1 ? -    DIEIntegerOne : new (DIEValueAllocator) DIEInteger(Integer); -  Die->addValue(Attribute, Form, Value); -} - -/// addSInt - Add an signed integer attribute data and value. -/// -void DwarfDebug::addSInt(DIE *Die, unsigned Attribute, -                         unsigned Form, int64_t Integer) { -  if (!Form) Form = DIEInteger::BestForm(true, Integer); -  DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer); -  Die->addValue(Attribute, Form, Value); -} - -/// addString - Add a string attribute data and value. DIEString only -/// keeps string reference. -void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form, -                           StringRef String) { -  DIEValue *Value = new (DIEValueAllocator) DIEString(String); -  Die->addValue(Attribute, Form, Value); -} - -/// addLabel - Add a Dwarf label attribute data and value. -/// -void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form, -                          const MCSymbol *Label) { -  DIEValue *Value = new (DIEValueAllocator) DIELabel(Label); -  Die->addValue(Attribute, Form, Value); -} - -/// addDelta - Add a label delta attribute data and value. -/// -void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form, -                          const MCSymbol *Hi, const MCSymbol *Lo) { -  DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo); -  Die->addValue(Attribute, Form, Value); -} - -/// addDIEEntry - Add a DIE attribute data and value. -/// -void DwarfDebug::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form, -                             DIE *Entry) { -  Die->addValue(Attribute, Form, createDIEEntry(Entry)); -} - - -/// addBlock - Add block data. -/// -void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form, -                          DIEBlock *Block) { -  Block->ComputeSize(Asm); -  DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on. -  Die->addValue(Attribute, Block->BestForm(), Block); -} - -/// addSourceLine - Add location information to specified debug information -/// entry. -void DwarfDebug::addSourceLine(DIE *Die, DIVariable V) { -  // Verify variable. -  if (!V.Verify()) -    return; - -  unsigned Line = V.getLineNumber(); -  if (Line == 0) -    return; -  unsigned FileID = GetOrCreateSourceID(V.getContext().getFilename()); -  assert(FileID && "Invalid file id"); -  addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); -  addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); -} - -/// addSourceLine - Add location information to specified debug information -/// entry. -void DwarfDebug::addSourceLine(DIE *Die, DIGlobalVariable G) { -  // Verify global variable. -  if (!G.Verify()) -    return; - -  unsigned Line = G.getLineNumber(); -  if (Line == 0) -    return; -  unsigned FileID = GetOrCreateSourceID(G.getContext().getFilename()); -  assert(FileID && "Invalid file id"); -  addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); -  addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); -} - -/// addSourceLine - Add location information to specified debug information -/// entry. -void DwarfDebug::addSourceLine(DIE *Die, DISubprogram SP) { -  // Verify subprogram. -  if (!SP.Verify()) -    return; -  // If the line number is 0, don't add it. -  if (SP.getLineNumber() == 0) -    return; - -  unsigned Line = SP.getLineNumber(); -  if (!SP.getContext().Verify()) -    return; -  unsigned FileID = GetOrCreateSourceID(SP.getFilename()); -  assert(FileID && "Invalid file id"); -  addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); -  addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); -} - -/// addSourceLine - Add location information to specified debug information -/// entry. -void DwarfDebug::addSourceLine(DIE *Die, DIType Ty) { -  // Verify type. -  if (!Ty.Verify()) -    return; - -  unsigned Line = Ty.getLineNumber(); -  if (Line == 0 || !Ty.getContext().Verify()) -    return; -  unsigned FileID = GetOrCreateSourceID(Ty.getFilename()); -  assert(FileID && "Invalid file id"); -  addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); -  addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); -} - -/// addSourceLine - Add location information to specified debug information -/// entry. -void DwarfDebug::addSourceLine(DIE *Die, DINameSpace NS) { -  // Verify namespace. -  if (!NS.Verify()) -    return; - -  unsigned Line = NS.getLineNumber(); -  if (Line == 0) -    return; -  StringRef FN = NS.getFilename(); - -  unsigned FileID = GetOrCreateSourceID(FN); -  assert(FileID && "Invalid file id"); -  addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); -  addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); -} - -/// addVariableAddress - Add DW_AT_location attribute for a DbgVariable based -/// on provided frame index. -void DwarfDebug::addVariableAddress(DbgVariable *&DV, DIE *Die, int64_t FI) { -  MachineLocation Location; -  unsigned FrameReg; -  const TargetFrameLowering *TFI = Asm->TM.getFrameLowering(); -  int Offset = TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg); -  Location.set(FrameReg, Offset); - -  if (DV->variableHasComplexAddress()) -    addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); -  else if (DV->isBlockByrefVariable()) -    addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location); -  else -    addAddress(Die, dwarf::DW_AT_location, Location); -} - -/// addComplexAddress - Start with the address based on the location provided, -/// and generate the DWARF information necessary to find the actual variable -/// given the extra address information encoded in the DIVariable, starting from -/// the starting location.  Add the DWARF information to the die. -/// -void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die, -                                   unsigned Attribute, -                                   const MachineLocation &Location) { -  DIType Ty = DV->getType(); - -  // Decode the original location, and use that as the start of the byref -  // variable's location. -  const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); -  unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false); -  DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); - -  if (Location.isReg()) { -    if (Reg < 32) { -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg); -    } else { -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx); -      addUInt(Block, 0, dwarf::DW_FORM_udata, Reg); -    } -  } else { -    if (Reg < 32) -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg); -    else { -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx); -      addUInt(Block, 0, dwarf::DW_FORM_udata, Reg); -    } - -    addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset()); -  } - -  for (unsigned i = 0, N = DV->getNumAddrElements(); i < N; ++i) { -    uint64_t Element = DV->getAddrElement(i); - -    if (Element == DIBuilder::OpPlus) { -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); -      addUInt(Block, 0, dwarf::DW_FORM_udata, DV->getAddrElement(++i)); -    } else if (Element == DIBuilder::OpDeref) { -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); -    } else llvm_unreachable("unknown DIBuilder Opcode"); -  } - -  // Now attach the location information to the DIE. -  addBlock(Die, Attribute, 0, Block); -} - -/* Byref variables, in Blocks, are declared by the programmer as "SomeType -   VarName;", but the compiler creates a __Block_byref_x_VarName struct, and -   gives the variable VarName either the struct, or a pointer to the struct, as -   its type.  This is necessary for various behind-the-scenes things the -   compiler needs to do with by-reference variables in Blocks. - -   However, as far as the original *programmer* is concerned, the variable -   should still have type 'SomeType', as originally declared. - -   The function getBlockByrefType dives into the __Block_byref_x_VarName -   struct to find the original type of the variable, which is then assigned to -   the variable's Debug Information Entry as its real type.  So far, so good. -   However now the debugger will expect the variable VarName to have the type -   SomeType.  So we need the location attribute for the variable to be an -   expression that explains to the debugger how to navigate through the -   pointers and struct to find the actual variable of type SomeType. - -   The following function does just that.  We start by getting -   the "normal" location for the variable. This will be the location -   of either the struct __Block_byref_x_VarName or the pointer to the -   struct __Block_byref_x_VarName. - -   The struct will look something like: - -   struct __Block_byref_x_VarName { -     ... <various fields> -     struct __Block_byref_x_VarName *forwarding; -     ... <various other fields> -     SomeType VarName; -     ... <maybe more fields> -   }; - -   If we are given the struct directly (as our starting point) we -   need to tell the debugger to: - -   1).  Add the offset of the forwarding field. - -   2).  Follow that pointer to get the real __Block_byref_x_VarName -   struct to use (the real one may have been copied onto the heap). - -   3).  Add the offset for the field VarName, to find the actual variable. - -   If we started with a pointer to the struct, then we need to -   dereference that pointer first, before the other steps. -   Translating this into DWARF ops, we will need to append the following -   to the current location description for the variable: - -   DW_OP_deref                    -- optional, if we start with a pointer -   DW_OP_plus_uconst <forward_fld_offset> -   DW_OP_deref -   DW_OP_plus_uconst <varName_fld_offset> - -   That is what this function does.  */ - -/// addBlockByrefAddress - Start with the address based on the location -/// provided, and generate the DWARF information necessary to find the -/// actual Block variable (navigating the Block struct) based on the -/// starting location.  Add the DWARF information to the die.  For -/// more information, read large comment just above here. -/// -void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die, -                                      unsigned Attribute, -                                      const MachineLocation &Location) { -  DIType Ty = DV->getType(); -  DIType TmpTy = Ty; -  unsigned Tag = Ty.getTag(); -  bool isPointer = false; - -  StringRef varName = DV->getName(); - -  if (Tag == dwarf::DW_TAG_pointer_type) { -    DIDerivedType DTy = DIDerivedType(Ty); -    TmpTy = DTy.getTypeDerivedFrom(); -    isPointer = true; -  } - -  DICompositeType blockStruct = DICompositeType(TmpTy); - -  // Find the __forwarding field and the variable field in the __Block_byref -  // struct. -  DIArray Fields = blockStruct.getTypeArray(); -  DIDescriptor varField = DIDescriptor(); -  DIDescriptor forwardingField = DIDescriptor(); - -  for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) { -    DIDescriptor Element = Fields.getElement(i); -    DIDerivedType DT = DIDerivedType(Element); -    StringRef fieldName = DT.getName(); -    if (fieldName == "__forwarding") -      forwardingField = Element; -    else if (fieldName == varName) -      varField = Element; -  } - -  // Get the offsets for the forwarding field and the variable field. -  unsigned forwardingFieldOffset = -    DIDerivedType(forwardingField).getOffsetInBits() >> 3; -  unsigned varFieldOffset = -    DIDerivedType(varField).getOffsetInBits() >> 3; - -  // Decode the original location, and use that as the start of the byref -  // variable's location. -  const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); -  unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false); -  DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); - -  if (Location.isReg()) { -    if (Reg < 32) -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg); -    else { -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx); -      addUInt(Block, 0, dwarf::DW_FORM_udata, Reg); -    } -  } else { -    if (Reg < 32) -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg); -    else { -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx); -      addUInt(Block, 0, dwarf::DW_FORM_udata, Reg); -    } - -    addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset()); -  } - -  // If we started with a pointer to the __Block_byref... struct, then -  // the first thing we need to do is dereference the pointer (DW_OP_deref). -  if (isPointer) -    addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); - -  // Next add the offset for the '__forwarding' field: -  // DW_OP_plus_uconst ForwardingFieldOffset.  Note there's no point in -  // adding the offset if it's 0. -  if (forwardingFieldOffset > 0) { -    addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); -    addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset); -  } - -  // Now dereference the __forwarding field to get to the real __Block_byref -  // struct:  DW_OP_deref. -  addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); - -  // Now that we've got the real __Block_byref... struct, add the offset -  // for the variable's field to get to the location of the actual variable: -  // DW_OP_plus_uconst varFieldOffset.  Again, don't add if it's 0. -  if (varFieldOffset > 0) { -    addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); -    addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset); -  } - -  // Now attach the location information to the DIE. -  addBlock(Die, Attribute, 0, Block); -} - -/// addAddress - Add an address attribute to a die based on the location -/// provided. -void DwarfDebug::addAddress(DIE *Die, unsigned Attribute, -                            const MachineLocation &Location) { -  const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); -  unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false); -  DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); - -  if (RI->getFrameRegister(*Asm->MF) == Location.getReg() -      && Location.getOffset()) { -    // If variable offset is based in frame register then use fbreg. -    addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_fbreg); -    addSInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset()); -    addBlock(Die, Attribute, 0, Block); -    return; -  } - -  if (Location.isReg()) { -    if (Reg < 32) { -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg); -    } else { -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx); -      addUInt(Block, 0, dwarf::DW_FORM_udata, Reg); -    } -  } else { -    if (Reg < 32) { -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg); -    } else { -      addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx); -      addUInt(Block, 0, dwarf::DW_FORM_udata, Reg); -    } - -    addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset()); -  } - -  addBlock(Die, Attribute, 0, Block); -} - -/// addRegisterAddress - Add register location entry in variable DIE. -bool DwarfDebug::addRegisterAddress(DIE *Die, const MachineOperand &MO) { -  assert (MO.isReg() && "Invalid machine operand!"); -  if (!MO.getReg()) -    return false; -  MachineLocation Location; -  Location.set(MO.getReg()); -  addAddress(Die, dwarf::DW_AT_location, Location); -  return true; -} - -/// addConstantValue - Add constant value entry in variable DIE. -bool DwarfDebug::addConstantValue(DIE *Die, const MachineOperand &MO) { -  assert (MO.isImm() && "Invalid machine operand!"); -  DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); -  unsigned Imm = MO.getImm(); -  addUInt(Block, 0, dwarf::DW_FORM_udata, Imm); -  addBlock(Die, dwarf::DW_AT_const_value, 0, Block); -  return true; -} - -/// addConstantFPValue - Add constant value entry in variable DIE. -bool DwarfDebug::addConstantFPValue(DIE *Die, const MachineOperand &MO) { -  assert (MO.isFPImm() && "Invalid machine operand!"); -  DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); -  APFloat FPImm = MO.getFPImm()->getValueAPF(); - -  // Get the raw data form of the floating point. -  const APInt FltVal = FPImm.bitcastToAPInt(); -  const char *FltPtr = (const char*)FltVal.getRawData(); - -  int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte. -  bool LittleEndian = Asm->getTargetData().isLittleEndian(); -  int Incr = (LittleEndian ? 1 : -1); -  int Start = (LittleEndian ? 0 : NumBytes - 1); -  int Stop = (LittleEndian ? NumBytes : -1); - -  // Output the constant to DWARF one byte at a time. -  for (; Start != Stop; Start += Incr) -    addUInt(Block, 0, dwarf::DW_FORM_data1, -            (unsigned char)0xFF & FltPtr[Start]); - -  addBlock(Die, dwarf::DW_AT_const_value, 0, Block); -  return true; -} - -/// addConstantValue - Add constant value entry in variable DIE. -bool DwarfDebug::addConstantValue(DIE *Die, ConstantInt *CI, -                                  bool Unsigned) { -  if (CI->getBitWidth() <= 64) { -    if (Unsigned) -      addUInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata, -              CI->getZExtValue()); -    else -      addSInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, -              CI->getSExtValue()); -    return true; -  } - -  DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); - -  // Get the raw data form of the large APInt. -  const APInt Val = CI->getValue(); -  const char *Ptr = (const char*)Val.getRawData(); - -  int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte. -  bool LittleEndian = Asm->getTargetData().isLittleEndian(); -  int Incr = (LittleEndian ? 1 : -1); -  int Start = (LittleEndian ? 0 : NumBytes - 1); -  int Stop = (LittleEndian ? NumBytes : -1); - -  // Output the constant to DWARF one byte at a time. -  for (; Start != Stop; Start += Incr) -    addUInt(Block, 0, dwarf::DW_FORM_data1, -            (unsigned char)0xFF & Ptr[Start]); - -  addBlock(Die, dwarf::DW_AT_const_value, 0, Block); -  return true; -} - -/// addToContextOwner - Add Die into the list of its context owner's children. -void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) { -  if (Context.isType()) { -    DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context)); -    ContextDIE->addChild(Die); -  } else if (Context.isNameSpace()) { -    DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context)); -    ContextDIE->addChild(Die); -  } else if (Context.isSubprogram()) { -    DIE *ContextDIE = createSubprogramDIE(DISubprogram(Context)); -    ContextDIE->addChild(Die); -  } else if (DIE *ContextDIE = getCompileUnit(Context)->getDIE(Context)) -    ContextDIE->addChild(Die); -  else -    getCompileUnit(Context)->addDie(Die); -} - -/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the -/// given DIType. -DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) { -  CompileUnit *TypeCU = getCompileUnit(Ty); -  DIE *TyDIE = TypeCU->getDIE(Ty); -  if (TyDIE) -    return TyDIE; - -  // Create new type. -  TyDIE = new DIE(dwarf::DW_TAG_base_type); -  TypeCU->insertDIE(Ty, TyDIE); -  if (Ty.isBasicType()) -    constructTypeDIE(*TyDIE, DIBasicType(Ty)); -  else if (Ty.isCompositeType()) -    constructTypeDIE(*TyDIE, DICompositeType(Ty)); -  else { -    assert(Ty.isDerivedType() && "Unknown kind of DIType"); -    constructTypeDIE(*TyDIE, DIDerivedType(Ty)); -  } - -  addToContextOwner(TyDIE, Ty.getContext()); -  return TyDIE; -} - -/// addType - Add a new type attribute to the specified entity. -void DwarfDebug::addType(DIE *Entity, DIType Ty) { -  if (!Ty.Verify()) -    return; - -  // Check for pre-existence. -  CompileUnit *TypeCU = getCompileUnit(Ty); -  DIEEntry *Entry = TypeCU->getDIEEntry(Ty); -  // If it exists then use the existing value. -  if (Entry) { -    Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry); -    return; -  } - -  // Construct type. -  DIE *Buffer = getOrCreateTypeDIE(Ty); - -  // Set up proxy. -  Entry = createDIEEntry(Buffer); -  TypeCU->insertDIEEntry(Ty, Entry); - -  Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry); -} - -/// constructTypeDIE - Construct basic type die from DIBasicType. -void DwarfDebug::constructTypeDIE(DIE &Buffer, DIBasicType BTy) { -  // Get core information. -  StringRef Name = BTy.getName(); -  Buffer.setTag(dwarf::DW_TAG_base_type); -  addUInt(&Buffer, dwarf::DW_AT_encoding,  dwarf::DW_FORM_data1, -          BTy.getEncoding()); - -  // Add name if not anonymous or intermediate type. -  if (!Name.empty()) -    addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); -  uint64_t Size = BTy.getSizeInBits() >> 3; -  addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size); -} - -/// constructTypeDIE - Construct derived type die from DIDerivedType. -void DwarfDebug::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) { -  // Get core information. -  StringRef Name = DTy.getName(); -  uint64_t Size = DTy.getSizeInBits() >> 3; -  unsigned Tag = DTy.getTag(); - -  // FIXME - Workaround for templates. -  if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type; - -  Buffer.setTag(Tag); - -  // Map to main type, void will not have a type. -  DIType FromTy = DTy.getTypeDerivedFrom(); -  addType(&Buffer, FromTy); - -  // Add name if not anonymous or intermediate type. -  if (!Name.empty()) -    addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); - -  // Add size if non-zero (derived types might be zero-sized.) -  if (Size) -    addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size); - -  // Add source line info if available and TyDesc is not a forward declaration. -  if (!DTy.isForwardDecl()) -    addSourceLine(&Buffer, DTy); -} - -/// constructTypeDIE - Construct type DIE from DICompositeType. -void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { -  // Get core information. -  StringRef Name = CTy.getName(); - -  uint64_t Size = CTy.getSizeInBits() >> 3; -  unsigned Tag = CTy.getTag(); -  Buffer.setTag(Tag); - -  switch (Tag) { -  case dwarf::DW_TAG_vector_type: -  case dwarf::DW_TAG_array_type: -    constructArrayTypeDIE(Buffer, &CTy); -    break; -  case dwarf::DW_TAG_enumeration_type: { -    DIArray Elements = CTy.getTypeArray(); - -    // Add enumerators to enumeration type. -    for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { -      DIE *ElemDie = NULL; -      DIDescriptor Enum(Elements.getElement(i)); -      if (Enum.isEnumerator()) { -        ElemDie = constructEnumTypeDIE(DIEnumerator(Enum)); -        Buffer.addChild(ElemDie); -      } -    } -  } -    break; -  case dwarf::DW_TAG_subroutine_type: { -    // Add return type. -    DIArray Elements = CTy.getTypeArray(); -    DIDescriptor RTy = Elements.getElement(0); -    addType(&Buffer, DIType(RTy)); - -    bool isPrototyped = true; -    // Add arguments. -    for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) { -      DIDescriptor Ty = Elements.getElement(i); -      if (Ty.isUnspecifiedParameter()) { -        DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters); -        Buffer.addChild(Arg); -        isPrototyped = false; -      } else { -        DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); -        addType(Arg, DIType(Ty)); -        Buffer.addChild(Arg); -      } -    } -    // Add prototype flag. -    if (isPrototyped) -      addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1); -  } -    break; -  case dwarf::DW_TAG_structure_type: -  case dwarf::DW_TAG_union_type: -  case dwarf::DW_TAG_class_type: { -    // Add elements to structure type. -    DIArray Elements = CTy.getTypeArray(); - -    // A forward struct declared type may not have elements available. -    unsigned N = Elements.getNumElements(); -    if (N == 0) -      break; - -    // Add elements to structure type. -    for (unsigned i = 0; i < N; ++i) { -      DIDescriptor Element = Elements.getElement(i); -      DIE *ElemDie = NULL; -      if (Element.isSubprogram()) { -        DISubprogram SP(Element); -        ElemDie = createSubprogramDIE(DISubprogram(Element)); -        if (SP.isProtected()) -          addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, -                  dwarf::DW_ACCESS_protected); -        else if (SP.isPrivate()) -          addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, -                  dwarf::DW_ACCESS_private); -        else  -          addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, -            dwarf::DW_ACCESS_public); -        if (SP.isExplicit()) -          addUInt(ElemDie, dwarf::DW_AT_explicit, dwarf::DW_FORM_flag, 1); -      } -      else if (Element.isVariable()) { -        DIVariable DV(Element); -        ElemDie = new DIE(dwarf::DW_TAG_variable); -        addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, -                  DV.getName()); -        addType(ElemDie, DV.getType()); -        addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); -        addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); -        addSourceLine(ElemDie, DV); -      } else if (Element.isDerivedType()) -        ElemDie = createMemberDIE(DIDerivedType(Element)); -      else -        continue; -      Buffer.addChild(ElemDie); -    } - -    if (CTy.isAppleBlockExtension()) -      addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1); - -    unsigned RLang = CTy.getRunTimeLang(); -    if (RLang) -      addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class, -              dwarf::DW_FORM_data1, RLang); - -    DICompositeType ContainingType = CTy.getContainingType(); -    if (DIDescriptor(ContainingType).isCompositeType()) -      addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, -                  getOrCreateTypeDIE(DIType(ContainingType))); -    else { -      DIDescriptor Context = CTy.getContext(); -      addToContextOwner(&Buffer, Context); -    } - -    if (Tag == dwarf::DW_TAG_class_type) { -      DIArray TParams = CTy.getTemplateParams(); -      unsigned N = TParams.getNumElements(); -      // Add template parameters. -      for (unsigned i = 0; i < N; ++i) { -        DIDescriptor Element = TParams.getElement(i); -        if (Element.isTemplateTypeParameter()) -          Buffer.addChild(getOrCreateTemplateTypeParameterDIE( -                            DITemplateTypeParameter(Element))); -        else if (Element.isTemplateValueParameter()) -          Buffer.addChild(getOrCreateTemplateValueParameterDIE( -                            DITemplateValueParameter(Element))); -      } -    } -    break; -  } -  default: -    break; -  } - -  // Add name if not anonymous or intermediate type. -  if (!Name.empty()) -    addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); - -  if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type -      || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) -    { -    // Add size if non-zero (derived types might be zero-sized.) -    if (Size) -      addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size); -    else { -      // Add zero size if it is not a forward declaration. -      if (CTy.isForwardDecl()) -        addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); -      else -        addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0); -    } - -    // Add source line info if available. -    if (!CTy.isForwardDecl()) -      addSourceLine(&Buffer, CTy); -  } -} - -/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE  -/// for the given DITemplateTypeParameter. -DIE * -DwarfDebug::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) { -  CompileUnit *TypeCU = getCompileUnit(TP); -  DIE *ParamDIE = TypeCU->getDIE(TP); -  if (ParamDIE) -    return ParamDIE; - -  ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter); -  addType(ParamDIE, TP.getType()); -  addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TP.getName()); -  return ParamDIE; -} - -/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE  -/// for the given DITemplateValueParameter. -DIE * -DwarfDebug::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV) { -  CompileUnit *TVCU = getCompileUnit(TPV); -  DIE *ParamDIE = TVCU->getDIE(TPV); -  if (ParamDIE) -    return ParamDIE; - -  ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter); -  addType(ParamDIE, TPV.getType()); -  addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TPV.getName()); -  addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,  -          TPV.getValue()); -  return ParamDIE; -} - -/// constructSubrangeDIE - Construct subrange DIE from DISubrange. -void DwarfDebug::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){ -  int64_t L = SR.getLo(); -  int64_t H = SR.getHi(); -  DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type); - -  addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy); -  if (L) -    addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L); -  addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H); - -  Buffer.addChild(DW_Subrange); -} - -/// constructArrayTypeDIE - Construct array type DIE from DICompositeType. -void DwarfDebug::constructArrayTypeDIE(DIE &Buffer, -                                       DICompositeType *CTy) { -  Buffer.setTag(dwarf::DW_TAG_array_type); -  if (CTy->getTag() == dwarf::DW_TAG_vector_type) -    addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1); - -  // Emit derived type. -  addType(&Buffer, CTy->getTypeDerivedFrom()); -  DIArray Elements = CTy->getTypeArray(); - -  // Get an anonymous type for index type. -  CompileUnit *TheCU = getCompileUnit(*CTy); -  DIE *IdxTy = TheCU->getIndexTyDie(); -  if (!IdxTy) { -    // Construct an anonymous type for index type. -    IdxTy = new DIE(dwarf::DW_TAG_base_type); -    addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t)); -    addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, -            dwarf::DW_ATE_signed); -    TheCU->addDie(IdxTy); -    TheCU->setIndexTyDie(IdxTy); -  } - -  // Add subranges to array type. -  for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { -    DIDescriptor Element = Elements.getElement(i); -    if (Element.getTag() == dwarf::DW_TAG_subrange_type) -      constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy); -  } -} - -/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. -DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator ETy) { -  DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator); -  StringRef Name = ETy.getName(); -  addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); -  int64_t Value = ETy.getEnumValue(); -  addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value); -  return Enumerator; -} -  /// getRealLinkageName - If special LLVM prefix that is used to inform the asm  /// printer to not emit usual symbol prefix before the symbol name is used then  /// return linkage name after skipping this special LLVM prefix. @@ -1295,84 +314,6 @@ static StringRef getRealLinkageName(StringRef LinkageName) {    return LinkageName;  } -/// createMemberDIE - Create new member DIE. -DIE *DwarfDebug::createMemberDIE(DIDerivedType DT) { -  DIE *MemberDie = new DIE(DT.getTag()); -  StringRef Name = DT.getName(); -  if (!Name.empty()) -    addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); - -  addType(MemberDie, DT.getTypeDerivedFrom()); - -  addSourceLine(MemberDie, DT); - -  DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock(); -  addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); - -  uint64_t Size = DT.getSizeInBits(); -  uint64_t FieldSize = DT.getOriginalTypeSize(); - -  if (Size != FieldSize) { -    // Handle bitfield. -    addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3); -    addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits()); - -    uint64_t Offset = DT.getOffsetInBits(); -    uint64_t AlignMask = ~(DT.getAlignInBits() - 1); -    uint64_t HiMark = (Offset + FieldSize) & AlignMask; -    uint64_t FieldOffset = (HiMark - FieldSize); -    Offset -= FieldOffset; - -    // Maybe we need to work from the other end. -    if (Asm->getTargetData().isLittleEndian()) -      Offset = FieldSize - (Offset + Size); -    addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset); - -    // Here WD_AT_data_member_location points to the anonymous -    // field that includes this bit field. -    addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3); - -  } else -    // This is not a bitfield. -    addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3); - -  if (DT.getTag() == dwarf::DW_TAG_inheritance -      && DT.isVirtual()) { - -    // For C++, virtual base classes are not at fixed offset. Use following -    // expression to extract appropriate offset from vtable. -    // BaseAddr = ObAddr + *((*ObAddr) - Offset) - -    DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock(); -    addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup); -    addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); -    addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); -    addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits()); -    addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus); -    addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); -    addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); - -    addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, -             VBaseLocationDie); -  } else -    addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie); - -  if (DT.isProtected()) -    addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, -            dwarf::DW_ACCESS_protected); -  else if (DT.isPrivate()) -    addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, -            dwarf::DW_ACCESS_private); -  // Otherwise C++ member and base classes are considered public. -  else if (DT.getCompileUnit().getLanguage() == dwarf::DW_LANG_C_plus_plus) -    addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, -            dwarf::DW_ACCESS_public); -  if (DT.isVirtual()) -    addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, -            dwarf::DW_VIRTUALITY_virtual); -  return MemberDie; -} -  /// createSubprogramDIE - Create new DIE using SP.  DIE *DwarfDebug::createSubprogramDIE(DISubprogram SP) {    CompileUnit *SPCU = getCompileUnit(SP); @@ -1381,19 +322,35 @@ DIE *DwarfDebug::createSubprogramDIE(DISubprogram SP) {      return SPDie;    SPDie = new DIE(dwarf::DW_TAG_subprogram); +   +  // DW_TAG_inlined_subroutine may refer to this DIE. +  SPCU->insertDIE(SP, SPDie); +   +  // Add to context owner. +  SPCU->addToContextOwner(SPDie, SP.getContext()); + +  // Add function template parameters. +  SPCU->addTemplateParams(*SPDie, SP.getTemplateParams()); + +  // If this DIE is going to refer declaration info using AT_specification +  // then there is no need to add other attributes. +  if (SP.getFunctionDeclaration().isSubprogram()) +    return SPDie; +    // Constructors and operators for anonymous aggregates do not have names.    if (!SP.getName().empty()) -    addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName()); +    SPCU->addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,  +                    SP.getName());    StringRef LinkageName = SP.getLinkageName();    if (!LinkageName.empty()) -    addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string, -              getRealLinkageName(LinkageName)); +    SPCU->addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string, +                    getRealLinkageName(LinkageName)); -  addSourceLine(SPDie, SP); +  SPCU->addSourceLine(SPDie, SP);    if (SP.isPrototyped())  -    addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1); +    SPCU->addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);    // Add Return Type.    DICompositeType SPTy = SP.getType(); @@ -1401,24 +358,24 @@ DIE *DwarfDebug::createSubprogramDIE(DISubprogram SP) {    unsigned SPTag = SPTy.getTag();    if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type) -    addType(SPDie, SPTy); +    SPCU->addType(SPDie, SPTy);    else -    addType(SPDie, DIType(Args.getElement(0))); +    SPCU->addType(SPDie, DIType(Args.getElement(0)));    unsigned VK = SP.getVirtuality();    if (VK) { -    addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK); -    DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); -    addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); -    addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex()); -    addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block); +    SPCU->addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK); +    DIEBlock *Block = SPCU->getDIEBlock(); +    SPCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); +    SPCU->addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex()); +    SPCU->addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);      ContainingTypeMap.insert(std::make_pair(SPDie,                                              SP.getContainingType()));    }    if (!SP.isDefinition()) { -    addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); - +    SPCU->addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); +          // Add arguments. Do not add arguments for subprogram definition. They will      // be handled while processing variables.      DICompositeType SPTy = SP.getType(); @@ -1429,32 +386,26 @@ DIE *DwarfDebug::createSubprogramDIE(DISubprogram SP) {        for (unsigned i = 1, N =  Args.getNumElements(); i < N; ++i) {          DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);          DIType ATy = DIType(DIType(Args.getElement(i))); -        addType(Arg, ATy); +        SPCU->addType(Arg, ATy);          if (ATy.isArtificial()) -          addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); +          SPCU->addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);          SPDie->addChild(Arg);        }    }    if (SP.isArtificial()) -    addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); +    SPCU->addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);    if (!SP.isLocalToUnit()) -    addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); +    SPCU->addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);    if (SP.isOptimized()) -    addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1); +    SPCU->addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);    if (unsigned isa = Asm->getISAEncoding()) { -    addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa); +    SPCU->addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);    } -  // DW_TAG_inlined_subroutine may refer to this DIE. -  SPCU->insertDIE(SP, SPDie); - -  // Add to context owner. -  addToContextOwner(SPDie, SP.getContext()); -    return SPDie;  } @@ -1509,51 +460,57 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(const MDNode *SPNode) {    assert(SPDie && "Unable to find subprogram DIE!");    DISubprogram SP(SPNode); -  // There is not any need to generate specification DIE for a function -  // defined at compile unit level. If a function is defined inside another -  // function then gdb prefers the definition at top level and but does not -  // expect specification DIE in parent function. So avoid creating -  // specification DIE for a function defined inside a function. -  if (SP.isDefinition() && !SP.getContext().isCompileUnit() && -      !SP.getContext().isFile() && -      !isSubprogramContext(SP.getContext())) { -    addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); - -    // Add arguments. -    DICompositeType SPTy = SP.getType(); -    DIArray Args = SPTy.getTypeArray(); -    unsigned SPTag = SPTy.getTag(); -    if (SPTag == dwarf::DW_TAG_subroutine_type) -      for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { -        DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); -        DIType ATy = DIType(DIType(Args.getElement(i))); -        addType(Arg, ATy); -        if (ATy.isArtificial()) -          addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); -        SPDie->addChild(Arg); -      } -    DIE *SPDeclDie = SPDie; -    SPDie = new DIE(dwarf::DW_TAG_subprogram); -    addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4, -                SPDeclDie); -    SPCU->addDie(SPDie); +  DISubprogram SPDecl = SP.getFunctionDeclaration(); +  if (SPDecl.isSubprogram()) +    // Refer function declaration directly. +    SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4, +                      createSubprogramDIE(SPDecl)); +  else { +    // There is not any need to generate specification DIE for a function +    // defined at compile unit level. If a function is defined inside another +    // function then gdb prefers the definition at top level and but does not +    // expect specification DIE in parent function. So avoid creating +    // specification DIE for a function defined inside a function. +    if (SP.isDefinition() && !SP.getContext().isCompileUnit() && +        !SP.getContext().isFile() && +        !isSubprogramContext(SP.getContext())) { +      SPCU-> addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); +       +      // Add arguments. +      DICompositeType SPTy = SP.getType(); +      DIArray Args = SPTy.getTypeArray(); +      unsigned SPTag = SPTy.getTag(); +      if (SPTag == dwarf::DW_TAG_subroutine_type) +        for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { +          DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); +          DIType ATy = DIType(DIType(Args.getElement(i))); +          SPCU->addType(Arg, ATy); +          if (ATy.isArtificial()) +            SPCU->addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); +          SPDie->addChild(Arg); +        } +      DIE *SPDeclDie = SPDie; +      SPDie = new DIE(dwarf::DW_TAG_subprogram); +      SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4, +                        SPDeclDie); +      SPCU->addDie(SPDie); +    }    } -    // Pick up abstract subprogram DIE.    if (DIE *AbsSPDIE = AbstractSPDies.lookup(SPNode)) {      SPDie = new DIE(dwarf::DW_TAG_subprogram); -    addDIEEntry(SPDie, dwarf::DW_AT_abstract_origin, -                dwarf::DW_FORM_ref4, AbsSPDIE); +    SPCU->addDIEEntry(SPDie, dwarf::DW_AT_abstract_origin, +                      dwarf::DW_FORM_ref4, AbsSPDIE);      SPCU->addDie(SPDie);    } -  addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, -           Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber())); -  addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, -           Asm->GetTempSymbol("func_end", Asm->getFunctionNumber())); +  SPCU->addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, +                 Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber())); +  SPCU->addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, +                 Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));    const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();    MachineLocation Location(RI->getFrameRegister(*Asm->MF)); -  addAddress(SPDie, dwarf::DW_AT_frame_base, Location); +  SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location);    return SPDie;  } @@ -1570,13 +527,14 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {    if (Ranges.empty())      return 0; +  CompileUnit *TheCU = getCompileUnit(Scope->getScopeNode());    SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin();    if (Ranges.size() > 1) {      // .debug_range section has not been laid out yet. Emit offset in      // .debug_range as a uint, size 4, for now. emitDIE will handle      // DW_AT_ranges appropriately. -    addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4, -            DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize()); +    TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4, +                   DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize());      for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(),           RE = Ranges.end(); RI != RE; ++RI) {        DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first)); @@ -1595,8 +553,8 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {    assert(Start->isDefined() && "Invalid starting label for an inlined scope!");    assert(End->isDefined() && "Invalid end label for an inlined scope!"); -  addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, Start); -  addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, End); +  TheCU->addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, Start); +  TheCU->addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, End);    return ScopeDIE;  } @@ -1636,11 +594,11 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {    CompileUnit *TheCU = getCompileUnit(InlinedSP);    DIE *OriginDIE = TheCU->getDIE(InlinedSP);    assert(OriginDIE && "Unable to find Origin DIE!"); -  addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin, -              dwarf::DW_FORM_ref4, OriginDIE); +  TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin, +                     dwarf::DW_FORM_ref4, OriginDIE); -  addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, StartLabel); -  addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, EndLabel); +  TheCU->addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, StartLabel); +  TheCU->addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, EndLabel);    InlinedSubprogramDIEs.insert(OriginDIE); @@ -1656,8 +614,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {      I->second.push_back(std::make_pair(StartLabel, ScopeDIE));    DILocation DL(Scope->getInlinedAt()); -  addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, TheCU->getID()); -  addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber()); +  TheCU->addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, TheCU->getID()); +  TheCU->addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber());    return ScopeDIE;  } @@ -1686,7 +644,7 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {    // Define variable debug information entry.    DIE *VariableDie = new DIE(Tag); - +  CompileUnit *VariableCU = getCompileUnit(DV->getVariable());    DIE *AbsDIE = NULL;    DenseMap<const DbgVariable *, const DbgVariable *>::iterator      V2AVI = VarToAbstractVarMap.find(DV); @@ -1694,20 +652,23 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {      AbsDIE = V2AVI->second->getDIE();    if (AbsDIE) -    addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin, -                dwarf::DW_FORM_ref4, AbsDIE); +    VariableCU->addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin, +                       dwarf::DW_FORM_ref4, AbsDIE);    else { -    addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); -    addSourceLine(VariableDie, DV->getVariable()); +    VariableCU->addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, +                          Name); +    VariableCU->addSourceLine(VariableDie, DV->getVariable());      // Add variable type. -    addType(VariableDie, DV->getType()); +    VariableCU->addType(VariableDie, DV->getType());    }    if (Tag == dwarf::DW_TAG_formal_parameter && DV->getType().isArtificial()) -    addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); +    VariableCU->addUInt(VariableDie, dwarf::DW_AT_artificial,  +                        dwarf::DW_FORM_flag, 1);    else if (DIVariable(DV->getVariable()).isArtificial()) -    addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); +    VariableCU->addUInt(VariableDie, dwarf::DW_AT_artificial,  +                        dwarf::DW_FORM_flag, 1);    if (Scope->isAbstractScope()) {      DV->setDIE(VariableDie); @@ -1718,7 +679,7 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {    unsigned Offset = DV->getDotDebugLocOffset();    if (Offset != ~0U) { -    addLabel(VariableDie, dwarf::DW_AT_location, dwarf::DW_FORM_data4, +    VariableCU->addLabel(VariableDie, dwarf::DW_AT_location, dwarf::DW_FORM_data4,               Asm->GetTempSymbol("debug_loc", Offset));      DV->setDIE(VariableDie);      UseDotDebugLocEntry.insert(VariableDie); @@ -1738,22 +699,30 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {          const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();          if (DVInsn->getOperand(1).isImm() &&              TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) { -          addVariableAddress(DV, VariableDie, DVInsn->getOperand(1).getImm()); -          updated = true; -        } else -          updated = addRegisterAddress(VariableDie, RegOp); +          unsigned FrameReg = 0; +          const TargetFrameLowering *TFI = Asm->TM.getFrameLowering(); +          int Offset =  +            TFI->getFrameIndexReference(*Asm->MF,  +                                        DVInsn->getOperand(1).getImm(),  +                                        FrameReg); +          MachineLocation Location(FrameReg, Offset); +          VariableCU->addVariableAddress(DV, VariableDie, Location); +           +        } else if (RegOp.getReg()) +          VariableCU->addVariableAddress(DV, VariableDie,  +                                         MachineLocation(RegOp.getReg())); +        updated = true;        }        else if (DVInsn->getOperand(0).isImm()) -        updated = addConstantValue(VariableDie, DVInsn->getOperand(0)); +        updated = VariableCU->addConstantValue(VariableDie,  +                                               DVInsn->getOperand(0));        else if (DVInsn->getOperand(0).isFPImm())          updated = -          addConstantFPValue(VariableDie, DVInsn->getOperand(0)); +          VariableCU->addConstantFPValue(VariableDie, DVInsn->getOperand(0));      } else { -      MachineLocation Location = Asm->getDebugValueLocation(DVInsn); -      if (Location.getReg()) { -        addAddress(VariableDie, dwarf::DW_AT_location, Location); -        updated = true; -      } +      VariableCU->addVariableAddress(DV, VariableDie,  +                                     Asm->getDebugValueLocation(DVInsn)); +      updated = true;      }      if (!updated) {        // If variableDie is not updated then DBG_VALUE instruction does not @@ -1767,15 +736,21 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {    // .. else use frame index, if available.    int FI = 0; -  if (findVariableFrameIndex(DV, &FI)) -    addVariableAddress(DV, VariableDie, FI); -   +  if (findVariableFrameIndex(DV, &FI)) { +    unsigned FrameReg = 0; +    const TargetFrameLowering *TFI = Asm->TM.getFrameLowering(); +    int Offset =  +      TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg); +    MachineLocation Location(FrameReg, Offset); +    VariableCU->addVariableAddress(DV, VariableDie, Location); +  } +    DV->setDIE(VariableDie);    return VariableDie;  } -void DwarfDebug::addPubTypes(DISubprogram SP) { +void CompileUnit::addPubTypes(DISubprogram SP) {    DICompositeType SPTy = SP.getType();    unsigned SPTag = SPTy.getTag();    if (SPTag != dwarf::DW_TAG_subroutine_type) @@ -1789,9 +764,8 @@ void DwarfDebug::addPubTypes(DISubprogram SP) {      DICompositeType CATy = getDICompositeType(ATy);      if (DIDescriptor(CATy).Verify() && !CATy.getName().empty()          && !CATy.isForwardDecl()) { -      CompileUnit *TheCU = getCompileUnit(CATy); -      if (DIEEntry *Entry = TheCU->getDIEEntry(CATy)) -        TheCU->addGlobalType(CATy.getName(), Entry->getEntry()); +      if (DIEEntry *Entry = getDIEEntry(CATy)) +        addGlobalType(CATy.getName(), Entry->getEntry());      }    }  } @@ -1802,6 +776,14 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {      return NULL;    SmallVector <DIE *, 8> Children; + +  // Collect arguments for current function. +  if (Scope == CurrentFnDbgScope) +    for (unsigned i = 0, N = CurrentFnArguments.size(); i < N; ++i) +      if (DbgVariable *ArgDV = CurrentFnArguments[i]) +        if (DIE *Arg = constructVariableDIE(ArgDV, Scope)) +          Children.push_back(Arg); +    // Collect lexical scope childrens first.    const SmallVector<DbgVariable *, 8> &Variables = Scope->getDbgVariables();    for (unsigned i = 0, N = Variables.size(); i < N; ++i) @@ -1841,7 +823,7 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {      ScopeDIE->addChild(*I);    if (DS.isSubprogram()) -    addPubTypes(DISubprogram(DS)); +    getCompileUnit(DS)->addPubTypes(DISubprogram(DS));   return ScopeDIE;  } @@ -1851,10 +833,21 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {  /// in the SourceIds map. This can update DirectoryNames and SourceFileNames  /// maps as well. -unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName){ +unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName,  +                                         StringRef DirName) {    // If FE did not provide a file name, then assume stdin.    if (FileName.empty()) -    return GetOrCreateSourceID("<stdin>"); +    return GetOrCreateSourceID("<stdin>", StringRef()); + +  // MCStream expects full path name as filename. +  if (!DirName.empty() && !FileName.startswith("/")) { +    std::string FullPathName(DirName.data()); +    if (!DirName.endswith("/")) +      FullPathName += "/"; +    FullPathName += FileName.data(); +    // Here FullPathName will be copied into StringMap by GetOrCreateSourceID. +    return GetOrCreateSourceID(StringRef(FullPathName), StringRef()); +  }    StringMapEntry<unsigned> &Entry = SourceIdMap.GetOrCreateValue(FileName);    if (Entry.getValue()) @@ -1864,19 +857,18 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName){    Entry.setValue(SrcId);    // Print out a .file directive to specify files for .loc directives. -  Asm->OutStreamer.EmitDwarfFileDirective(SrcId, FileName); +  Asm->OutStreamer.EmitDwarfFileDirective(SrcId, Entry.getKey());    return SrcId;  }  /// getOrCreateNameSpace - Create a DIE for DINameSpace. -DIE *DwarfDebug::getOrCreateNameSpace(DINameSpace NS) { -  CompileUnit *TheCU = getCompileUnit(NS); -  DIE *NDie = TheCU->getDIE(NS); +DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) { +  DIE *NDie = getDIE(NS);    if (NDie)      return NDie;    NDie = new DIE(dwarf::DW_TAG_namespace); -  TheCU->insertDIE(NS, NDie); +  insertDIE(NS, NDie);    if (!NS.getName().empty())      addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName());    addSourceLine(NDie, NS); @@ -1890,40 +882,40 @@ void DwarfDebug::constructCompileUnit(const MDNode *N) {    DICompileUnit DIUnit(N);    StringRef FN = DIUnit.getFilename();    StringRef Dir = DIUnit.getDirectory(); -  unsigned ID = GetOrCreateSourceID(FN); +  unsigned ID = GetOrCreateSourceID(FN, Dir);    DIE *Die = new DIE(dwarf::DW_TAG_compile_unit); -  addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string, -            DIUnit.getProducer()); -  addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2, -          DIUnit.getLanguage()); -  addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN); +  CompileUnit *NewCU = new CompileUnit(ID, Die, Asm, this); +  NewCU->addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string, +                   DIUnit.getProducer()); +  NewCU->addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2, +                 DIUnit.getLanguage()); +  NewCU->addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);    // Use DW_AT_entry_pc instead of DW_AT_low_pc/DW_AT_high_pc pair. This    // simplifies debug range entries. -  addUInt(Die, dwarf::DW_AT_entry_pc, dwarf::DW_FORM_addr, 0); +  NewCU->addUInt(Die, dwarf::DW_AT_entry_pc, dwarf::DW_FORM_addr, 0);    // DW_AT_stmt_list is a offset of line number information for this    // compile unit in debug_line section.    if (Asm->MAI->doesDwarfUsesAbsoluteLabelForStmtList()) -    addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_addr, -             Asm->GetTempSymbol("section_line")); +    NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_addr, +                    Asm->GetTempSymbol("section_line"));    else -    addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0); +    NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);    if (!Dir.empty()) -    addString(Die, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string, Dir); +    NewCU->addString(Die, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string, Dir);    if (DIUnit.isOptimized()) -    addUInt(Die, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1); +    NewCU->addUInt(Die, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);    StringRef Flags = DIUnit.getFlags();    if (!Flags.empty()) -    addString(Die, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string, Flags); - +    NewCU->addString(Die, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string, Flags); +      unsigned RVer = DIUnit.getRunTimeVersion();    if (RVer) -    addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers, +    NewCU->addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,              dwarf::DW_FORM_data1, RVer); -  CompileUnit *NewCU = new CompileUnit(ID, Die);    if (!FirstCU)      FirstCU = NewCU;    CUMap.insert(std::make_pair(N, NewCU)); @@ -2019,14 +1011,15 @@ void DwarfDebug::constructGlobalVariableDIE(const MDNode *N) {    bool isGlobalVariable = GV.getGlobal() != NULL;    // Add name. -  addString(VariableDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, -            GV.getDisplayName()); +  TheCU->addString(VariableDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, +                   GV.getDisplayName());    StringRef LinkageName = GV.getLinkageName();    if (!LinkageName.empty() && isGlobalVariable) -    addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string, -              getRealLinkageName(LinkageName)); +    TheCU->addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,  +                     dwarf::DW_FORM_string, +                     getRealLinkageName(LinkageName));    // Add type. -  addType(VariableDIE, GTy); +  TheCU->addType(VariableDIE, GTy);    if (GTy.isCompositeType() && !GTy.getName().empty()        && !GTy.isForwardDecl()) {      DIEEntry *Entry = TheCU->getDIEEntry(GTy); @@ -2035,22 +1028,22 @@ void DwarfDebug::constructGlobalVariableDIE(const MDNode *N) {    }    // Add scoping info.    if (!GV.isLocalToUnit()) { -    addUInt(VariableDIE, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); +    TheCU->addUInt(VariableDIE, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);      // Expose as global.       TheCU->addGlobal(GV.getName(), VariableDIE);    }    // Add line number info. -  addSourceLine(VariableDIE, GV); +  TheCU->addSourceLine(VariableDIE, GV);    // Add to map.    TheCU->insertDIE(N, VariableDIE);    // Add to context owner.    DIDescriptor GVContext = GV.getContext(); -  addToContextOwner(VariableDIE, GVContext); +  TheCU->addToContextOwner(VariableDIE, GVContext);    // Add location.    if (isGlobalVariable) {      DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); -    addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); -    addLabel(Block, 0, dwarf::DW_FORM_udata, +    TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); +    TheCU->addLabel(Block, 0, dwarf::DW_FORM_udata,               Asm->Mang->getSymbol(GV.getGlobal()));      // Do not create specification DIE if context is either compile unit      // or a subprogram. @@ -2058,28 +1051,28 @@ void DwarfDebug::constructGlobalVariableDIE(const MDNode *N) {          !GVContext.isFile() && !isSubprogramContext(GVContext)) {        // Create specification DIE.        DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable); -      addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification, +      TheCU->addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,                    dwarf::DW_FORM_ref4, VariableDIE); -      addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block); -      addUInt(VariableDIE, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); +      TheCU->addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block); +      TheCU->addUInt(VariableDIE, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);        TheCU->addDie(VariableSpecDIE);      } else { -      addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block); +      TheCU->addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);      }     } else if (ConstantInt *CI =                dyn_cast_or_null<ConstantInt>(GV.getConstant())) -    addConstantValue(VariableDIE, CI, isUnsignedDIType(GTy)); +    TheCU->addConstantValue(VariableDIE, CI, isUnsignedDIType(GTy));    else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) {      // GV is a merged global.      DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); -    addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); -    addLabel(Block, 0, dwarf::DW_FORM_udata, -             Asm->Mang->getSymbol(cast<GlobalValue>(CE->getOperand(0)))); +    TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); +    TheCU->addLabel(Block, 0, dwarf::DW_FORM_udata, +                    Asm->Mang->getSymbol(cast<GlobalValue>(CE->getOperand(0))));      ConstantInt *CII = cast<ConstantInt>(CE->getOperand(2)); -    addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); -    addUInt(Block, 0, dwarf::DW_FORM_udata, CII->getZExtValue()); -    addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); -    addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block); +    TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); +    TheCU->addUInt(Block, 0, dwarf::DW_FORM_udata, CII->getZExtValue()); +    TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); +    TheCU->addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);    }    return; @@ -2105,7 +1098,7 @@ void DwarfDebug::constructSubprogramDIE(const MDNode *N) {    TheCU->insertDIE(N, SubprogramDie);    // Add to context owner. -  addToContextOwner(SubprogramDie, SP.getContext()); +  TheCU->addToContextOwner(SubprogramDie, SP.getContext());    // Expose as global.    TheCU->addGlobal(SP.getName(), SubprogramDie); @@ -2160,12 +1153,16 @@ void DwarfDebug::beginModule(Module *M) {    //getOrCreateTypeDIE    if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.enum")) -    for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) -      getOrCreateTypeDIE(DIType(NMD->getOperand(i))); +    for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { +      DIType Ty(NMD->getOperand(i)); +      getCompileUnit(Ty)->getOrCreateTypeDIE(Ty); +    }    if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.ty")) -    for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) -      getOrCreateTypeDIE(DIType(NMD->getOperand(i))); +    for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { +      DIType Ty(NMD->getOperand(i)); +      getCompileUnit(Ty)->getOrCreateTypeDIE(Ty); +    }    // Prime section data.    SectionMap.insert(Asm->getObjFileLowering().getTextSection()); @@ -2216,7 +1213,7 @@ void DwarfDebug::endModule() {    for (SmallPtrSet<DIE *, 4>::iterator AI = InlinedSubprogramDIEs.begin(),           AE = InlinedSubprogramDIEs.end(); AI != AE; ++AI) {      DIE *ISP = *AI; -    addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined); +    FirstCU->addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined);    }    for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(), @@ -2226,7 +1223,8 @@ void DwarfDebug::endModule() {      if (!N) continue;      DIE *NDie = getCompileUnit(N)->getDIE(N);      if (!NDie) continue; -    addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie); +    getCompileUnit(N)->addDIEEntry(SPDie, dwarf::DW_AT_containing_type,  +                                   dwarf::DW_FORM_ref4, NDie);    }    // Standard sections final addresses. @@ -2309,6 +1307,30 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,    return AbsDbgVariable;  } +/// addCurrentFnArgument - If Var is an current function argument that add +/// it in CurrentFnArguments list. +bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, +                                      DbgVariable *Var, DbgScope *Scope) { +  if (Scope != CurrentFnDbgScope)  +    return false; +  DIVariable DV = Var->getVariable(); +  if (DV.getTag() != dwarf::DW_TAG_arg_variable) +    return false; +  unsigned ArgNo = DV.getArgNumber(); +  if (ArgNo == 0)  +    return false; + +  size_t Size = CurrentFnArguments.size(); +  if (Size == 0) +    CurrentFnArguments.resize(MF->getFunction()->arg_size()); +  // llvm::Function argument size is not good indicator of how many +  // arguments does the function have at source level. +  if (ArgNo > Size) +    CurrentFnArguments.resize(ArgNo * 2); +  CurrentFnArguments[ArgNo - 1] = Var; +  return true; +} +  /// collectVariableInfoFromMMITable - Collect variable information from  /// side table maintained by MMI.  void @@ -2337,7 +1359,8 @@ DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction * MF,      DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.second);      DbgVariable *RegVar = new DbgVariable(DV);      recordVariableFrameIndex(RegVar, VP.first); -    Scope->addVariable(RegVar); +    if (!addCurrentFnArgument(MF, RegVar, Scope)) +      Scope->addVariable(RegVar);      if (AbsDbgVariable) {        recordVariableFrameIndex(AbsDbgVariable, VP.first);        VarToAbstractVarMap[RegVar] = AbsDbgVariable; @@ -2349,9 +1372,9 @@ DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction * MF,  /// DBG_VALUE instruction, is in a defined reg.  static bool isDbgValueInDefinedReg(const MachineInstr *MI) {    assert (MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!"); -  if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg()) -    return true; -  return false; +  return MI->getNumOperands() == 3 && +         MI->getOperand(0).isReg() && MI->getOperand(0).getReg() && +         MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0;  }  /// collectVariableInfo - Populate DbgScope entries with variables' info. @@ -2362,41 +1385,21 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,    /// collection info from MMI table.    collectVariableInfoFromMMITable(MF, Processed); -  SmallVector<const MachineInstr *, 8> DbgValues; -  // Collect variable information from DBG_VALUE machine instructions; -  for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end(); -       I != E; ++I) -    for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); -         II != IE; ++II) { -      const MachineInstr *MInsn = II; -      if (!MInsn->isDebugValue()) -        continue; -      DbgValues.push_back(MInsn); -    } - -  // This is a collection of DBV_VALUE instructions describing same variable. -  SmallVector<const MachineInstr *, 4> MultipleValues; -  for(SmallVector<const MachineInstr *, 8>::iterator I = DbgValues.begin(), -        E = DbgValues.end(); I != E; ++I) { -    const MachineInstr *MInsn = *I; -    MultipleValues.clear(); -    if (isDbgValueInDefinedReg(MInsn)) -      MultipleValues.push_back(MInsn); -    DIVariable DV(MInsn->getOperand(MInsn->getNumOperands() - 1).getMetadata()); -    if (Processed.count(DV) != 0) +  for (SmallVectorImpl<const MDNode*>::const_iterator +         UVI = UserVariables.begin(), UVE = UserVariables.end(); UVI != UVE; +         ++UVI) { +    const MDNode *Var = *UVI; +    if (Processed.count(Var))        continue; -    const MachineInstr *PrevMI = MInsn; -    for (SmallVector<const MachineInstr *, 8>::iterator MI = I+1, -           ME = DbgValues.end(); MI != ME; ++MI) { -      const MDNode *Var = -        (*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata(); -      if (Var == DV &&  -          !PrevMI->isIdenticalTo(*MI)) -        MultipleValues.push_back(*MI); -      PrevMI = *MI; -    } +    // History contains relevant DBG_VALUE instructions for Var and instructions +    // clobbering it. +    SmallVectorImpl<const MachineInstr*> &History = DbgValues[Var]; +    if (History.empty()) +      continue; +    const MachineInstr *MInsn = History.front(); +    DIVariable DV(Var);      DbgScope *Scope = NULL;      if (DV.getTag() == dwarf::DW_TAG_arg_variable &&          DISubprogram(DV.getContext()).describes(MF->getFunction())) @@ -2408,32 +1411,29 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,        continue;      Processed.insert(DV); +    assert(MInsn->isDebugValue() && "History must begin with debug value");      DbgVariable *RegVar = new DbgVariable(DV); -    Scope->addVariable(RegVar); +    if (!addCurrentFnArgument(MF, RegVar, Scope)) +      Scope->addVariable(RegVar);      if (DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc())) {        DbgVariableToDbgInstMap[AbsVar] = MInsn;        VarToAbstractVarMap[RegVar] = AbsVar;      } -    if (MultipleValues.size() <= 1) { + +    // Simple ranges that are fully coalesced. +    if (History.size() <= 1 || (History.size() == 2 && +                                MInsn->isIdenticalTo(History.back()))) {        DbgVariableToDbgInstMap[RegVar] = MInsn;        continue;      }      // handle multiple DBG_VALUE instructions describing one variable. -    if (DotDebugLocEntries.empty()) -      RegVar->setDotDebugLocOffset(0); -    else -      RegVar->setDotDebugLocOffset(DotDebugLocEntries.size()); -    const MachineInstr *Begin = NULL; -    const MachineInstr *End = NULL; -    for (SmallVector<const MachineInstr *, 4>::iterator -           MVI = MultipleValues.begin(), MVE = MultipleValues.end(); -         MVI != MVE; ++MVI) { -      if (!Begin) { -        Begin = *MVI; -        continue; -      } -      End = *MVI; +    RegVar->setDotDebugLocOffset(DotDebugLocEntries.size()); + +    for (SmallVectorImpl<const MachineInstr*>::const_iterator +           HI = History.begin(), HE = History.end(); HI != HE; ++HI) { +      const MachineInstr *Begin = *HI; +      assert(Begin->isDebugValue() && "Invalid History entry");        MachineLocation MLoc;        if (Begin->getNumOperands() == 3) {          if (Begin->getOperand(0).isReg() && Begin->getOperand(1).isImm()) @@ -2441,25 +1441,32 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,        } else          MLoc = Asm->getDebugValueLocation(Begin); +      // FIXME: emitDebugLoc only understands registers. +      if (!MLoc.getReg()) +        continue; + +      // Compute the range for a register location.        const MCSymbol *FLabel = getLabelBeforeInsn(Begin); -      const MCSymbol *SLabel = getLabelBeforeInsn(End); -      if (MLoc.getReg()) -        DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc)); - -      Begin = End; -      if (MVI + 1 == MVE) { -        // If End is the last instruction then its value is valid -        // until the end of the funtion. -        MachineLocation EMLoc; -        if (End->getNumOperands() == 3) { -          if (End->getOperand(0).isReg() && Begin->getOperand(1).isImm()) -          EMLoc.set(Begin->getOperand(0).getReg(), Begin->getOperand(1).getImm()); -        } else -          EMLoc = Asm->getDebugValueLocation(End); -        if (EMLoc.getReg())  -          DotDebugLocEntries. -            push_back(DotDebugLocEntry(SLabel, FunctionEndSym, EMLoc)); +      const MCSymbol *SLabel = 0; + +      if (HI + 1 == HE) +        // If Begin is the last instruction in History then its value is valid +        // until the end of the function. +        SLabel = FunctionEndSym; +      else { +        const MachineInstr *End = HI[1]; +        if (End->isDebugValue()) +          SLabel = getLabelBeforeInsn(End); +        else { +          // End is a normal instruction clobbering the range. +          SLabel = getLabelAfterInsn(End); +          assert(SLabel && "Forgot label after clobber instruction"); +          ++HI; +        }        } + +      // The value is valid until the next DBG_VALUE or clobber. +      DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc, Var));      }      DotDebugLocEntries.push_back(DotDebugLocEntry());    } @@ -2480,66 +1487,74 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,  /// getLabelBeforeInsn - Return Label preceding the instruction.  const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) { -  DenseMap<const MachineInstr *, MCSymbol *>::iterator I = -    LabelsBeforeInsn.find(MI); -  if (I == LabelsBeforeInsn.end()) -    // FunctionBeginSym always preceeds all the instruction in current function. -    return FunctionBeginSym; -  return I->second; +  MCSymbol *Label = LabelsBeforeInsn.lookup(MI); +  assert(Label && "Didn't insert label before instruction"); +  return Label;  }  /// getLabelAfterInsn - Return Label immediately following the instruction.  const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) { -  DenseMap<const MachineInstr *, MCSymbol *>::iterator I = -    LabelsAfterInsn.find(MI); -  if (I == LabelsAfterInsn.end()) -    return NULL; -  return I->second; +  return LabelsAfterInsn.lookup(MI);  }  /// beginInstruction - Process beginning of an instruction.  void DwarfDebug::beginInstruction(const MachineInstr *MI) { -  if (InsnNeedsLabel.count(MI) == 0) { -    LabelsBeforeInsn[MI] = PrevLabel; -    return; +  // Check if source location changes, but ignore DBG_VALUE locations. +  if (!MI->isDebugValue()) { +    DebugLoc DL = MI->getDebugLoc(); +    if (DL != PrevInstLoc && (!DL.isUnknown() || UnknownLocations)) { +      PrevInstLoc = DL; +      if (!DL.isUnknown()) { +        const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext()); +        recordSourceLine(DL.getLine(), DL.getCol(), Scope); +      } else +        recordSourceLine(0, 0, 0); +    }    } -  // Check location. -  DebugLoc DL = MI->getDebugLoc(); -  if (!DL.isUnknown()) { -    const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext()); -    PrevLabel = recordSourceLine(DL.getLine(), DL.getCol(), Scope); -    PrevInstLoc = DL; -    LabelsBeforeInsn[MI] = PrevLabel; -    return; -  } +  // Insert labels where requested. +  DenseMap<const MachineInstr*, MCSymbol*>::iterator I = +    LabelsBeforeInsn.find(MI); -  // If location is unknown then use temp label for this DBG_VALUE -  // instruction. -  if (MI->isDebugValue()) { -    PrevLabel = MMI->getContext().CreateTempSymbol(); -    Asm->OutStreamer.EmitLabel(PrevLabel); -    LabelsBeforeInsn[MI] = PrevLabel; +  // No label needed. +  if (I == LabelsBeforeInsn.end())      return; -  } -  if (UnknownLocations) { -    PrevLabel = recordSourceLine(0, 0, 0); -    LabelsBeforeInsn[MI] = PrevLabel; +  // Label already assigned. +  if (I->second)      return; -  } -  assert (0 && "Instruction is not processed!"); +  if (!PrevLabel) { +    PrevLabel = MMI->getContext().CreateTempSymbol(); +    Asm->OutStreamer.EmitLabel(PrevLabel); +  } +  I->second = PrevLabel;  }  /// endInstruction - Process end of an instruction.  void DwarfDebug::endInstruction(const MachineInstr *MI) { -  if (InsnsEndScopeSet.count(MI) != 0) { -    // Emit a label if this instruction ends a scope. -    MCSymbol *Label = MMI->getContext().CreateTempSymbol(); -    Asm->OutStreamer.EmitLabel(Label); -    LabelsAfterInsn[MI] = Label; +  // Don't create a new label after DBG_VALUE instructions. +  // They don't generate code. +  if (!MI->isDebugValue()) +    PrevLabel = 0; + +  DenseMap<const MachineInstr*, MCSymbol*>::iterator I = +    LabelsAfterInsn.find(MI); + +  // No label needed. +  if (I == LabelsAfterInsn.end()) +    return; + +  // Label already assigned. +  if (I->second) +    return; + +  // We need a label after this instruction. +  if (!PrevLabel) { +    PrevLabel = MMI->getContext().CreateTempSymbol(); +    Asm->OutStreamer.EmitLabel(PrevLabel);    } +  I->second = PrevLabel;  }  /// getOrCreateDbgScope - Create DbgScope for the scope. @@ -2799,7 +1814,8 @@ void DwarfDebug::identifyScopeMarkers() {             RE = Ranges.end(); RI != RE; ++RI) {        assert(RI->first && "DbgRange does not have first instruction!");        assert(RI->second && "DbgRange does not have second instruction!"); -      InsnsEndScopeSet.insert(RI->second); +      requestLabelBeforeInsn(RI->first); +      requestLabelAfterInsn(RI->second);      }    }  } @@ -2877,45 +1893,145 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {    recordSourceLine(Line, Col, TheScope); +  assert(UserVariables.empty() && DbgValues.empty() && "Maps weren't cleaned"); +    /// ProcessedArgs - Collection of arguments already processed.    SmallPtrSet<const MDNode *, 8> ProcessedArgs; -  DebugLoc PrevLoc; +  const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo(); + +  /// LiveUserVar - Map physreg numbers to the MDNode they contain. +  std::vector<const MDNode*> LiveUserVar(TRI->getNumRegs()); +    for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); -       I != E; ++I) +       I != E; ++I) { +    bool AtBlockEntry = true;      for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();           II != IE; ++II) {        const MachineInstr *MI = II; -      DebugLoc DL = MI->getDebugLoc(); +        if (MI->isDebugValue()) {          assert (MI->getNumOperands() > 1 && "Invalid machine instruction!"); -        DIVariable DV(MI->getOperand(MI->getNumOperands() - 1).getMetadata()); -        if (!DV.Verify()) continue; -        // If DBG_VALUE is for a local variable then it needs a label. -        if (DV.getTag() != dwarf::DW_TAG_arg_variable) -          InsnNeedsLabel.insert(MI); -        // DBG_VALUE for inlined functions argument needs a label. -        else if (!DISubprogram(getDISubprogram(DV.getContext())). -                 describes(MF->getFunction())) -          InsnNeedsLabel.insert(MI); -        // DBG_VALUE indicating argument location change needs a label. -        else if (!ProcessedArgs.insert(DV)) -          InsnNeedsLabel.insert(MI); + +        // Keep track of user variables. +        const MDNode *Var = +          MI->getOperand(MI->getNumOperands() - 1).getMetadata(); + +        // Variable is in a register, we need to check for clobbers. +        if (isDbgValueInDefinedReg(MI)) +          LiveUserVar[MI->getOperand(0).getReg()] = Var; + +        // Check the history of this variable. +        SmallVectorImpl<const MachineInstr*> &History = DbgValues[Var]; +        if (History.empty()) { +          UserVariables.push_back(Var); +          // The first mention of a function argument gets the FunctionBeginSym +          // label, so arguments are visible when breaking at function entry. +          DIVariable DV(Var); +          if (DV.Verify() && DV.getTag() == dwarf::DW_TAG_arg_variable && +              DISubprogram(getDISubprogram(DV.getContext())) +                .describes(MF->getFunction())) +            LabelsBeforeInsn[MI] = FunctionBeginSym; +        } else { +          // We have seen this variable before. Try to coalesce DBG_VALUEs. +          const MachineInstr *Prev = History.back(); +          if (Prev->isDebugValue()) { +            // Coalesce identical entries at the end of History. +            if (History.size() >= 2 && +                Prev->isIdenticalTo(History[History.size() - 2])) +              History.pop_back(); + +            // Terminate old register assignments that don't reach MI; +            MachineFunction::const_iterator PrevMBB = Prev->getParent(); +            if (PrevMBB != I && (!AtBlockEntry || llvm::next(PrevMBB) != I) && +                isDbgValueInDefinedReg(Prev)) { +              // Previous register assignment needs to terminate at the end of +              // its basic block. +              MachineBasicBlock::const_iterator LastMI = +                PrevMBB->getLastNonDebugInstr(); +              if (LastMI == PrevMBB->end()) +                // Drop DBG_VALUE for empty range. +                History.pop_back(); +              else { +                // Terminate after LastMI. +                History.push_back(LastMI); +              } +            } +          } +        } +        History.push_back(MI);        } else { -        // If location is unknown then instruction needs a location only if -        // UnknownLocations flag is set. -        if (DL.isUnknown()) { -          if (UnknownLocations && !PrevLoc.isUnknown()) -            InsnNeedsLabel.insert(MI); -        } else if (DL != PrevLoc) -          // Otherwise, instruction needs a location only if it is new location. -          InsnNeedsLabel.insert(MI); +        // Not a DBG_VALUE instruction. +        if (!MI->isLabel()) +          AtBlockEntry = false; + +        // Check if the instruction clobbers any registers with debug vars. +        for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(), +               MOE = MI->operands_end(); MOI != MOE; ++MOI) { +          if (!MOI->isReg() || !MOI->isDef() || !MOI->getReg()) +            continue; +          for (const unsigned *AI = TRI->getOverlaps(MOI->getReg()); +               unsigned Reg = *AI; ++AI) { +            const MDNode *Var = LiveUserVar[Reg]; +            if (!Var) +              continue; +            // Reg is now clobbered. +            LiveUserVar[Reg] = 0; + +            // Was MD last defined by a DBG_VALUE referring to Reg? +            DbgValueHistoryMap::iterator HistI = DbgValues.find(Var); +            if (HistI == DbgValues.end()) +              continue; +            SmallVectorImpl<const MachineInstr*> &History = HistI->second; +            if (History.empty()) +              continue; +            const MachineInstr *Prev = History.back(); +            // Sanity-check: Register assignments are terminated at the end of +            // their block. +            if (!Prev->isDebugValue() || Prev->getParent() != MI->getParent()) +              continue; +            // Is the variable still in Reg? +            if (!isDbgValueInDefinedReg(Prev) || +                Prev->getOperand(0).getReg() != Reg) +              continue; +            // Var is clobbered. Make sure the next instruction gets a label. +            History.push_back(MI); +          } +        }        } +    } +  } + +  for (DbgValueHistoryMap::iterator I = DbgValues.begin(), E = DbgValues.end(); +       I != E; ++I) { +    SmallVectorImpl<const MachineInstr*> &History = I->second; +    if (History.empty()) +      continue; -      if (!DL.isUnknown() || UnknownLocations) -        PrevLoc = DL; +    // Make sure the final register assignments are terminated. +    const MachineInstr *Prev = History.back(); +    if (Prev->isDebugValue() && isDbgValueInDefinedReg(Prev)) { +      const MachineBasicBlock *PrevMBB = Prev->getParent(); +      MachineBasicBlock::const_iterator LastMI = PrevMBB->getLastNonDebugInstr(); +      if (LastMI == PrevMBB->end()) +        // Drop DBG_VALUE for empty range. +        History.pop_back(); +      else { +        // Terminate after LastMI. +        History.push_back(LastMI); +      }      } +    // Request labels for the full history. +    for (unsigned i = 0, e = History.size(); i != e; ++i) { +      const MachineInstr *MI = History[i]; +      if (MI->isDebugValue()) +        requestLabelBeforeInsn(MI); +      else +        requestLabelAfterInsn(MI); +    } +  } +  PrevInstLoc = DebugLoc();    PrevLabel = FunctionBeginSym;  } @@ -2963,8 +2079,9 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {      DIE *CurFnDIE = constructScopeDIE(CurrentFnDbgScope);      if (!DisableFramePointerElim(*MF)) -      addUInt(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr, -              dwarf::DW_FORM_flag, 1); +      getCompileUnit(CurrentFnDbgScope->getScopeNode())->addUInt(CurFnDIE,  +                                                                 dwarf::DW_AT_APPLE_omit_frame_ptr, +                                                                 dwarf::DW_FORM_flag, 1);      DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(), @@ -2973,12 +2090,13 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {    // Clear debug info    CurrentFnDbgScope = NULL; -  InsnNeedsLabel.clear(); +  DeleteContainerPointers(CurrentFnArguments);    DbgVariableToFrameIndexMap.clear();    VarToAbstractVarMap.clear();    DbgVariableToDbgInstMap.clear();    DeleteContainerSeconds(DbgScopeMap); -  InsnsEndScopeSet.clear(); +  UserVariables.clear(); +  DbgValues.clear();    ConcreteScopes.clear();    DeleteContainerSeconds(AbstractScopes);    AbstractScopesList.clear(); @@ -3029,10 +2147,9 @@ DbgScope *DwarfDebug::findDbgScope(const MachineInstr *MInsn) {  /// recordSourceLine - Register a source line with debug info. Returns the  /// unique label that was emitted and which provides correspondence to  /// the source line list. -MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, -                                       const MDNode *S) { +void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S){    StringRef Fn; - +  StringRef Dir;    unsigned Src = 1;    if (S) {      DIDescriptor Scope(S); @@ -3040,27 +2157,26 @@ MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col,      if (Scope.isCompileUnit()) {        DICompileUnit CU(S);        Fn = CU.getFilename(); +      Dir = CU.getDirectory();      } else if (Scope.isFile()) {        DIFile F(S);        Fn = F.getFilename(); +      Dir = F.getDirectory();      } else if (Scope.isSubprogram()) {        DISubprogram SP(S);        Fn = SP.getFilename(); +      Dir = SP.getDirectory();      } else if (Scope.isLexicalBlock()) {        DILexicalBlock DB(S);        Fn = DB.getFilename(); +      Dir = DB.getDirectory();      } else        assert(0 && "Unexpected scope info"); -    Src = GetOrCreateSourceID(Fn); +    Src = GetOrCreateSourceID(Fn, Dir);    } -    Asm->OutStreamer.EmitDwarfLocDirective(Src, Line, Col, DWARF2_FLAG_IS_STMT, -                                         0, 0); - -  MCSymbol *Label = MMI->getContext().CreateTempSymbol(); -  Asm->OutStreamer.EmitLabel(Label); -  return Label; +                                         0, 0, Fn);  }  //===----------------------------------------------------------------------===// @@ -3118,17 +2234,15 @@ DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset, bool Last) {  /// computeSizeAndOffsets - Compute the size and offset of all the DIEs.  ///  void DwarfDebug::computeSizeAndOffsets() { -  unsigned PrevOffset = 0;    for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),           E = CUMap.end(); I != E; ++I) {      // Compute size of compile unit header. -    static unsigned Offset = PrevOffset + +    unsigned Offset =         sizeof(int32_t) + // Length of Compilation Unit Info        sizeof(int16_t) + // DWARF version number        sizeof(int32_t) + // Offset Into Abbrev. Section        sizeof(int8_t);   // Pointer Size (in bytes)      computeSizeAndOffset(I->second->getCUDie(), Offset, true); -    PrevOffset = Offset;    }  } @@ -3289,8 +2403,7 @@ void DwarfDebug::emitDebugInfo() {      unsigned ContentSize = Die->getSize() +        sizeof(int16_t) + // DWARF version number        sizeof(int32_t) + // Offset Into Abbrev. Section -      sizeof(int8_t) +  // Pointer Size (in bytes) -      sizeof(int32_t);  // FIXME - extra pad for gdb bug. +      sizeof(int8_t);   // Pointer Size (in bytes)      Asm->OutStreamer.AddComment("Length of Compilation Unit Info");      Asm->EmitInt32(ContentSize); @@ -3303,12 +2416,6 @@ void DwarfDebug::emitDebugInfo() {      Asm->EmitInt8(Asm->getTargetData().getPointerSize());      emitDIE(Die); -    // FIXME - extra padding for gdb bug. -    Asm->OutStreamer.AddComment("4 extra padding bytes for GDB"); -    Asm->EmitInt8(0); -    Asm->EmitInt8(0); -    Asm->EmitInt8(0); -    Asm->EmitInt8(0);      Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_end", TheCU->getID()));    }  } @@ -3614,32 +2721,38 @@ void DwarfDebug::emitDebugLoc() {      } else {        Asm->OutStreamer.EmitSymbolValue(Entry.Begin, Size, 0);        Asm->OutStreamer.EmitSymbolValue(Entry.End, Size, 0); -      const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); -      unsigned Reg = RI->getDwarfRegNum(Entry.Loc.getReg(), false); -      if (int Offset =  Entry.Loc.getOffset()) { -        // If the value is at a certain offset from frame register then -        // use DW_OP_fbreg. -        unsigned OffsetSize = Offset ? MCAsmInfo::getSLEB128Size(Offset) : 1; +      DIVariable DV(Entry.Variable); +      if (DV.hasComplexAddress()) { +        unsigned N = DV.getNumAddrElements(); +        unsigned i = 0;          Asm->OutStreamer.AddComment("Loc expr size"); -        Asm->EmitInt16(1 + OffsetSize); -        Asm->OutStreamer.AddComment( -          dwarf::OperationEncodingString(dwarf::DW_OP_fbreg)); -        Asm->EmitInt8(dwarf::DW_OP_fbreg); -        Asm->OutStreamer.AddComment("Offset"); -        Asm->EmitSLEB128(Offset); -      } else { -        if (Reg < 32) { -          Asm->OutStreamer.AddComment("Loc expr size"); -          Asm->EmitInt16(1); -          Asm->OutStreamer.AddComment( -            dwarf::OperationEncodingString(dwarf::DW_OP_reg0 + Reg)); -          Asm->EmitInt8(dwarf::DW_OP_reg0 + Reg); +        if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) { +          // If first address element is OpPlus then emit +          // DW_OP_breg + Offset instead of DW_OP_reg + Offset. +          MachineLocation Loc(Entry.Loc.getReg(), DV.getAddrElement(1)); +          Asm->EmitInt16(Asm->getDwarfRegOpSize(Loc) + N - 2); +          Asm->EmitDwarfRegOp(Loc); +//          Asm->EmitULEB128(DV.getAddrElement(1)); +          i = 2;          } else { -          Asm->OutStreamer.AddComment("Loc expr size"); -          Asm->EmitInt16(1 + MCAsmInfo::getULEB128Size(Reg)); -          Asm->EmitInt8(dwarf::DW_OP_regx); -          Asm->EmitULEB128(Reg); +          Asm->EmitInt16(Asm->getDwarfRegOpSize(Entry.Loc) + N); +          Asm->EmitDwarfRegOp(Entry.Loc); +        } + +        // Emit remaining complex address elements. +        for (; i < N; ++i) { +          uint64_t Element = DV.getAddrElement(i); +          if (Element == DIBuilder::OpPlus) { +            Asm->EmitInt8(dwarf::DW_OP_plus_uconst); +            Asm->EmitULEB128(DV.getAddrElement(++i)); +          } else if (Element == DIBuilder::OpDeref) +            Asm->EmitInt8(dwarf::DW_OP_deref); +          else llvm_unreachable("unknown Opcode found in complex address");          } +      } else { +        Asm->OutStreamer.AddComment("Loc expr size"); +        Asm->EmitInt16(Asm->getDwarfRegOpSize(Entry.Loc)); +        Asm->EmitDwarfRegOp(Entry.Loc);        }      }    }  | 
