aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp61
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h15
2 files changed, 70 insertions, 6 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index f667e31569..8a74a8ee44 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -556,7 +556,7 @@ DIType DwarfDebug::GetBlockByrefType(DIType Ty, std::string Name) {
unsigned tag = Ty.getTag();
if (tag == dwarf::DW_TAG_pointer_type) {
- DIDerivedType DTy = DIDerivedType (Ty.getNode());
+ DIDerivedType DTy = DIDerivedType(Ty.getNode());
subType = DTy.getTypeDerivedFrom();
}
@@ -577,6 +577,56 @@ DIType DwarfDebug::GetBlockByrefType(DIType Ty, std::string Name) {
return Ty;
}
+/// 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) {
+ const DIVariable &VD = DV->getVariable();
+ DIType Ty = VD.getType();
+
+ // Decode the original location, and use that as the start of the byref
+ // variable's location.
+ unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
+ DIEBlock *Block = new DIEBlock();
+
+ if (Location.isReg()) {
+ if (Reg < 32) {
+ AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
+ } else {
+ Reg = Reg - dwarf::DW_OP_reg0;
+ AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
+ 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 = VD.getNumAddrElements(); i < N; ++i) {
+ uint64_t Element = VD.getAddrElement(i);
+
+ if (Element == DIFactory::OpPlus) {
+ AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
+ AddUInt(Block, 0, dwarf::DW_FORM_udata, VD.getAddrElement(++i));
+ } else if (Element == DIFactory::OpDeref) {
+ AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
+ } else llvm_unreachable("unknown DIFactory 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
@@ -649,7 +699,7 @@ void DwarfDebug::AddBlockByrefAddress(DbgVariable *&DV, DIE *Die,
const char *varName = VD.getName();
if (Tag == dwarf::DW_TAG_pointer_type) {
- DIDerivedType DTy = DIDerivedType (Ty.getNode());
+ DIDerivedType DTy = DIDerivedType(Ty.getNode());
TmpTy = DTy.getTypeDerivedFrom();
isPointer = true;
}
@@ -790,7 +840,6 @@ void DwarfDebug::AddType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) {
else {
assert(Ty.isDerivedType() && "Unknown kind of DIType");
ConstructTypeDIE(DW_Unit, Buffer, DIDerivedType(Ty.getNode()));
-
}
// Add debug information entry to entity and appropriate context.
@@ -1187,6 +1236,7 @@ DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) {
AddSourceLine(VariableDie, &VD);
// Add variable type.
+ // FIXME: isBlockByrefVariable should be reformulated in terms of complex addresses instead.
if (VD.isBlockByrefVariable())
AddType(Unit, VariableDie, GetBlockByrefType(VD.getType(), Name));
else
@@ -1200,7 +1250,10 @@ DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) {
Location.set(RI->getFrameRegister(*MF),
RI->getFrameIndexOffset(*MF, DV->getFrameIndex()));
- if (VD.isBlockByrefVariable())
+
+ if (VD.hasComplexAddress())
+ AddComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
+ else if (VD.isBlockByrefVariable())
AddBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
else
AddAddress(VariableDie, dwarf::DW_AT_location, Location);
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index f582f9b829..8899529698 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -284,10 +284,20 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {
void AddAddress(DIE *Die, unsigned Attribute,
const MachineLocation &Location);
+ /// AddComplexAddress - Start with the address based on the location provided,
+ /// and generate the DWARF information necessary to find the actual variable
+ /// (navigating the extra location information encoded in the type) based on
+ /// the starting location. Add the DWARF information to the die.
+ ///
+ void AddComplexAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute,
+ const MachineLocation &Location);
+
+ // FIXME: Should be reformulated in terms of AddComplexAddress.
/// 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.
+ /// starting location. Add the DWARF information to the die. Obsolete,
+ /// please use AddComplexAddress instead.
///
void AddBlockByrefAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute,
const MachineLocation &Location);
@@ -459,8 +469,9 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {
void ConstructSubprogram(MDNode *N);
+ // FIXME: This should go away in favor of complex addresses.
/// Find the type the programmer originally declared the variable to be
- /// and return that type.
+ /// and return that type. Obsolete, use GetComplexAddrType instead.
///
DIType GetBlockByrefType(DIType Ty, std::string Name);