Refactoring. Update DbgVarible to handle queries itself.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110600 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel
2010-08-09 21:01:39 +00:00
parent 2f3ffb80fa
commit 8bd11de33e
2 changed files with 93 additions and 82 deletions

View File

@@ -180,6 +180,73 @@ public:
DIE *getDIE() const { return TheDIE; } DIE *getDIE() const { return TheDIE; }
void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; } void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; }
unsigned getDotDebugLocOffset() const { return DotDebugLocOffset; } 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;
}
return Ty;
}
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@@ -517,55 +584,16 @@ void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace NS) {
addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
} }
/* Byref variables, in Blocks, are declared by the programmer as /// addVariableAddress - Add DW_AT_location attribute for a DbgVariable.
"SomeType VarName;", but the compiler creates a void DwarfDebug::addVariableAddress(DbgVariable *&DV, DIE *Die,
__Block_byref_x_VarName struct, and gives the variable VarName unsigned Attribute,
either the struct, or a pointer to the struct, as its type. This const MachineLocation &Location) {
is necessary for various behind-the-scenes things the compiler if (DV->variableHasComplexAddress())
needs to do with by-reference variables in blocks. addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
else if (DV->isBlockByrefVariable())
However, as far as the original *programmer* is concerned, the addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location);
variable should still have type 'SomeType', as originally declared. else
addAddress(Die, dwarf::DW_AT_location, Location);
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. */
/// Find the type the programmer originally declared the variable to be
/// and return that type.
///
DIType DwarfDebug::getBlockByrefType(DIType Ty, std::string Name) {
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 (Name == DT.getName())
return (DT.getTypeDerivedFrom());
}
return Ty;
} }
/// addComplexAddress - Start with the address based on the location provided, /// addComplexAddress - Start with the address based on the location provided,
@@ -576,8 +604,7 @@ DIType DwarfDebug::getBlockByrefType(DIType Ty, std::string Name) {
void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die, void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
unsigned Attribute, unsigned Attribute,
const MachineLocation &Location) { const MachineLocation &Location) {
const DIVariable &VD = DV->getVariable(); DIType Ty = DV->getType();
DIType Ty = VD.getType();
// Decode the original location, and use that as the start of the byref // Decode the original location, and use that as the start of the byref
// variable's location. // variable's location.
@@ -604,12 +631,12 @@ void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset()); addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
} }
for (unsigned i = 0, N = VD.getNumAddrElements(); i < N; ++i) { for (unsigned i = 0, N = DV->getNumAddrElements(); i < N; ++i) {
uint64_t Element = VD.getAddrElement(i); uint64_t Element = DV->getAddrElement(i);
if (Element == DIFactory::OpPlus) { if (Element == DIFactory::OpPlus) {
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
addUInt(Block, 0, dwarf::DW_FORM_udata, VD.getAddrElement(++i)); addUInt(Block, 0, dwarf::DW_FORM_udata, DV->getAddrElement(++i));
} else if (Element == DIFactory::OpDeref) { } else if (Element == DIFactory::OpDeref) {
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
} else llvm_unreachable("unknown DIFactory Opcode"); } else llvm_unreachable("unknown DIFactory Opcode");
@@ -682,13 +709,12 @@ void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die, void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
unsigned Attribute, unsigned Attribute,
const MachineLocation &Location) { const MachineLocation &Location) {
const DIVariable &VD = DV->getVariable(); DIType Ty = DV->getType();
DIType Ty = VD.getType();
DIType TmpTy = Ty; DIType TmpTy = Ty;
unsigned Tag = Ty.getTag(); unsigned Tag = Ty.getTag();
bool isPointer = false; bool isPointer = false;
StringRef varName = VD.getName(); StringRef varName = DV->getName();
if (Tag == dwarf::DW_TAG_pointer_type) { if (Tag == dwarf::DW_TAG_pointer_type) {
DIDerivedType DTy = DIDerivedType(Ty); DIDerivedType DTy = DIDerivedType(Ty);
@@ -1556,16 +1582,14 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
/// constructVariableDIE - Construct a DIE for the given DbgVariable. /// constructVariableDIE - Construct a DIE for the given DbgVariable.
DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) { DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
// Get the descriptor. StringRef Name = DV->getName();
const DIVariable &VD = DV->getVariable();
StringRef Name = VD.getName();
if (Name.empty()) if (Name.empty())
return NULL; return NULL;
// Translate tag to proper Dwarf tag. The result variable is dropped for // Translate tag to proper Dwarf tag. The result variable is dropped for
// now. // now.
unsigned Tag; unsigned Tag;
switch (VD.getTag()) { switch (DV->getTag()) {
case dwarf::DW_TAG_return_variable: case dwarf::DW_TAG_return_variable:
return NULL; return NULL;
case dwarf::DW_TAG_arg_variable: case dwarf::DW_TAG_arg_variable:
@@ -1591,18 +1615,13 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
dwarf::DW_FORM_ref4, AbsDIE); dwarf::DW_FORM_ref4, AbsDIE);
else { else {
addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
addSourceLine(VariableDie, VD); addSourceLine(VariableDie, DV->getVariable());
// Add variable type. // Add variable type.
// FIXME: isBlockByrefVariable should be reformulated in terms of complex addType(VariableDie, DV->getType());
// addresses instead.
if (VD.isBlockByrefVariable())
addType(VariableDie, getBlockByrefType(VD.getType(), Name));
else
addType(VariableDie, VD.getType());
} }
if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial()) if (Tag == dwarf::DW_TAG_formal_parameter && DV->getType().isArtificial())
addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
if (Scope->isAbstractScope()) { if (Scope->isAbstractScope()) {
@@ -1666,13 +1685,7 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
if (findVariableFrameIndex(DV, &FI)) { if (findVariableFrameIndex(DV, &FI)) {
int Offset = RI->getFrameIndexReference(*Asm->MF, FI, FrameReg); int Offset = RI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
Location.set(FrameReg, Offset); Location.set(FrameReg, Offset);
addVariableAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
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);
} }
DV->setDIE(VariableDie); DV->setDIE(VariableDie);
return VariableDie; return VariableDie;

View File

@@ -376,6 +376,10 @@ private:
void addBlockByrefAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute, void addBlockByrefAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute,
const MachineLocation &Location); const MachineLocation &Location);
/// addVariableAddress - Add DW_AT_location attribute for a DbgVariable.
void addVariableAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute,
const MachineLocation &Location);
/// addToContextOwner - Add Die into the list of its context owner's children. /// addToContextOwner - Add Die into the list of its context owner's children.
void addToContextOwner(DIE *Die, DIDescriptor Context); void addToContextOwner(DIE *Die, DIDescriptor Context);
@@ -560,12 +564,6 @@ private:
/// construct SubprogramDIE - Construct subprogram DIE. /// construct SubprogramDIE - Construct subprogram DIE.
void constructSubprogramDIE(const MDNode *N); void constructSubprogramDIE(const 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. Obsolete, use GetComplexAddrType instead.
///
DIType getBlockByrefType(DIType Ty, std::string Name);
/// recordSourceLine - Register a source line with debug info. Returns the /// recordSourceLine - Register a source line with debug info. Returns the
/// unique label that was emitted and which provides correspondence to /// unique label that was emitted and which provides correspondence to
/// the source line list. /// the source line list.