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
This commit is contained in:
Eric Christopher 2014-02-16 08:46:55 +00:00
parent 268e96a8a6
commit 0cefb0ecbc
8 changed files with 184 additions and 77 deletions

View File

@ -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<DIEAbbrevData> &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<DIEAbbrevData> &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
//===----------------------------------------------------------------------===//

View File

@ -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

View File

@ -43,7 +43,7 @@ class MCAsmInfo;
class MCObjectFileInfo;
class DIEAbbrev;
class DIE;
class DIEBlock;
class DIELoc;
class DIEEntry;
//===----------------------------------------------------------------------===//

View File

@ -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<dwarf::Form> Form,
void DwarfUnit::addSInt(DIELoc *Die, Optional<dwarf::Form> 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<GlobalValue>(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<MDString>(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<GlobalValue>(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<Value *, 3> 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);

View File

@ -113,6 +113,9 @@ protected:
/// DIEBlocks - A list of all the DIEBlocks in use.
std::vector<DIEBlock *> DIEBlocks;
/// DIELocs - A list of all the DIELocs in use.
std::vector<DIELoc *> 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<dwarf::Form> 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<dwarf::Form> Form,
int64_t Integer);
void addSInt(DIEBlock *Die, Optional<dwarf::Form> Form, int64_t Integer);
void addSInt(DIELoc *Die, Optional<dwarf::Form> 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

View File

@ -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 }

View File

@ -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")

View File

@ -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