From 0cefb0ecbc995f53fc8724105fa4a42bebbf4110 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Sun, 16 Feb 2014 08:46:55 +0000 Subject: [PATCH] Add a DIELoc class to cover the DW_FORM_exprloc set of expressions alongside DIEBlock and replace uses accordingly. Use DW_FORM_exprloc in DWARF4 and later code. Update testcases. Adding a DIELoc instead of using extra forms inside DIEBlock so that we can keep location expressions separate from other uses. No direct use at the moment, however, it's not a lot of code and using a separately named class keeps it somewhat more obvious what's going on in various locations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201481 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/DIE.cpp | 55 ++++++++++ lib/CodeGen/AsmPrinter/DIE.h | 55 ++++++++-- lib/CodeGen/AsmPrinter/DwarfDebug.h | 2 +- lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 117 ++++++++++++---------- lib/CodeGen/AsmPrinter/DwarfUnit.h | 24 +++-- test/DebugInfo/X86/dbg-merge-loc-entry.ll | 2 +- test/DebugInfo/X86/fission-cu.ll | 4 +- test/DebugInfo/X86/template.ll | 2 +- 8 files changed, 184 insertions(+), 77 deletions(-) diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index 90d46630a90..79c4b438f8e 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -418,6 +418,61 @@ void DIETypeSignature::print(raw_ostream &O) const { void DIETypeSignature::dump() const { print(dbgs()); } #endif +//===----------------------------------------------------------------------===// +// DIELoc Implementation +//===----------------------------------------------------------------------===// + +/// ComputeSize - calculate the size of the location expression. +/// +unsigned DIELoc::ComputeSize(AsmPrinter *AP) { + if (!Size) { + const SmallVectorImpl &AbbrevData = Abbrev.getData(); + for (unsigned i = 0, N = Values.size(); i < N; ++i) + Size += Values[i]->SizeOf(AP, AbbrevData[i].getForm()); + } + + return Size; +} + +/// EmitValue - Emit location data. +/// +void DIELoc::EmitValue(AsmPrinter *Asm, dwarf::Form Form) const { + switch (Form) { + default: llvm_unreachable("Improper form for block"); + case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break; + case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break; + case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break; + case dwarf::DW_FORM_block: + case dwarf::DW_FORM_exprloc: + Asm->EmitULEB128(Size); break; + } + + const SmallVectorImpl &AbbrevData = Abbrev.getData(); + for (unsigned i = 0, N = Values.size(); i < N; ++i) + Values[i]->EmitValue(Asm, AbbrevData[i].getForm()); +} + +/// SizeOf - Determine size of location data in bytes. +/// +unsigned DIELoc::SizeOf(AsmPrinter *AP, dwarf::Form Form) const { + switch (Form) { + case dwarf::DW_FORM_block1: return Size + sizeof(int8_t); + case dwarf::DW_FORM_block2: return Size + sizeof(int16_t); + case dwarf::DW_FORM_block4: return Size + sizeof(int32_t); + case dwarf::DW_FORM_block: + case dwarf::DW_FORM_exprloc: + return Size + MCAsmInfo::getULEB128Size(Size); + default: llvm_unreachable("Improper form for block"); + } +} + +#ifndef NDEBUG +void DIELoc::print(raw_ostream &O) const { + O << "ExprLoc: "; + DIE::print(O, 5); +} +#endif + //===----------------------------------------------------------------------===// // DIEBlock Implementation //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h index 40b496d3adb..a35229da910 100644 --- a/lib/CodeGen/AsmPrinter/DIE.h +++ b/lib/CodeGen/AsmPrinter/DIE.h @@ -197,7 +197,8 @@ namespace llvm { isDelta, isEntry, isTypeSignature, - isBlock + isBlock, + isLoc }; protected: /// Type - Type of data stored in the value. @@ -441,14 +442,53 @@ namespace llvm { }; //===--------------------------------------------------------------------===// - /// DIEBlock - A block of values. Primarily used for location expressions. + /// DIELoc - Represents an expression location. + // + class DIELoc : public DIEValue, public DIE { + unsigned Size; // Size in bytes excluding size header. + public: + DIELoc() : DIEValue(isLoc), DIE(0), Size(0) {} + + /// ComputeSize - Calculate the size of the location expression. + /// + unsigned ComputeSize(AsmPrinter *AP); + + /// BestForm - Choose the best form for data. + /// + dwarf::Form BestForm(unsigned DwarfVersion) const { + if (DwarfVersion > 3) return dwarf::DW_FORM_exprloc; + // Pre-DWARF4 location expressions were blocks and not exprloc. + if ((unsigned char)Size == Size) return dwarf::DW_FORM_block1; + if ((unsigned short)Size == Size) return dwarf::DW_FORM_block2; + if ((unsigned int)Size == Size) return dwarf::DW_FORM_block4; + return dwarf::DW_FORM_block; + } + + /// EmitValue - Emit location data. + /// + virtual void EmitValue(AsmPrinter *AP, dwarf::Form Form) const; + + /// SizeOf - Determine size of location data in bytes. + /// + virtual unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const; + + // Implement isa/cast/dyncast. + static bool classof(const DIEValue *E) { return E->getType() == isLoc; } + +#ifndef NDEBUG + virtual void print(raw_ostream &O) const; +#endif + }; + + //===--------------------------------------------------------------------===// + /// DIEBlock - Represents a block of values. // class DIEBlock : public DIEValue, public DIE { unsigned Size; // Size in bytes excluding size header. public: DIEBlock() : DIEValue(isBlock), DIE(0), Size(0) {} - /// ComputeSize - calculate the size of the block. + /// ComputeSize - Calculate the size of the location expression. /// unsigned ComputeSize(AsmPrinter *AP); @@ -461,22 +501,21 @@ namespace llvm { return dwarf::DW_FORM_block; } - /// EmitValue - Emit block data. + /// EmitValue - Emit location data. /// virtual void EmitValue(AsmPrinter *AP, dwarf::Form Form) const; - /// SizeOf - Determine size of block data in bytes. + /// SizeOf - Determine size of location data in bytes. /// virtual unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const; // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isBlock; } -#ifndef NDEBUG + #ifndef NDEBUG virtual void print(raw_ostream &O) const; -#endif + #endif }; - } // end llvm namespace #endif diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index c1d78587121..def43b9e094 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -43,7 +43,7 @@ class MCAsmInfo; class MCObjectFileInfo; class DIEAbbrev; class DIE; -class DIEBlock; +class DIELoc; class DIEEntry; //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 18070462b4a..933587ad868 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -57,13 +57,14 @@ DwarfCompileUnit::DwarfCompileUnit(unsigned UID, DIE *D, DICompileUnit Node, DwarfTypeUnit::DwarfTypeUnit(unsigned UID, DIE *D, DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) - : DwarfUnit(UID, D, CU.getCUNode(), A, DW, DWU), CU(CU) { -} + : DwarfUnit(UID, D, CU.getCUNode(), A, DW, DWU), CU(CU) {} /// ~Unit - Destructor for compile unit. DwarfUnit::~DwarfUnit() { for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j) DIEBlocks[j]->~DIEBlock(); + for (unsigned j = 0, M = DIELocs.size(); j < M; ++j) + DIELocs[j]->~DIELoc(); } /// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug @@ -171,7 +172,7 @@ void DwarfUnit::addUInt(DIE *Die, dwarf::Attribute Attribute, Die->addValue(Attribute, *Form, Value); } -void DwarfUnit::addUInt(DIEBlock *Block, dwarf::Form Form, uint64_t Integer) { +void DwarfUnit::addUInt(DIE *Block, dwarf::Form Form, uint64_t Integer) { addUInt(Block, (dwarf::Attribute)0, Form, Integer); } @@ -185,7 +186,7 @@ void DwarfUnit::addSInt(DIE *Die, dwarf::Attribute Attribute, Die->addValue(Attribute, *Form, Value); } -void DwarfUnit::addSInt(DIEBlock *Die, Optional Form, +void DwarfUnit::addSInt(DIELoc *Die, Optional Form, int64_t Integer) { addSInt(Die, (dwarf::Attribute)0, Form, Integer); } @@ -225,7 +226,7 @@ void DwarfUnit::addLocalString(DIE *Die, dwarf::Attribute Attribute, /// addExpr - Add a Dwarf expression attribute data and value. /// -void DwarfUnit::addExpr(DIEBlock *Die, dwarf::Form Form, const MCExpr *Expr) { +void DwarfUnit::addExpr(DIELoc *Die, dwarf::Form Form, const MCExpr *Expr) { DIEValue *Value = new (DIEValueAllocator) DIEExpr(Expr); Die->addValue((dwarf::Attribute)0, Form, Value); } @@ -238,8 +239,7 @@ void DwarfUnit::addLabel(DIE *Die, dwarf::Attribute Attribute, dwarf::Form Form, Die->addValue(Attribute, Form, Value); } -void DwarfUnit::addLabel(DIEBlock *Die, dwarf::Form Form, - const MCSymbol *Label) { +void DwarfUnit::addLabel(DIELoc *Die, dwarf::Form Form, const MCSymbol *Label) { addLabel(Die, (dwarf::Attribute)0, Form, Label); } @@ -289,7 +289,7 @@ void DwarfCompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute, /// addOpAddress - Add a dwarf op address data and value using the /// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index. /// -void DwarfUnit::addOpAddress(DIEBlock *Die, const MCSymbol *Sym) { +void DwarfUnit::addOpAddress(DIELoc *Die, const MCSymbol *Sym) { if (!DD->useSplitDwarf()) { addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); addLabel(Die, dwarf::DW_FORM_udata, Sym); @@ -347,6 +347,12 @@ DIE *DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, DIDescriptor N) { /// addBlock - Add block data. /// +void DwarfUnit::addBlock(DIE *Die, dwarf::Attribute Attribute, DIELoc *Loc) { + Loc->ComputeSize(Asm); + DIELocs.push_back(Loc); // Memoize so we can call the destructor later on. + Die->addValue(Attribute, Loc->BestForm(DD->getDwarfVersion()), Loc); +} + void DwarfUnit::addBlock(DIE *Die, dwarf::Attribute Attribute, DIEBlock *Block) { Block->ComputeSize(Asm); @@ -433,7 +439,7 @@ void DwarfUnit::addVariableAddress(const DbgVariable &DV, DIE *Die, } /// addRegisterOp - Add register operand. -void DwarfUnit::addRegisterOp(DIEBlock *TheDie, unsigned Reg) { +void DwarfUnit::addRegisterOp(DIELoc *TheDie, unsigned Reg) { const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); int DWReg = RI->getDwarfRegNum(Reg, false); bool isSubRegister = DWReg < 0; @@ -478,7 +484,7 @@ void DwarfUnit::addRegisterOp(DIEBlock *TheDie, unsigned Reg) { } /// addRegisterOffset - Add register offset. -void DwarfUnit::addRegisterOffset(DIEBlock *TheDie, unsigned Reg, +void DwarfUnit::addRegisterOffset(DIELoc *TheDie, unsigned Reg, int64_t Offset) { const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); unsigned DWReg = RI->getDwarfRegNum(Reg, false); @@ -499,19 +505,19 @@ void DwarfUnit::addRegisterOffset(DIEBlock *TheDie, unsigned Reg, /// provided. void DwarfUnit::addAddress(DIE *Die, dwarf::Attribute Attribute, const MachineLocation &Location, bool Indirect) { - DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc(); if (Location.isReg() && !Indirect) - addRegisterOp(Block, Location.getReg()); + addRegisterOp(Loc, Location.getReg()); else { - addRegisterOffset(Block, Location.getReg(), Location.getOffset()); + addRegisterOffset(Loc, Location.getReg(), Location.getOffset()); if (Indirect && !Location.isReg()) { - addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); + addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); } } // Now attach the location information to the DIE. - addBlock(Die, Attribute, Block); + addBlock(Die, Attribute, Loc); } /// addComplexAddress - Start with the address based on the location provided, @@ -522,34 +528,34 @@ void DwarfUnit::addAddress(DIE *Die, dwarf::Attribute Attribute, void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE *Die, dwarf::Attribute Attribute, const MachineLocation &Location) { - DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc(); unsigned N = DV.getNumAddrElements(); unsigned i = 0; if (Location.isReg()) { 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. - addRegisterOffset(Block, Location.getReg(), DV.getAddrElement(1)); + addRegisterOffset(Loc, Location.getReg(), DV.getAddrElement(1)); i = 2; } else - addRegisterOp(Block, Location.getReg()); + addRegisterOp(Loc, Location.getReg()); } else - addRegisterOffset(Block, Location.getReg(), Location.getOffset()); + addRegisterOffset(Loc, Location.getReg(), Location.getOffset()); for (; i < N; ++i) { uint64_t Element = DV.getAddrElement(i); if (Element == DIBuilder::OpPlus) { - addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); - addUInt(Block, dwarf::DW_FORM_udata, DV.getAddrElement(++i)); + addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); + addUInt(Loc, dwarf::DW_FORM_udata, DV.getAddrElement(++i)); } else if (Element == DIBuilder::OpDeref) { if (!Location.isReg()) - addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); + addUInt(Loc, 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, Block); + addBlock(Die, Attribute, Loc); } /* Byref variables, in Blocks, are declared by the programmer as "SomeType @@ -651,40 +657,40 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE *Die, // Decode the original location, and use that as the start of the byref // variable's location. - DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc(); if (Location.isReg()) - addRegisterOp(Block, Location.getReg()); + addRegisterOp(Loc, Location.getReg()); else - addRegisterOffset(Block, Location.getReg(), Location.getOffset()); + addRegisterOffset(Loc, Location.getReg(), 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, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); + addUInt(Loc, 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, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); - addUInt(Block, dwarf::DW_FORM_udata, forwardingFieldOffset); + addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); + addUInt(Loc, dwarf::DW_FORM_udata, forwardingFieldOffset); } // Now dereference the __forwarding field to get to the real __Block_byref // struct: DW_OP_deref. - addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); + addUInt(Loc, 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, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); - addUInt(Block, dwarf::DW_FORM_udata, varFieldOffset); + addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); + addUInt(Loc, dwarf::DW_FORM_udata, varFieldOffset); } // Now attach the location information to the DIE. - addBlock(Die, Attribute, Block); + addBlock(Die, Attribute, Loc); } /// isTypeSigned - Return true if the type is signed. @@ -788,6 +794,7 @@ void DwarfUnit::addConstantValue(DIE *Die, const MachineOperand &MO, /// addConstantFPValue - Add constant value entry in variable DIE. void DwarfUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) { assert(MO.isFPImm() && "Invalid machine operand!"); + // FIXME-echristo: Use a block here. DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); APFloat FPImm = MO.getFPImm()->getValueAPF(); @@ -1331,12 +1338,12 @@ DwarfUnit::constructTemplateValueParameterDIE(DIE &Buffer, else if (GlobalValue *GV = dyn_cast(Val)) { // For declaration non-type template parameters (such as global values and // functions) - DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); - addOpAddress(Block, Asm->getSymbol(GV)); + DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + addOpAddress(Loc, Asm->getSymbol(GV)); // Emit DW_OP_stack_value to use the address as the immediate value of the // parameter, rather than a pointer to it. - addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value); - addBlock(ParamDIE, dwarf::DW_AT_location, Block); + addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value); + addBlock(ParamDIE, dwarf::DW_AT_location, Loc); } else if (VP.getTag() == dwarf::DW_TAG_GNU_template_template_param) { assert(isa(Val)); addString(ParamDIE, dwarf::DW_AT_GNU_template_name, @@ -1438,7 +1445,7 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) { unsigned VK = SP.getVirtuality(); if (VK) { addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK); - DIEBlock *Block = getDIEBlock(); + DIELoc *Block = getDIELoc(); addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); addUInt(Block, dwarf::DW_FORM_udata, SP.getVirtualIndex()); addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, Block); @@ -1573,7 +1580,7 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) { bool isGlobalVariable = GV.getGlobal() != NULL; if (isGlobalVariable) { addToAccelTable = true; - DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc(); const MCSymbol *Sym = Asm->getSymbol(GV.getGlobal()); if (GV.getGlobal()->isThreadLocal()) { // FIXME: Make this work with -gsplit-dwarf. @@ -1583,22 +1590,22 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) { // Based on GCC's support for TLS: if (!DD->useSplitDwarf()) { // 1) Start with a constNu of the appropriate pointer size - addUInt(Block, dwarf::DW_FORM_data1, + addUInt(Loc, dwarf::DW_FORM_data1, PointerSize == 4 ? dwarf::DW_OP_const4u : dwarf::DW_OP_const8u); // 2) containing the (relocated) offset of the TLS variable // within the module's TLS block. - addExpr(Block, dwarf::DW_FORM_udata, + addExpr(Loc, dwarf::DW_FORM_udata, Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym)); } else { - addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); - addUInt(Block, dwarf::DW_FORM_udata, + addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); + addUInt(Loc, dwarf::DW_FORM_udata, DU->getAddrPoolIndex(Sym, /* TLS */ true)); } // 3) followed by a custom OP to make the debugger do a TLS lookup. - addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address); + addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address); } else { DD->addArangeLabel(SymbolCU(this, Sym)); - addOpAddress(Block, Sym); + addOpAddress(Loc, Sym); } // Do not create specification DIE if context is either compile unit // or a subprogram. @@ -1607,12 +1614,12 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) { // Create specification DIE. VariableSpecDIE = createAndAddDIE(dwarf::DW_TAG_variable, *UnitDie); addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification, VariableDIE); - addBlock(VariableSpecDIE, dwarf::DW_AT_location, Block); + addBlock(VariableSpecDIE, dwarf::DW_AT_location, Loc); // A static member's declaration is already flagged as such. if (!SDMDecl.Verify()) addFlag(VariableDIE, dwarf::DW_AT_declaration); } else { - addBlock(VariableDIE, dwarf::DW_AT_location, Block); + addBlock(VariableDIE, dwarf::DW_AT_location, Loc); } // Add the linkage name. StringRef LinkageName = GV.getLinkageName(); @@ -1634,17 +1641,17 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) { } else if (const ConstantExpr *CE = getMergedGlobalExpr(GV->getOperand(11))) { addToAccelTable = true; // GV is a merged global. - DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc(); Value *Ptr = CE->getOperand(0); MCSymbol *Sym = Asm->getSymbol(cast(Ptr)); DD->addArangeLabel(SymbolCU(this, Sym)); - addOpAddress(Block, Sym); - addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); + addOpAddress(Loc, Sym); + addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); SmallVector Idx(CE->op_begin() + 1, CE->op_end()); - addUInt(Block, dwarf::DW_FORM_udata, + addUInt(Loc, dwarf::DW_FORM_udata, Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx)); - addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); - addBlock(VariableDIE, dwarf::DW_AT_location, Block); + addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); + addBlock(VariableDIE, dwarf::DW_AT_location, Loc); } if (addToAccelTable) { @@ -1848,7 +1855,7 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) { // expression to extract appropriate offset from vtable. // BaseAddr = ObAddr + *((*ObAddr) - Offset) - DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock(); + DIELoc *VBaseLocationDie = new (DIEValueAllocator) DIELoc(); addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup); addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); @@ -1888,7 +1895,7 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) { OffsetInBytes = DT.getOffsetInBits() >> 3; if (DD->getDwarfVersion() <= 2) { - DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock(); + DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc(); addUInt(MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); addUInt(MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes); addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie); diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h index 2fa40cb63cb..370ecbf831e 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -113,6 +113,9 @@ protected: /// DIEBlocks - A list of all the DIEBlocks in use. std::vector DIEBlocks; + + /// DIELocs - A list of all the DIELocs in use. + std::vector DIELocs; /// ContainingTypeMap - This map is used to keep track of subprogram DIEs that /// need DW_AT_containing_type attribute. This attribute points to a DIE that @@ -288,8 +291,8 @@ public: /// kept in DwarfDebug. DIE *getDIE(DIDescriptor D) const; - /// getDIEBlock - Returns a fresh newly allocated DIEBlock. - DIEBlock *getDIEBlock() { return new (DIEValueAllocator) DIEBlock(); } + /// getDIELoc - Returns a fresh newly allocated DIELoc. + DIELoc *getDIELoc() { return new (DIEValueAllocator) DIELoc(); } /// insertDIE - Insert DIE into the map. We delegate the request to DwarfDebug /// when the MDNode can be part of the type system, since DIEs for @@ -308,13 +311,13 @@ public: void addUInt(DIE *Die, dwarf::Attribute Attribute, Optional Form, uint64_t Integer); - void addUInt(DIEBlock *Block, dwarf::Form Form, uint64_t Integer); + void addUInt(DIE *Block, dwarf::Form Form, uint64_t Integer); /// addSInt - Add an signed integer attribute data and value. void addSInt(DIE *Die, dwarf::Attribute Attribute, Optional Form, int64_t Integer); - void addSInt(DIEBlock *Die, Optional Form, int64_t Integer); + void addSInt(DIELoc *Die, Optional Form, int64_t Integer); /// addString - Add a string attribute data and value. void addString(DIE *Die, dwarf::Attribute Attribute, const StringRef Str); @@ -324,13 +327,13 @@ public: const StringRef Str); /// addExpr - Add a Dwarf expression attribute data and value. - void addExpr(DIEBlock *Die, dwarf::Form Form, const MCExpr *Expr); + void addExpr(DIELoc *Die, dwarf::Form Form, const MCExpr *Expr); /// addLabel - Add a Dwarf label attribute data and value. void addLabel(DIE *Die, dwarf::Attribute Attribute, dwarf::Form Form, const MCSymbol *Label); - void addLabel(DIEBlock *Die, dwarf::Form Form, const MCSymbol *Label); + void addLabel(DIELoc *Die, dwarf::Form Form, const MCSymbol *Label); /// addSectionLabel - Add a Dwarf section label attribute data and value. /// @@ -343,7 +346,7 @@ public: /// addOpAddress - Add a dwarf op address data and value using the /// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index. - void addOpAddress(DIEBlock *Die, const MCSymbol *Label); + void addOpAddress(DIELoc *Die, const MCSymbol *Label); /// addSectionDelta - Add a label delta attribute data and value. void addSectionDelta(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Hi, @@ -357,6 +360,9 @@ public: void addDIETypeSignature(DIE *Die, const DwarfTypeUnit &Type); + /// addBlock - Add block data. + void addBlock(DIE *Die, dwarf::Attribute Attribute, DIELoc *Block); + /// addBlock - Add block data. void addBlock(DIE *Die, dwarf::Attribute Attribute, DIEBlock *Block); @@ -389,10 +395,10 @@ public: void addTemplateParams(DIE &Buffer, DIArray TParams); /// addRegisterOp - Add register operand. - void addRegisterOp(DIEBlock *TheDie, unsigned Reg); + void addRegisterOp(DIELoc *TheDie, unsigned Reg); /// addRegisterOffset - Add register offset. - void addRegisterOffset(DIEBlock *TheDie, unsigned Reg, int64_t Offset); + void addRegisterOffset(DIELoc *TheDie, unsigned Reg, int64_t Offset); /// addComplexAddress - Start with the address based on the location provided, /// and generate the DWARF information necessary to find the actual variable diff --git a/test/DebugInfo/X86/dbg-merge-loc-entry.ll b/test/DebugInfo/X86/dbg-merge-loc-entry.ll index 8b619ea8607..016d0a1e9f7 100644 --- a/test/DebugInfo/X86/dbg-merge-loc-entry.ll +++ b/test/DebugInfo/X86/dbg-merge-loc-entry.ll @@ -6,7 +6,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin8" -;CHECK: DW_AT_location{{.*}}(<0x01> 55 ) +;CHECK: DW_AT_location{{.*}}(<0x1> 55 ) %0 = type { i64, i1 } diff --git a/test/DebugInfo/X86/fission-cu.ll b/test/DebugInfo/X86/fission-cu.ll index 8acbced3d32..1482ec27cf6 100644 --- a/test/DebugInfo/X86/fission-cu.ll +++ b/test/DebugInfo/X86/fission-cu.ll @@ -48,7 +48,7 @@ ; CHECK: DW_AT_external DW_FORM_flag_present ; CHECK: DW_AT_decl_file DW_FORM_data1 ; CHECK: DW_AT_decl_line DW_FORM_data1 -; CHECK: DW_AT_location DW_FORM_block1 +; CHECK: DW_AT_location DW_FORM_exprloc ; CHECK: [3] DW_TAG_base_type DW_CHILDREN_no ; CHECK: DW_AT_name DW_FORM_GNU_str_index @@ -80,7 +80,7 @@ ; CHECK: DW_AT_external [DW_FORM_flag_present] (true) ; CHECK: DW_AT_decl_file [DW_FORM_data1] (0x01) ; CHECK: DW_AT_decl_line [DW_FORM_data1] (0x01) -; CHECK: DW_AT_location [DW_FORM_block1] (<0x02> fb 00 ) +; CHECK: DW_AT_location [DW_FORM_exprloc] (<0x2> fb 00 ) ; CHECK: [[TYPE]]: DW_TAG_base_type ; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000003) string = "int") diff --git a/test/DebugInfo/X86/template.ll b/test/DebugInfo/X86/template.ll index 38b5f9c3369..54c351c7bfd 100644 --- a/test/DebugInfo/X86/template.ll +++ b/test/DebugInfo/X86/template.ll @@ -35,7 +35,7 @@ ; The address of the global 'glbl', followed by DW_OP_stack_value (9f), to use ; the value immediately, rather than indirecting through the address. -; CHECK-NEXT: DW_AT_location [DW_FORM_block1]{{ *}}(<0x0a> 03 00 00 00 00 00 00 00 00 9f ) +; CHECK-NEXT: DW_AT_location [DW_FORM_exprloc]{{ *}}(<0xa> 03 00 00 00 00 00 00 00 00 9f ) ; CHECK-NOT: NULL ; CHECK: DW_TAG_GNU_template_template_param -- 2.34.1