//===----------------------------------------------------------------------===//
/// Utility routines.
///
-/// getGlobalVariablesUsing - Return all of the GlobalVariables which have the
-/// specified value in their initializer somewhere.
+/// getGlobalVariablesUsing - Return all of the GlobalVariables which have the
+/// specified value in their initializer somewhere.
static void
getGlobalVariablesUsing(Value *V, std::vector<GlobalVariable*> &Result) {
- // Scan though value users.
+ // Scan though value users.
for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I)) {
- // If the user is a GlobalVariable then add to result.
+ // If the user is a GlobalVariable then add to result.
Result.push_back(GV);
} else if (Constant *C = dyn_cast<Constant>(*I)) {
- // If the user is a constant variable then scan its users
+ // If the user is a constant variable then scan its users.
getGlobalVariablesUsing(C, Result);
}
}
}
-/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
-/// named GlobalVariable.
+/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
+/// named GlobalVariable.
static void
getGlobalVariablesUsing(Module &M, const std::string &RootName,
std::vector<GlobalVariable*> &Result) {
FieldTypes.push_back(Type::Int32Ty);
FieldTypes.push_back(Type::Int32Ty);
- // Get the GlobalVariable root.
+ // Get the GlobalVariable root.
GlobalVariable *UseRoot = M.getGlobalVariable(RootName,
StructType::get(FieldTypes));
- // If present and linkonce then scan for users.
+ // If present and linkonce then scan for users.
if (UseRoot && UseRoot->hasLinkOnceLinkage())
getGlobalVariablesUsing(UseRoot, Result);
}
/// GVToDieMap - Tracks the mapping of unit level debug informaton
/// variables to debug information entries.
- DenseMap<GlobalVariable *, DIE *> GVToDieMap;
+ std::map<GlobalVariable *, DIE *> GVToDieMap;
/// GVToDIEntryMap - Tracks the mapping of unit level debug informaton
/// descriptors to debug information entries using a DIEntry proxy.
- DenseMap<GlobalVariable *, DIEntry *> GVToDIEntryMap;
+ std::map<GlobalVariable *, DIEntry *> GVToDIEntryMap;
/// Globals - A map of globally visible named entities for this unit.
///
///
FoldingSet<DIE> DiesSet;
- /// Dies - List of all dies in the compile unit.
- ///
- std::vector<DIE *> Dies;
-
public:
CompileUnit(unsigned I, DIE *D)
: ID(I), Die(D), GVToDieMap(),
- GVToDIEntryMap(), Globals(), DiesSet(InitDiesSetSize), Dies()
+ GVToDIEntryMap(), Globals(), DiesSet(InitDiesSetSize)
{}
~CompileUnit() {
delete Die;
-
- for (unsigned i = 0, N = Dies.size(); i < N; ++i)
- delete Dies[i];
}
// Accessors.
// Attributes used to construct specific Dwarf sections.
//
- /// CompileUnits - All the compile units involved in this build. The index
+ /// DW_CUs - All the compile units involved in this build. The index
/// of each entry in this vector corresponds to the sources in MMI.
- std::vector<CompileUnit *> CompileUnits;
DenseMap<Value *, CompileUnit *> DW_CUs;
/// AbbreviationsSet - Used to uniquely define abbreviations.
///
std::vector<DIEAbbrev *> Abbreviations;
- /// Directories - Uniquing vector for directories.
+ /// Directories - Uniquing vector for directories.
UniqueVector<std::string> Directories;
- /// SourceFiles - Uniquing vector for source files.
+ /// SourceFiles - Uniquing vector for source files.
UniqueVector<SrcFileInfo> SrcFiles;
/// Lines - List of of source line correspondence.
void AddSourceLine(DIE *Die, const DIVariable *V) {
unsigned FileID = 0;
unsigned Line = V->getLineNumber();
- if (V->getVersion() < DIDescriptor::Version7) {
+ if (V->getVersion() <= LLVMDebugVersion6) {
// Version6 or earlier. Use compile unit info to get file id.
CompileUnit *Unit = FindCompileUnit(V->getCompileUnit());
FileID = Unit->getID();
void AddSourceLine(DIE *Die, const DIGlobal *G) {
unsigned FileID = 0;
unsigned Line = G->getLineNumber();
- if (G->getVersion() < DIDescriptor::Version7) {
+ if (G->getVersion() < LLVMDebugVersion6) {
// Version6 or earlier. Use compile unit info to get file id.
CompileUnit *Unit = FindCompileUnit(G->getCompileUnit());
FileID = Unit->getID();
void AddSourceLine(DIE *Die, const DIType *Ty) {
unsigned FileID = 0;
unsigned Line = Ty->getLineNumber();
- if (Ty->getVersion() < DIDescriptor::Version7) {
+ if (Ty->getVersion() <= LLVMDebugVersion6) {
// Version6 or earlier. Use compile unit info to get file id.
CompileUnit *Unit = FindCompileUnit(Ty->getCompileUnit());
FileID = Unit->getID();
void ConstructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
DICompositeType CTy) {
- /// FIXME - Enable this asap.
- return;
-
- // Get core information.
+ // Get core information.
const std::string &Name = CTy.getName();
uint64_t Size = CTy.getSizeInBits() >> 3;
unsigned Tag = CTy.getTag();
case DW_TAG_array_type:
ConstructArrayTypeDIE(DW_Unit, Buffer, &CTy);
break;
- //FIXME - Enable this.
- // case DW_TAG_enumeration_type:
- // DIArray Elements = CTy.getTypeArray();
- // // Add enumerators to enumeration type.
- // for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i)
- // ConstructEnumTypeDIE(Buffer, &Elements.getElement(i));
- // break;
+ case 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;
+ DIEnumerator Enum(Elements.getElement(i).getGV());
+ ElemDie = ConstructEnumTypeDIE(DW_Unit, &Enum);
+ Buffer.AddChild(ElemDie);
+ }
+ }
+ break;
case DW_TAG_subroutine_type:
{
// Add prototype flag.
DIDescriptor RTy = Elements.getElement(0);
AddType(DW_Unit, &Buffer, DIType(RTy.getGV()));
- //AddType(DW_Unit, &Buffer, Elements.getElement(0));
// Add arguments.
for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
DIE *Arg = new DIE(DW_TAG_formal_parameter);
DIDescriptor Ty = Elements.getElement(i);
- AddType(DW_Unit, &Buffer, DIType(Ty.getGV()));
+ AddType(DW_Unit, Arg, DIType(Ty.getGV()));
Buffer.AddChild(Arg);
}
}
// Add elements to structure type.
for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
DIDescriptor Element = Elements.getElement(i);
+ DIE *ElemDie = NULL;
if (Element.getTag() == dwarf::DW_TAG_subprogram)
- ConstructFieldTypeDIE(DW_Unit, Buffer, DISubprogram(Element.getGV()));
- else if (Element.getTag() == dwarf::DW_TAG_variable)
- ConstructFieldTypeDIE(DW_Unit, Buffer,
- DIGlobalVariable(Element.getGV()));
+ ElemDie = CreateSubprogramDIE(DW_Unit,
+ DISubprogram(Element.getGV()));
+ else if (Element.getTag() == dwarf::DW_TAG_variable) // ???
+ ElemDie = CreateGlobalVariableDIE(DW_Unit,
+ DIGlobalVariable(Element.getGV()));
else {
DIDerivedType DT = DIDerivedType(Element.getGV());
- assert (DT.isDerivedType(DT.getTag()) && "Unexpected strcut element");
- ConstructFieldTypeDIE(DW_Unit, Buffer, DT);
+ assert (DT.isDerivedType(DT.getTag())
+ && "Unexpected struct element type");
+ ElemDie = new DIE(DT.getTag());
+ AddType(DW_Unit, ElemDie, DT);
}
+ Buffer.AddChild(ElemDie);
}
}
break;
if (L != H) {
AddDIEntry(DW_Subrange, DW_AT_type, DW_FORM_ref4, IndexTy);
if (L)
- AddSInt(DW_Subrange, DW_AT_lower_bound, 0, L);
- AddSInt(DW_Subrange, DW_AT_upper_bound, 0, H);
+ AddSInt(DW_Subrange, DW_AT_lower_bound, 0, L);
+ AddSInt(DW_Subrange, DW_AT_upper_bound, 0, H);
}
Buffer.AddChild(DW_Subrange);
}
AddUInt(&Buffer, DW_AT_GNU_vector, DW_FORM_flag, 1);
DIArray Elements = CTy->getTypeArray();
- // FIXME - Enable this.
AddType(DW_Unit, &Buffer, CTy->getTypeDerivedFrom());
// Construct an anonymous type for index type.
/// ConstructEnumTypeDIE - Construct enum type DIE from
/// DIEnumerator.
- void ConstructEnumTypeDIE(CompileUnit *DW_Unit,
- DIE &Buffer, DIEnumerator *ETy) {
+ DIE *ConstructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy) {
DIE *Enumerator = new DIE(DW_TAG_enumerator);
AddString(Enumerator, DW_AT_name, DW_FORM_string, ETy->getName());
int64_t Value = ETy->getEnumValue();
AddSInt(Enumerator, DW_AT_const_value, DW_FORM_sdata, Value);
- Buffer.AddChild(Enumerator);
+ return Enumerator;
}
- /// ConstructFieldTypeDIE - Construct variable DIE for a struct field.
- void ConstructFieldTypeDIE(CompileUnit *DW_Unit,
- DIE &Buffer, DIGlobalVariable V) {
-
- DIE *VariableDie = new DIE(DW_TAG_variable);
- const std::string &LinkageName = V.getLinkageName();
+ /// CreateGlobalVariableDIE - Create new DIE using GV.
+ DIE *CreateGlobalVariableDIE(CompileUnit *DW_Unit, const DIGlobalVariable &GV)
+ {
+ DIE *GVDie = new DIE(DW_TAG_variable);
+ AddString(GVDie, DW_AT_name, DW_FORM_string, GV.getName());
+ const std::string &LinkageName = GV.getLinkageName();
if (!LinkageName.empty())
- AddString(VariableDie, DW_AT_MIPS_linkage_name, DW_FORM_string,
- LinkageName);
- // FIXME - Enable this. AddSourceLine(VariableDie, V);
- AddType(DW_Unit, VariableDie, V.getType());
- if (!V.isLocalToUnit())
- AddUInt(VariableDie, DW_AT_external, DW_FORM_flag, 1);
- AddUInt(VariableDie, DW_AT_declaration, DW_FORM_flag, 1);
- Buffer.AddChild(VariableDie);
- }
-
- /// ConstructFieldTypeDIE - Construct subprogram DIE for a struct field.
- void ConstructFieldTypeDIE(CompileUnit *DW_Unit,
- DIE &Buffer, DISubprogram SP,
- bool IsConstructor = false) {
- DIE *Method = new DIE(DW_TAG_subprogram);
- AddString(Method, DW_AT_name, DW_FORM_string, SP.getName());
+ AddString(GVDie, DW_AT_MIPS_linkage_name, DW_FORM_string, LinkageName);
+ AddType(DW_Unit, GVDie, GV.getType());
+ if (!GV.isLocalToUnit())
+ AddUInt(GVDie, DW_AT_external, DW_FORM_flag, 1);
+ AddSourceLine(GVDie, &GV);
+ return GVDie;
+ }
+
+ /// CreateSubprogramDIE - Create new DIE using SP.
+ DIE *CreateSubprogramDIE(CompileUnit *DW_Unit,
+ const DISubprogram &SP,
+ bool IsConstructor = false) {
+ DIE *SPDie = new DIE(DW_TAG_subprogram);
+ AddString(SPDie, DW_AT_name, DW_FORM_string, SP.getName());
const std::string &LinkageName = SP.getLinkageName();
if (!LinkageName.empty())
- AddString(Method, DW_AT_MIPS_linkage_name, DW_FORM_string, LinkageName);
- // FIXME - Enable this. AddSourceLine(Method, SP);
-
- DICompositeType MTy = SP.getType();
- DIArray Args = MTy.getTypeArray();
+ AddString(SPDie, DW_AT_MIPS_linkage_name, DW_FORM_string,
+ LinkageName);
+ AddSourceLine(SPDie, &SP);
+ DICompositeType SPTy = SP.getType();
+ DIArray Args = SPTy.getTypeArray();
+
// Add Return Type.
if (!IsConstructor)
- AddType(DW_Unit, Method, DIType(Args.getElement(0).getGV()));
-
+ AddType(DW_Unit, SPDie, DIType(Args.getElement(0).getGV()));
+
// Add arguments.
- for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
- DIE *Arg = new DIE(DW_TAG_formal_parameter);
- AddType(DW_Unit, Method, DIType(Args.getElement(i).getGV()));
- AddUInt(Arg, DW_AT_artificial, DW_FORM_flag, 1); // ???
- Method->AddChild(Arg);
- }
-
+ if (!Args.isNull())
+ for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
+ DIE *Arg = new DIE(DW_TAG_formal_parameter);
+ AddType(DW_Unit, Arg, DIType(Args.getElement(i).getGV()));
+ AddUInt(Arg, DW_AT_artificial, DW_FORM_flag, 1); // ???
+ SPDie->AddChild(Arg);
+ }
+
if (!SP.isLocalToUnit())
- AddUInt(Method, DW_AT_external, DW_FORM_flag, 1);
- Buffer.AddChild(Method);
+ AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1);
+ return SPDie;
}
- /// ConstructFieldTypeDIE - Construct derived type DIE for a struct field.
- void ConstructFieldTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
- DIDerivedType DTy) {
- unsigned Tag = DTy.getTag();
- DIE *MemberDie = new DIE(Tag);
- if (!DTy.getName().empty())
- AddString(MemberDie, DW_AT_name, DW_FORM_string, DTy.getName());
- // FIXME - Enable this. AddSourceLine(MemberDie, DTy);
-
- DIType FromTy = DTy.getTypeDerivedFrom();
- AddType(DW_Unit, MemberDie, FromTy);
-
- uint64_t Size = DTy.getSizeInBits();
- uint64_t Offset = DTy.getOffsetInBits();
-
- // FIXME Handle bitfields
-
- // Add size.
- AddUInt(MemberDie, DW_AT_bit_size, 0, Size);
- // Add computation for offset.
- DIEBlock *Block = new DIEBlock();
- AddUInt(Block, 0, DW_FORM_data1, DW_OP_plus_uconst);
- AddUInt(Block, 0, DW_FORM_udata, Offset >> 3);
- AddBlock(MemberDie, DW_AT_data_member_location, 0, Block);
-
- // FIXME Handle DW_AT_accessibility.
-
- Buffer.AddChild(MemberDie);
- }
-
- /// FindCompileUnit - Get the compile unit for the given descriptor.
- ///
+ /// FindCompileUnit - Get the compile unit for the given descriptor.
+ ///
CompileUnit *FindCompileUnit(DICompileUnit Unit) {
CompileUnit *DW_Unit = DW_CUs[Unit.getGV()];
assert(DW_Unit && "Missing compile unit.");
"func_begin", DebugFrameInfo.Number);
Asm->EOL("FDE address range");
- EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves, false);
+ EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves,
+ false);
Asm->EmitAlignment(2, 0, 0, false);
EmitLabel("debug_frame_end", DebugFrameInfo.Number);
Unit->getID(), 0, true, false);
Asm->EOL("Offset of Compilation Unit Info");
- EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(),true);
+ EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(),
+ true);
Asm->EOL("Compilation Unit Length");
std::map<std::string, DIE *> &Globals = Unit->getGlobals();
DIE *&Slot = DW_Unit->getDieMapSlotFor(DI_GV.getGV());
if (Slot) continue;
- DIE *VariableDie = new DIE(DW_TAG_variable);
- AddString(VariableDie, DW_AT_name, DW_FORM_string, DI_GV.getName());
- const std::string &LinkageName = DI_GV.getLinkageName();
- if (!LinkageName.empty())
- AddString(VariableDie, DW_AT_MIPS_linkage_name, DW_FORM_string,
- LinkageName);
- AddType(DW_Unit, VariableDie, DI_GV.getType());
-
- if (!DI_GV.isLocalToUnit())
- AddUInt(VariableDie, DW_AT_external, DW_FORM_flag, 1);
-
- // Add source line info, if available.
- AddSourceLine(VariableDie, &DI_GV);
+ DIE *VariableDie = CreateGlobalVariableDIE(DW_Unit, DI_GV);
// Add address.
DIEBlock *Block = new DIEBlock();
AddUInt(Block, 0, DW_FORM_data1, DW_OP_addr);
AddObjectLabel(Block, 0, DW_FORM_udata,
- Asm->getGlobalLinkName(DI_GV.getGV()));
+ Asm->getGlobalLinkName(DI_GV.getGlobal()));
AddBlock(VariableDie, DW_AT_location, 0, Block);
//Add to map.
DISubprogram SP(*RI);
CompileUnit *Unit = FindCompileUnit(SP.getCompileUnit());
- // Check for pre-existence.
+ // Check for pre-existence.
DIE *&Slot = Unit->getDieMapSlotFor(SP.getGV());
if (Slot) continue;
- DIE *SubprogramDie = new DIE(DW_TAG_subprogram);
- AddString(SubprogramDie, DW_AT_name, DW_FORM_string, SP.getName());
- const std::string &LinkageName = SP.getLinkageName();
- if (!LinkageName.empty())
- AddString(SubprogramDie, DW_AT_MIPS_linkage_name, DW_FORM_string,
- LinkageName);
- DIType SPTy = SP.getType();
- AddType(Unit, SubprogramDie, SPTy);
- if (!SP.isLocalToUnit())
- AddUInt(SubprogramDie, DW_AT_external, DW_FORM_flag, 1);
- AddUInt(SubprogramDie, DW_AT_prototyped, DW_FORM_flag, 1);
-
- AddSourceLine(SubprogramDie, &SP);
+ DIE *SubprogramDie = CreateSubprogramDIE(Unit, SP);
+
//Add to map.
Slot = SubprogramDie;
//Add to context owner.
//
DwarfDebug(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
: Dwarf(OS, A, T, "dbg")
- , CompileUnits()
, AbbreviationsSet(InitAbbreviationsSetSize)
, Abbreviations()
, ValuesSet(InitValuesSetSize)
{
}
virtual ~DwarfDebug() {
- for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i)
- delete CompileUnits[i];
for (unsigned j = 0, M = Values.size(); j < M; ++j)
delete Values[j];
}
/// ValidDebugInfo - Return true if V represents valid debug info value.
bool ValidDebugInfo(Value *V) {
+ if (!V)
+ return false;
+
if (!shouldEmit)
return false;
DIDescriptor DI(GV);
// Check current version. Allow Version6 for now.
unsigned Version = DI.getVersion();
- if (Version != DIDescriptor::Version7 && Version != DIDescriptor::Version6)
+ if (Version != LLVMDebugVersion && Version != LLVMDebugVersion6)
return false;
- //FIXME - Check individual descriptors.
+ unsigned Tag = DI.getTag();
+ switch (Tag) {
+ case DW_TAG_variable:
+ assert (DIVariable(GV).Verify() && "Invalid DebugInfo value");
+ break;
+ case DW_TAG_compile_unit:
+ assert (DICompileUnit(GV).Verify() && "Invalid DebugInfo value");
+ break;
+ case DW_TAG_subprogram:
+ assert (DISubprogram(GV).Verify() && "Invalid DebugInfo value");
+ break;
+ default:
+ break;
+ }
+
return true;
}
// If the corresponding function is static, this should not be
// externally visible.
if (linkage != Function::InternalLinkage &&
- linkage != Function::PrivateLinkage) {
+ linkage != Function::PrivateLinkage) {
if (const char *GlobalEHDirective = TAI->getGlobalEHDirective())
O << GlobalEHDirective << EHFrameInfo.FnName << "\n";
}
// Indicate locations of function specific callee saved registers in
// frame.
- EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, true);
+ EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves,
+ true);
// On Darwin the linker honors the alignment of eh_frame, which means it
// must be 8-byte on 64-bit targets to match what gcc does. Otherwise