mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-13 21:05:16 +00:00
Clean up dwarf writer, part 1. This eliminated the horrible recursive getGlobalVariablesUsing and replaced it something readable. It eliminated use of slow UniqueVector and replaced it with StringMap, SmallVector, and DenseMap, etc. It also fixed some non-deterministic behavior.
This is a very minor compile time win. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@65438 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
20babb112c
commit
e3d423244a
@ -84,9 +84,12 @@ public:
|
||||
/// the source line list.
|
||||
unsigned RecordSourceLine(unsigned Line, unsigned Col, unsigned Src);
|
||||
|
||||
/// RecordSource - Register a source file with debug info. Returns an source
|
||||
/// ID.
|
||||
unsigned RecordSource(const std::string &Dir, const std::string &File);
|
||||
/// getOrCreateSourceID - Look up the source id with the given directory and
|
||||
/// source file names. If none currently exists, create a new id and insert it
|
||||
/// in the SourceIds map. This can update DirectoryIds and SourceFileIds maps
|
||||
/// as well.
|
||||
unsigned getOrCreateSourceID(const std::string &DirName,
|
||||
const std::string &FileName);
|
||||
|
||||
/// RecordRegionStart - Indicate the start of a region.
|
||||
unsigned RecordRegionStart(GlobalVariable *V);
|
||||
|
@ -12,11 +12,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/DwarfWriter.h"
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/UniqueVector.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Constants.h"
|
||||
@ -39,6 +34,10 @@
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
using namespace llvm;
|
||||
@ -67,40 +66,6 @@ class DIEValue;
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// Utility routines.
|
||||
///
|
||||
/// 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.
|
||||
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.
|
||||
Result.push_back(GV);
|
||||
} else if (Constant *C = dyn_cast<Constant>(*I)) {
|
||||
// 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.
|
||||
static void
|
||||
getGlobalVariablesUsing(Module &M, const std::string &RootName,
|
||||
std::vector<GlobalVariable*> &Result) {
|
||||
std::vector<const Type*> FieldTypes;
|
||||
FieldTypes.push_back(Type::Int32Ty);
|
||||
FieldTypes.push_back(Type::Int32Ty);
|
||||
|
||||
// Get the GlobalVariable root.
|
||||
GlobalVariable *UseRoot = M.getGlobalVariable(RootName,
|
||||
StructType::get(FieldTypes));
|
||||
|
||||
// If present and linkonce then scan for users.
|
||||
if (UseRoot && UseRoot->hasLinkOnceLinkage())
|
||||
getGlobalVariablesUsing(UseRoot, Result);
|
||||
}
|
||||
|
||||
/// getGlobalVariable - Return either a direct or cast Global value.
|
||||
///
|
||||
static GlobalVariable *getGlobalVariable(Value *V) {
|
||||
@ -138,7 +103,7 @@ public:
|
||||
DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {}
|
||||
|
||||
void Profile(FoldingSetNodeID &ID) const {
|
||||
ID.AddString(std::string(Tag));
|
||||
ID.AddString(Tag);
|
||||
ID.AddInteger(Number);
|
||||
}
|
||||
|
||||
@ -559,7 +524,7 @@ public:
|
||||
ID.AddInteger(isAsIsLabel);
|
||||
ID.AddString(Label);
|
||||
}
|
||||
virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Label); }
|
||||
virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Label.c_str()); }
|
||||
|
||||
#ifndef NDEBUG
|
||||
virtual void print(std::ostream &O) {
|
||||
@ -1172,33 +1137,6 @@ public:
|
||||
unsigned getLabelID() const { return LabelID; }
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// SrcFileInfo - This class is used to track source information.
|
||||
///
|
||||
class SrcFileInfo {
|
||||
unsigned DirectoryID; // Directory ID number.
|
||||
std::string Name; // File name (not including directory.)
|
||||
public:
|
||||
SrcFileInfo(unsigned D, const std::string &N) : DirectoryID(D), Name(N) {}
|
||||
|
||||
// Accessors
|
||||
unsigned getDirectoryID() const { return DirectoryID; }
|
||||
const std::string &getName() const { return Name; }
|
||||
|
||||
/// operator== - Used by UniqueVector to locate entry.
|
||||
///
|
||||
bool operator==(const SrcFileInfo &SI) const {
|
||||
return getDirectoryID() == SI.getDirectoryID() && getName() == SI.getName();
|
||||
}
|
||||
|
||||
/// operator< - Used by UniqueVector to locate entry.
|
||||
///
|
||||
bool operator<(const SrcFileInfo &SI) const {
|
||||
return getDirectoryID() < SI.getDirectoryID() ||
|
||||
(getDirectoryID() == SI.getDirectoryID() && getName() < SI.getName());
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// DbgVariable - This class is used to track local variable information.
|
||||
///
|
||||
@ -1260,9 +1198,13 @@ class DwarfDebug : public Dwarf {
|
||||
// Attributes used to construct specific Dwarf sections.
|
||||
//
|
||||
|
||||
/// DW_CUs - All the compile units involved in this build. The index
|
||||
/// of each entry in this vector corresponds to the sources in MMI.
|
||||
DenseMap<Value *, CompileUnit *> DW_CUs;
|
||||
/// CompileUnitMap - A map of global variables representing compile units to
|
||||
/// compile units.
|
||||
DenseMap<Value *, CompileUnit *> CompileUnitMap;
|
||||
|
||||
/// CompileUnits - All the compile units in this module.
|
||||
///
|
||||
SmallVector<CompileUnit *, 8> CompileUnits;
|
||||
|
||||
/// MainCU - Some platform prefers one compile unit per .o file. In such
|
||||
/// cases, all dies are inserted in MainCU.
|
||||
@ -1276,11 +1218,27 @@ class DwarfDebug : public Dwarf {
|
||||
///
|
||||
std::vector<DIEAbbrev *> Abbreviations;
|
||||
|
||||
/// Directories - Uniquing vector for directories.
|
||||
UniqueVector<std::string> Directories;
|
||||
/// DirectoryIdMap - Directory name to directory id map.
|
||||
///
|
||||
StringMap<unsigned> DirectoryIdMap;
|
||||
|
||||
/// SrcFiles - Uniquing vector for source files.
|
||||
UniqueVector<SrcFileInfo> SrcFiles;
|
||||
/// DirectoryNames - A list of directory names.
|
||||
SmallVector<std::string, 8> DirectoryNames;
|
||||
|
||||
/// SourceFileIdMap - Source file name to source file id map.
|
||||
///
|
||||
StringMap<unsigned> SourceFileIdMap;
|
||||
|
||||
/// SourceFileNames - A list of source file names.
|
||||
SmallVector<std::string, 8> SourceFileNames;
|
||||
|
||||
/// SourceIdMap - Source id map, i.e. pair of directory id and source file
|
||||
/// id mapped to a unique id.
|
||||
DenseMap<std::pair<unsigned, unsigned>, unsigned> SourceIdMap;
|
||||
|
||||
/// SourceIds - Reverse map from source id to directory id + file id pair.
|
||||
///
|
||||
SmallVector<std::pair<unsigned, unsigned>, 8> SourceIds;
|
||||
|
||||
/// Lines - List of of source line correspondence.
|
||||
std::vector<SrcLineInfo> Lines;
|
||||
@ -1434,7 +1392,7 @@ public:
|
||||
Die->AddValue(Attribute, Form, Value);
|
||||
}
|
||||
|
||||
/// AddString - Add a std::string attribute data and value.
|
||||
/// AddString - Add a string attribute data and value.
|
||||
///
|
||||
void AddString(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
const std::string &String) {
|
||||
@ -1691,7 +1649,8 @@ private:
|
||||
AddType(DW_Unit, &Buffer, FromTy);
|
||||
|
||||
// Add name if not anonymous or intermediate type.
|
||||
if (!Name.empty()) AddString(&Buffer, DW_AT_name, DW_FORM_string, Name);
|
||||
if (!Name.empty())
|
||||
AddString(&Buffer, DW_AT_name, DW_FORM_string, Name);
|
||||
|
||||
// Add size if non-zero (derived types might be zero-sized.)
|
||||
if (Size)
|
||||
@ -1782,7 +1741,8 @@ private:
|
||||
}
|
||||
|
||||
// Add name if not anonymous or intermediate type.
|
||||
if (!Name.empty()) AddString(&Buffer, DW_AT_name, DW_FORM_string, Name);
|
||||
if (!Name.empty())
|
||||
AddString(&Buffer, DW_AT_name, DW_FORM_string, Name);
|
||||
|
||||
if (Tag == DW_TAG_enumeration_type || Tag == DW_TAG_structure_type
|
||||
|| Tag == DW_TAG_union_type) {
|
||||
@ -1846,7 +1806,8 @@ private:
|
||||
DIE *ConstructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy) {
|
||||
|
||||
DIE *Enumerator = new DIE(DW_TAG_enumerator);
|
||||
AddString(Enumerator, DW_AT_name, DW_FORM_string, ETy->getName());
|
||||
const std::string &Name = ETy->getName();
|
||||
AddString(Enumerator, DW_AT_name, DW_FORM_string, Name);
|
||||
int64_t Value = ETy->getEnumValue();
|
||||
AddSInt(Enumerator, DW_AT_const_value, DW_FORM_sdata, Value);
|
||||
return Enumerator;
|
||||
@ -1856,7 +1817,8 @@ private:
|
||||
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 &Name = GV.getName();
|
||||
AddString(GVDie, DW_AT_name, DW_FORM_string, Name);
|
||||
const std::string &LinkageName = GV.getLinkageName();
|
||||
if (!LinkageName.empty())
|
||||
AddString(GVDie, DW_AT_MIPS_linkage_name, DW_FORM_string, LinkageName);
|
||||
@ -1870,7 +1832,7 @@ private:
|
||||
/// CreateMemberDIE - Create new member DIE.
|
||||
DIE *CreateMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT) {
|
||||
DIE *MemberDie = new DIE(DT.getTag());
|
||||
std::string Name = DT.getName();
|
||||
const std::string &Name = DT.getName();
|
||||
if (!Name.empty())
|
||||
AddString(MemberDie, DW_AT_name, DW_FORM_string, Name);
|
||||
|
||||
@ -1914,7 +1876,8 @@ private:
|
||||
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 &Name = SP.getName();
|
||||
AddString(SPDie, DW_AT_name, DW_FORM_string, Name);
|
||||
const std::string &LinkageName = SP.getLinkageName();
|
||||
if (!LinkageName.empty())
|
||||
AddString(SPDie, DW_AT_MIPS_linkage_name, DW_FORM_string,
|
||||
@ -1955,7 +1918,7 @@ private:
|
||||
/// FindCompileUnit - Get the compile unit for the given descriptor.
|
||||
///
|
||||
CompileUnit *FindCompileUnit(DICompileUnit Unit) {
|
||||
CompileUnit *DW_Unit = DW_CUs[Unit.getGV()];
|
||||
CompileUnit *DW_Unit = CompileUnitMap[Unit.getGV()];
|
||||
assert(DW_Unit && "Missing compile unit.");
|
||||
return DW_Unit;
|
||||
}
|
||||
@ -1978,7 +1941,8 @@ private:
|
||||
|
||||
// Define variable debug information entry.
|
||||
DIE *VariableDie = new DIE(Tag);
|
||||
AddString(VariableDie, DW_AT_name, DW_FORM_string, VD.getName());
|
||||
const std::string &Name = VD.getName();
|
||||
AddString(VariableDie, DW_AT_name, DW_FORM_string, Name);
|
||||
|
||||
// Add source line info if available.
|
||||
AddSourceLine(VariableDie, &VD);
|
||||
@ -2119,27 +2083,12 @@ private:
|
||||
/// ConstructDefaultDbgScope - Construct a default scope for the subprogram.
|
||||
///
|
||||
void ConstructDefaultDbgScope(MachineFunction *MF) {
|
||||
// Find the correct subprogram descriptor.
|
||||
std::string SPName = "llvm.dbg.subprograms";
|
||||
std::vector<GlobalVariable*> Result;
|
||||
getGlobalVariablesUsing(*M, SPName, Result);
|
||||
|
||||
for (std::vector<GlobalVariable *>::iterator I = Result.begin(),
|
||||
E = Result.end(); I != E; ++I) {
|
||||
DISubprogram SPD(*I);
|
||||
|
||||
if (SPD.getName() == MF->getFunction()->getName()) {
|
||||
// Get the compile unit context.
|
||||
CompileUnit *Unit = MainCU;
|
||||
if (!Unit)
|
||||
Unit = FindCompileUnit(SPD.getCompileUnit());
|
||||
|
||||
// Get the subprogram die.
|
||||
DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV());
|
||||
if (!SPDie)
|
||||
/* A subprogram die may not exist if the corresponding function
|
||||
does not have any debug info. */
|
||||
continue;
|
||||
const char *FnName = MF->getFunction()->getNameStart();
|
||||
if (MainCU) {
|
||||
std::map<std::string, DIE*> &Globals = MainCU->getGlobals();
|
||||
std::map<std::string, DIE*>::iterator GI = Globals.find(FnName);
|
||||
if (GI != Globals.end()) {
|
||||
DIE *SPDie = GI->second;
|
||||
|
||||
// Add the function bounds.
|
||||
AddLabel(SPDie, DW_AT_low_pc, DW_FORM_addr,
|
||||
@ -2151,12 +2100,33 @@ private:
|
||||
AddAddress(SPDie, DW_AT_frame_base, Location);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
for (unsigned i = 0, e = CompileUnits.size(); i != e; ++i) {
|
||||
CompileUnit *Unit = CompileUnits[i];
|
||||
std::map<std::string, DIE*> &Globals = Unit->getGlobals();
|
||||
std::map<std::string, DIE*>::iterator GI = Globals.find(FnName);
|
||||
if (GI != Globals.end()) {
|
||||
DIE *SPDie = GI->second;
|
||||
|
||||
// Add the function bounds.
|
||||
AddLabel(SPDie, DW_AT_low_pc, DW_FORM_addr,
|
||||
DWLabel("func_begin", SubprogramCount));
|
||||
AddLabel(SPDie, DW_AT_high_pc, DW_FORM_addr,
|
||||
DWLabel("func_end", SubprogramCount));
|
||||
|
||||
MachineLocation Location(RI->getFrameRegister(*MF));
|
||||
AddAddress(SPDie, DW_AT_frame_base, Location);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// FIXME: This is causing an abort because C++ mangled names are compared
|
||||
// with their unmangled counterparts. See PR2885. Don't do this assert.
|
||||
assert(0 && "Couldn't find DIE for machine function!");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc
|
||||
@ -2316,9 +2286,8 @@ private:
|
||||
SizeAndOffsetDie(MainCU->getDie(), Offset, true);
|
||||
return;
|
||||
}
|
||||
for (DenseMap<Value *, CompileUnit *>::iterator CI = DW_CUs.begin(),
|
||||
CE = DW_CUs.end(); CI != CE; ++CI) {
|
||||
CompileUnit *Unit = CI->second;
|
||||
for (unsigned i = 0, e = CompileUnits.size(); i != e; ++i) {
|
||||
CompileUnit *Unit = CompileUnits[i];
|
||||
// Compute size of compile unit header
|
||||
unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info
|
||||
sizeof(int16_t) + // DWARF version number
|
||||
@ -2328,45 +2297,47 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
/// EmitDebugInfo - Emit the debug info section.
|
||||
/// EmitDebugInfo / EmitDebugInfoPerCU - Emit the debug info section.
|
||||
///
|
||||
void EmitDebugInfoPerCU(CompileUnit *Unit) {
|
||||
DIE *Die = Unit->getDie();
|
||||
// Emit the compile units header.
|
||||
EmitLabel("info_begin", Unit->getID());
|
||||
// Emit size of content not including length itself
|
||||
unsigned ContentSize = Die->getSize() +
|
||||
sizeof(int16_t) + // DWARF version number
|
||||
sizeof(int32_t) + // Offset Into Abbrev. Section
|
||||
sizeof(int8_t) + // Pointer Size (in bytes)
|
||||
sizeof(int32_t); // FIXME - extra pad for gdb bug.
|
||||
|
||||
Asm->EmitInt32(ContentSize); Asm->EOL("Length of Compilation Unit Info");
|
||||
Asm->EmitInt16(DWARF_VERSION); Asm->EOL("DWARF version number");
|
||||
EmitSectionOffset("abbrev_begin", "section_abbrev", 0, 0, true, false);
|
||||
Asm->EOL("Offset Into Abbrev. Section");
|
||||
Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)");
|
||||
|
||||
EmitDIE(Die);
|
||||
// FIXME - extra padding for gdb bug.
|
||||
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
|
||||
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
|
||||
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
|
||||
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
|
||||
EmitLabel("info_end", Unit->getID());
|
||||
|
||||
Asm->EOL();
|
||||
}
|
||||
|
||||
void EmitDebugInfo() {
|
||||
// Start debug info section.
|
||||
Asm->SwitchToDataSection(TAI->getDwarfInfoSection());
|
||||
|
||||
for (DenseMap<Value *, CompileUnit *>::iterator CI = DW_CUs.begin(),
|
||||
CE = DW_CUs.end(); CI != CE; ++CI) {
|
||||
CompileUnit *Unit = CI->second;
|
||||
if (MainCU)
|
||||
Unit = MainCU;
|
||||
DIE *Die = Unit->getDie();
|
||||
// Emit the compile units header.
|
||||
EmitLabel("info_begin", Unit->getID());
|
||||
// Emit size of content not including length itself
|
||||
unsigned ContentSize = Die->getSize() +
|
||||
sizeof(int16_t) + // DWARF version number
|
||||
sizeof(int32_t) + // Offset Into Abbrev. Section
|
||||
sizeof(int8_t) + // Pointer Size (in bytes)
|
||||
sizeof(int32_t); // FIXME - extra pad for gdb bug.
|
||||
|
||||
Asm->EmitInt32(ContentSize); Asm->EOL("Length of Compilation Unit Info");
|
||||
Asm->EmitInt16(DWARF_VERSION); Asm->EOL("DWARF version number");
|
||||
EmitSectionOffset("abbrev_begin", "section_abbrev", 0, 0, true, false);
|
||||
Asm->EOL("Offset Into Abbrev. Section");
|
||||
Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)");
|
||||
|
||||
EmitDIE(Die);
|
||||
// FIXME - extra padding for gdb bug.
|
||||
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
|
||||
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
|
||||
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
|
||||
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
|
||||
EmitLabel("info_end", Unit->getID());
|
||||
|
||||
Asm->EOL();
|
||||
if (MainCU)
|
||||
return;
|
||||
if (MainCU) {
|
||||
EmitDebugInfoPerCU(MainCU);
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = CompileUnits.size(); i != e; ++i)
|
||||
EmitDebugInfoPerCU(CompileUnits[i]);
|
||||
}
|
||||
|
||||
/// EmitAbbreviations - Emit the abbreviation section.
|
||||
@ -2469,19 +2440,19 @@ private:
|
||||
Asm->EmitInt8(1); Asm->EOL("DW_LNS_fixed_advance_pc arg count");
|
||||
|
||||
// Emit directories.
|
||||
for (unsigned DirectoryID = 1, NDID = Directories.size();
|
||||
DirectoryID <= NDID; ++DirectoryID) {
|
||||
Asm->EmitString(Directories[DirectoryID]); Asm->EOL("Directory");
|
||||
for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) {
|
||||
Asm->EmitString(getSourceDirectoryName(DI));
|
||||
Asm->EOL("Directory");
|
||||
}
|
||||
Asm->EmitInt8(0); Asm->EOL("End of directories");
|
||||
|
||||
// Emit files.
|
||||
for (unsigned SourceID = 1, NSID = SrcFiles.size();
|
||||
SourceID <= NSID; ++SourceID) {
|
||||
const SrcFileInfo &SourceFile = SrcFiles[SourceID];
|
||||
Asm->EmitString(SourceFile.getName());
|
||||
for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) {
|
||||
// Remember source id starts at 1.
|
||||
std::pair<unsigned, unsigned> Id = getSourceDirsectoryAndFileIds(SI);
|
||||
Asm->EmitString(getSourceFileName(Id.second));
|
||||
Asm->EOL("Source");
|
||||
Asm->EmitULEB128Bytes(SourceFile.getDirectoryID());
|
||||
Asm->EmitULEB128Bytes(Id.first);
|
||||
Asm->EOL("Directory #");
|
||||
Asm->EmitULEB128Bytes(0);
|
||||
Asm->EOL("Mod date");
|
||||
@ -2501,7 +2472,8 @@ private:
|
||||
|
||||
if (VerboseAsm) {
|
||||
const Section* S = SectionMap[j + 1];
|
||||
Asm->EOL(std::string("Section ") + S->getName());
|
||||
O << '\t' << TAI->getCommentString() << " Section"
|
||||
<< S->getName() << '\n';
|
||||
} else
|
||||
Asm->EOL();
|
||||
|
||||
@ -2515,16 +2487,16 @@ private:
|
||||
unsigned LabelID = MMI->MappedLabel(LineInfo.getLabelID());
|
||||
if (!LabelID) continue;
|
||||
|
||||
unsigned SourceID = LineInfo.getSourceID();
|
||||
const SrcFileInfo &SourceFile = SrcFiles[SourceID];
|
||||
unsigned DirectoryID = SourceFile.getDirectoryID();
|
||||
if (VerboseAsm)
|
||||
Asm->EOL(Directories[DirectoryID]
|
||||
+ SourceFile.getName()
|
||||
+ ":"
|
||||
+ utostr_32(LineInfo.getLine()));
|
||||
else
|
||||
if (!VerboseAsm)
|
||||
Asm->EOL();
|
||||
else {
|
||||
std::pair<unsigned, unsigned> SourceID =
|
||||
getSourceDirsectoryAndFileIds(LineInfo.getSourceID());
|
||||
O << '\t' << TAI->getCommentString() << ' '
|
||||
<< getSourceDirectoryName(SourceID.first) << ' '
|
||||
<< getSourceFileName(SourceID.second)
|
||||
<<" :" << utostr_32(LineInfo.getLine()) << '\n';
|
||||
}
|
||||
|
||||
// Define the line address.
|
||||
Asm->EmitInt8(0); Asm->EOL("Extended Op");
|
||||
@ -2656,53 +2628,52 @@ private:
|
||||
Asm->EOL();
|
||||
}
|
||||
|
||||
void EmitDebugPubNamesPerCU(CompileUnit *Unit) {
|
||||
EmitDifference("pubnames_end", Unit->getID(),
|
||||
"pubnames_begin", Unit->getID(), true);
|
||||
Asm->EOL("Length of Public Names Info");
|
||||
|
||||
EmitLabel("pubnames_begin", Unit->getID());
|
||||
|
||||
Asm->EmitInt16(DWARF_VERSION); Asm->EOL("DWARF Version");
|
||||
|
||||
EmitSectionOffset("info_begin", "section_info",
|
||||
Unit->getID(), 0, true, false);
|
||||
Asm->EOL("Offset of Compilation Unit Info");
|
||||
|
||||
EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(),
|
||||
true);
|
||||
Asm->EOL("Compilation Unit Length");
|
||||
|
||||
std::map<std::string, DIE *> &Globals = Unit->getGlobals();
|
||||
for (std::map<std::string, DIE *>::iterator GI = Globals.begin(),
|
||||
GE = Globals.end(); GI != GE; ++GI) {
|
||||
const std::string &Name = GI->first;
|
||||
DIE * Entity = GI->second;
|
||||
|
||||
Asm->EmitInt32(Entity->getOffset()); Asm->EOL("DIE offset");
|
||||
Asm->EmitString(Name); Asm->EOL("External Name");
|
||||
}
|
||||
|
||||
Asm->EmitInt32(0); Asm->EOL("End Mark");
|
||||
EmitLabel("pubnames_end", Unit->getID());
|
||||
|
||||
Asm->EOL();
|
||||
}
|
||||
|
||||
/// EmitDebugPubNames - Emit visible names into a debug pubnames section.
|
||||
///
|
||||
void EmitDebugPubNames() {
|
||||
// Start the dwarf pubnames section.
|
||||
Asm->SwitchToDataSection(TAI->getDwarfPubNamesSection());
|
||||
|
||||
for (DenseMap<Value *, CompileUnit *>::iterator CI = DW_CUs.begin(),
|
||||
CE = DW_CUs.end(); CI != CE; ++CI) {
|
||||
CompileUnit *Unit = CI->second;
|
||||
if (MainCU)
|
||||
Unit = MainCU;
|
||||
|
||||
EmitDifference("pubnames_end", Unit->getID(),
|
||||
"pubnames_begin", Unit->getID(), true);
|
||||
Asm->EOL("Length of Public Names Info");
|
||||
|
||||
EmitLabel("pubnames_begin", Unit->getID());
|
||||
|
||||
Asm->EmitInt16(DWARF_VERSION); Asm->EOL("DWARF Version");
|
||||
|
||||
EmitSectionOffset("info_begin", "section_info",
|
||||
Unit->getID(), 0, true, false);
|
||||
Asm->EOL("Offset of Compilation Unit Info");
|
||||
|
||||
EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(),
|
||||
true);
|
||||
Asm->EOL("Compilation Unit Length");
|
||||
|
||||
std::map<std::string, DIE *> &Globals = Unit->getGlobals();
|
||||
|
||||
for (std::map<std::string, DIE *>::iterator GI = Globals.begin(),
|
||||
GE = Globals.end();
|
||||
GI != GE; ++GI) {
|
||||
const std::string &Name = GI->first;
|
||||
DIE * Entity = GI->second;
|
||||
|
||||
Asm->EmitInt32(Entity->getOffset()); Asm->EOL("DIE offset");
|
||||
Asm->EmitString(Name); Asm->EOL("External Name");
|
||||
}
|
||||
|
||||
Asm->EmitInt32(0); Asm->EOL("End Mark");
|
||||
EmitLabel("pubnames_end", Unit->getID());
|
||||
|
||||
Asm->EOL();
|
||||
if (MainCU)
|
||||
return;
|
||||
if (MainCU) {
|
||||
EmitDebugPubNamesPerCU(MainCU);
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = CompileUnits.size(); i != e; ++i)
|
||||
EmitDebugPubNamesPerCU(CompileUnits[i]);
|
||||
}
|
||||
|
||||
/// EmitDebugStr - Emit visible names into a debug str section.
|
||||
@ -2792,122 +2763,160 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void ConstructCompileUnit(GlobalVariable *GV) {
|
||||
DICompileUnit DIUnit(GV);
|
||||
unsigned ID = getOrCreateSourceID(DIUnit.getDirectory(),
|
||||
DIUnit.getFilename());
|
||||
|
||||
DIE *Die = new DIE(DW_TAG_compile_unit);
|
||||
AddSectionOffset(Die, DW_AT_stmt_list, DW_FORM_data4,
|
||||
DWLabel("section_line", 0), DWLabel("section_line", 0),
|
||||
false);
|
||||
AddString(Die, DW_AT_producer, DW_FORM_string, DIUnit.getProducer());
|
||||
AddUInt(Die, DW_AT_language, DW_FORM_data1, DIUnit.getLanguage());
|
||||
AddString(Die, DW_AT_name, DW_FORM_string, DIUnit.getFilename());
|
||||
if (!DIUnit.getDirectory().empty())
|
||||
AddString(Die, DW_AT_comp_dir, DW_FORM_string, DIUnit.getDirectory());
|
||||
if (DIUnit.isOptimized())
|
||||
AddUInt(Die, DW_AT_APPLE_optimized, DW_FORM_flag, 1);
|
||||
const std::string &Flags = DIUnit.getFlags();
|
||||
if (!Flags.empty())
|
||||
AddString(Die, DW_AT_APPLE_flags, DW_FORM_string, Flags);
|
||||
unsigned RVer = DIUnit.getRunTimeVersion();
|
||||
if (RVer)
|
||||
AddUInt(Die, DW_AT_APPLE_major_runtime_vers, DW_FORM_data1, RVer);
|
||||
|
||||
CompileUnit *Unit = new CompileUnit(ID, Die);
|
||||
if (DIUnit.isMain()) {
|
||||
assert(!MainCU && "Multiple main compile units are found!");
|
||||
MainCU = Unit;
|
||||
}
|
||||
CompileUnitMap[DIUnit.getGV()] = Unit;
|
||||
CompileUnits.push_back(Unit);
|
||||
}
|
||||
|
||||
/// ConstructCompileUnits - Create a compile unit DIEs.
|
||||
void ConstructCompileUnits() {
|
||||
std::string CUName = "llvm.dbg.compile_units";
|
||||
std::vector<GlobalVariable*> Result;
|
||||
getGlobalVariablesUsing(*M, CUName, Result);
|
||||
for (std::vector<GlobalVariable *>::iterator RI = Result.begin(),
|
||||
RE = Result.end(); RI != RE; ++RI) {
|
||||
DICompileUnit DIUnit(*RI);
|
||||
unsigned ID = RecordSource(DIUnit.getDirectory(),
|
||||
DIUnit.getFilename());
|
||||
|
||||
DIE *Die = new DIE(DW_TAG_compile_unit);
|
||||
AddSectionOffset(Die, DW_AT_stmt_list, DW_FORM_data4,
|
||||
DWLabel("section_line", 0), DWLabel("section_line", 0),
|
||||
false);
|
||||
AddString(Die, DW_AT_producer, DW_FORM_string, DIUnit.getProducer());
|
||||
AddUInt(Die, DW_AT_language, DW_FORM_data1, DIUnit.getLanguage());
|
||||
AddString(Die, DW_AT_name, DW_FORM_string, DIUnit.getFilename());
|
||||
if (!DIUnit.getDirectory().empty())
|
||||
AddString(Die, DW_AT_comp_dir, DW_FORM_string, DIUnit.getDirectory());
|
||||
if (DIUnit.isOptimized())
|
||||
AddUInt(Die, DW_AT_APPLE_optimized, DW_FORM_flag, 1);
|
||||
const std::string &Flags = DIUnit.getFlags();
|
||||
if (!Flags.empty())
|
||||
AddString(Die, DW_AT_APPLE_flags, DW_FORM_string, Flags);
|
||||
unsigned RVer = DIUnit.getRunTimeVersion();
|
||||
if (RVer)
|
||||
AddUInt(Die, DW_AT_APPLE_major_runtime_vers, DW_FORM_data1, RVer);
|
||||
|
||||
CompileUnit *Unit = new CompileUnit(ID, Die);
|
||||
if (DIUnit.isMain()) {
|
||||
assert(!MainCU && "Multiple main compile units are found!");
|
||||
MainCU = Unit;
|
||||
GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.compile_units");
|
||||
if (!Root)
|
||||
return;
|
||||
assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
|
||||
"Malformed compile unit descriptor anchor type");
|
||||
Constant *RootC = cast<Constant>(*Root->use_begin());
|
||||
assert(RootC->hasNUsesOrMore(1) &&
|
||||
"Malformed compile unit descriptor anchor type");
|
||||
for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
|
||||
UI != UE; ++UI)
|
||||
for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
|
||||
UUI != UUE; ++UUI) {
|
||||
GlobalVariable *GV = cast<GlobalVariable>(*UUI);
|
||||
ConstructCompileUnit(GV);
|
||||
}
|
||||
DW_CUs[DIUnit.getGV()] = Unit;
|
||||
}
|
||||
}
|
||||
|
||||
bool ConstructGlobalVariableDIE(GlobalVariable *GV) {
|
||||
DIGlobalVariable DI_GV(GV);
|
||||
CompileUnit *DW_Unit = MainCU;
|
||||
if (!DW_Unit)
|
||||
DW_Unit = FindCompileUnit(DI_GV.getCompileUnit());
|
||||
|
||||
// Check for pre-existence.
|
||||
DIE *&Slot = DW_Unit->getDieMapSlotFor(DI_GV.getGV());
|
||||
if (Slot)
|
||||
return false;
|
||||
|
||||
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.getGlobal()));
|
||||
AddBlock(VariableDie, DW_AT_location, 0, Block);
|
||||
|
||||
// Add to map.
|
||||
Slot = VariableDie;
|
||||
// Add to context owner.
|
||||
DW_Unit->getDie()->AddChild(VariableDie);
|
||||
// Expose as global. FIXME - need to check external flag.
|
||||
DW_Unit->AddGlobal(DI_GV.getName(), VariableDie);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// ConstructGlobalVariableDIEs - Create DIEs for each of the externally
|
||||
/// visible global variables. Return true if at least one global DIE is
|
||||
/// created.
|
||||
bool ConstructGlobalVariableDIEs() {
|
||||
std::string GVName = "llvm.dbg.global_variables";
|
||||
std::vector<GlobalVariable*> Result;
|
||||
getGlobalVariablesUsing(*M, GVName, Result);
|
||||
bool result = false;
|
||||
for (std::vector<GlobalVariable *>::iterator GVI = Result.begin(),
|
||||
GVE = Result.end(); GVI != GVE; ++GVI) {
|
||||
DIGlobalVariable DI_GV(*GVI);
|
||||
CompileUnit *DW_Unit = MainCU;
|
||||
if (!DW_Unit)
|
||||
DW_Unit = FindCompileUnit(DI_GV.getCompileUnit());
|
||||
GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.global_variables");
|
||||
if (!Root)
|
||||
return false;
|
||||
|
||||
// Check for pre-existence.
|
||||
DIE *&Slot = DW_Unit->getDieMapSlotFor(DI_GV.getGV());
|
||||
if (Slot) continue;
|
||||
assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
|
||||
"Malformed global variable descriptor anchor type");
|
||||
Constant *RootC = cast<Constant>(*Root->use_begin());
|
||||
assert(RootC->hasNUsesOrMore(1) &&
|
||||
"Malformed global variable descriptor anchor type");
|
||||
|
||||
DIE *VariableDie = CreateGlobalVariableDIE(DW_Unit, DI_GV);
|
||||
bool Result = false;
|
||||
for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
|
||||
UI != UE; ++UI)
|
||||
for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
|
||||
UUI != UUE; ++UUI) {
|
||||
GlobalVariable *GV = cast<GlobalVariable>(*UUI);
|
||||
Result |= ConstructGlobalVariableDIE(GV);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
// 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.getGlobal()));
|
||||
AddBlock(VariableDie, DW_AT_location, 0, Block);
|
||||
bool ConstructSubprogram(GlobalVariable *GV) {
|
||||
DISubprogram SP(GV);
|
||||
CompileUnit *Unit = MainCU;
|
||||
if (!Unit)
|
||||
Unit = FindCompileUnit(SP.getCompileUnit());
|
||||
|
||||
//Add to map.
|
||||
Slot = VariableDie;
|
||||
//Add to context owner.
|
||||
DW_Unit->getDie()->AddChild(VariableDie);
|
||||
//Expose as global. FIXME - need to check external flag.
|
||||
DW_Unit->AddGlobal(DI_GV.getName(), VariableDie);
|
||||
|
||||
if (!result)
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
// Check for pre-existence.
|
||||
DIE *&Slot = Unit->getDieMapSlotFor(GV);
|
||||
if (Slot)
|
||||
return false;
|
||||
|
||||
if (!SP.isDefinition())
|
||||
// This is a method declaration which will be handled while
|
||||
// constructing class type.
|
||||
return false;
|
||||
|
||||
DIE *SubprogramDie = CreateSubprogramDIE(Unit, SP);
|
||||
|
||||
// Add to map.
|
||||
Slot = SubprogramDie;
|
||||
// Add to context owner.
|
||||
Unit->getDie()->AddChild(SubprogramDie);
|
||||
// Expose as global.
|
||||
Unit->AddGlobal(SP.getName(), SubprogramDie);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// ConstructSubprograms - Create DIEs for each of the externally visible
|
||||
/// subprograms. Return true if at least one subprogram DIE is created.
|
||||
bool ConstructSubprograms() {
|
||||
std::string SPName = "llvm.dbg.subprograms";
|
||||
std::vector<GlobalVariable*> Result;
|
||||
getGlobalVariablesUsing(*M, SPName, Result);
|
||||
bool result = false;
|
||||
for (std::vector<GlobalVariable *>::iterator RI = Result.begin(),
|
||||
RE = Result.end(); RI != RE; ++RI) {
|
||||
GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.subprograms");
|
||||
if (!Root)
|
||||
return false;
|
||||
|
||||
DISubprogram SP(*RI);
|
||||
CompileUnit *Unit = MainCU;
|
||||
if (!Unit)
|
||||
Unit = FindCompileUnit(SP.getCompileUnit());
|
||||
assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
|
||||
"Malformed subprogram descriptor anchor type");
|
||||
Constant *RootC = cast<Constant>(*Root->use_begin());
|
||||
assert(RootC->hasNUsesOrMore(1) &&
|
||||
"Malformed subprogram descriptor anchor type");
|
||||
|
||||
// Check for pre-existence.
|
||||
DIE *&Slot = Unit->getDieMapSlotFor(SP.getGV());
|
||||
if (Slot) continue;
|
||||
|
||||
if (!SP.isDefinition())
|
||||
// This is a method declaration which will be handled while
|
||||
// constructing class type.
|
||||
continue;
|
||||
|
||||
DIE *SubprogramDie = CreateSubprogramDIE(Unit, SP);
|
||||
|
||||
//Add to map.
|
||||
Slot = SubprogramDie;
|
||||
//Add to context owner.
|
||||
Unit->getDie()->AddChild(SubprogramDie);
|
||||
//Expose as global.
|
||||
Unit->AddGlobal(SP.getName(), SubprogramDie);
|
||||
|
||||
if (!result)
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
bool Result = false;
|
||||
for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
|
||||
UI != UE; ++UI)
|
||||
for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
|
||||
UUI != UUE; ++UUI) {
|
||||
GlobalVariable *GV = cast<GlobalVariable>(*UUI);
|
||||
Result |= ConstructSubprogram(GV);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
public:
|
||||
@ -2940,7 +2949,7 @@ public:
|
||||
// Create all the compile unit DIEs.
|
||||
ConstructCompileUnits();
|
||||
|
||||
if (DW_CUs.empty())
|
||||
if (CompileUnits.empty())
|
||||
return;
|
||||
|
||||
// Create DIEs for each of the externally visible global variables.
|
||||
@ -2964,9 +2973,12 @@ public:
|
||||
// Print out .file directives to specify files for .loc directives. These
|
||||
// are printed out early so that they precede any .loc directives.
|
||||
if (TAI->hasDotLocAndDotFile()) {
|
||||
for (unsigned i = 1, e = SrcFiles.size(); i <= e; ++i) {
|
||||
sys::Path FullPath(Directories[SrcFiles[i].getDirectoryID()]);
|
||||
bool AppendOk = FullPath.appendComponent(SrcFiles[i].getName());
|
||||
for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) {
|
||||
// Remember source id starts at 1.
|
||||
std::pair<unsigned, unsigned> Id = getSourceDirsectoryAndFileIds(i);
|
||||
sys::Path FullPath(getSourceDirectoryName(Id.first));
|
||||
bool AppendOk =
|
||||
FullPath.appendComponent(getSourceFileName(Id.second));
|
||||
assert(AppendOk && "Could not append filename to directory!");
|
||||
AppendOk = false;
|
||||
Asm->EmitFile(i, FullPath.toString());
|
||||
@ -3152,7 +3164,7 @@ public:
|
||||
/// label. Returns a unique label ID used to generate a label and provide
|
||||
/// correspondence to the source line list.
|
||||
unsigned RecordSourceLine(Value *V, unsigned Line, unsigned Col) {
|
||||
CompileUnit *Unit = DW_CUs[V];
|
||||
CompileUnit *Unit = CompileUnitMap[V];
|
||||
assert(Unit && "Unable to find CompileUnit");
|
||||
unsigned ID = MMI->NextLabelID();
|
||||
Lines.push_back(SrcLineInfo(Line, Col, Unit->getID(), ID));
|
||||
@ -3172,12 +3184,77 @@ public:
|
||||
return Lines.size();
|
||||
}
|
||||
|
||||
/// RecordSource - Register a source file with debug info. Returns an source
|
||||
/// ID.
|
||||
unsigned RecordSource(const std::string &Directory,
|
||||
const std::string &File) {
|
||||
unsigned DID = Directories.insert(Directory);
|
||||
return SrcFiles.insert(SrcFileInfo(DID,File));
|
||||
/// getNumSourceDirectories - Return the number of source directories in the
|
||||
/// debug info.
|
||||
unsigned getNumSourceDirectories() const {
|
||||
return DirectoryNames.size();
|
||||
}
|
||||
|
||||
/// getSourceDirectoryName - Return the name of the directory corresponding
|
||||
/// to the id.
|
||||
const std::string &getSourceDirectoryName(unsigned Id) const {
|
||||
return DirectoryNames[Id - 1];
|
||||
}
|
||||
|
||||
/// getNumSourceFiles - Return the number of source files in the debug info.
|
||||
///
|
||||
unsigned getNumSourceFiles() const {
|
||||
return SourceFileNames.size();
|
||||
}
|
||||
|
||||
/// getSourceFileName - Return the name of the source file corresponding
|
||||
/// to the id.
|
||||
const std::string &getSourceFileName(unsigned Id) const {
|
||||
return SourceFileNames[Id - 1];
|
||||
}
|
||||
|
||||
/// getNumSourceIds - Return the number of unique source ids.
|
||||
///
|
||||
unsigned getNumSourceIds() const {
|
||||
return SourceIds.size();
|
||||
}
|
||||
|
||||
/// getSourceDirsectoryAndFileIds - Return the directory and file ids that
|
||||
/// maps to the source id. Source id starts at 1.
|
||||
std::pair<unsigned, unsigned>
|
||||
getSourceDirsectoryAndFileIds(unsigned SId) const {
|
||||
return SourceIds[SId-1];
|
||||
}
|
||||
|
||||
/// getOrCreateSourceID - Look up the source id with the given directory and
|
||||
/// source file names. If none currently exists, create a new id and insert it
|
||||
/// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps
|
||||
/// as well.
|
||||
unsigned getOrCreateSourceID(const std::string &DirName,
|
||||
const std::string &FileName) {
|
||||
unsigned DId;
|
||||
StringMap<unsigned>::iterator DI = DirectoryIdMap.find(DirName);
|
||||
if (DI != DirectoryIdMap.end())
|
||||
DId = DI->getValue();
|
||||
else {
|
||||
DId = DirectoryNames.size() + 1;
|
||||
DirectoryIdMap[DirName] = DId;
|
||||
DirectoryNames.push_back(DirName);
|
||||
}
|
||||
|
||||
unsigned FId;
|
||||
StringMap<unsigned>::iterator FI = SourceFileIdMap.find(FileName);
|
||||
if (FI != SourceFileIdMap.end())
|
||||
FId = FI->getValue();
|
||||
else {
|
||||
FId = SourceFileNames.size() + 1;
|
||||
SourceFileIdMap[FileName] = FId;
|
||||
SourceFileNames.push_back(FileName);
|
||||
}
|
||||
|
||||
DenseMap<std::pair<unsigned, unsigned>, unsigned>::iterator SI =
|
||||
SourceIdMap.find(std::make_pair(DId, FId));
|
||||
if (SI != SourceIdMap.end())
|
||||
return SI->second;
|
||||
unsigned SrcId = SourceIds.size() + 1; // DW_AT_decl_file cannot be 0.
|
||||
SourceIdMap[std::make_pair(DId, FId)] = SrcId;
|
||||
SourceIds.push_back(std::make_pair(DId, FId));
|
||||
return SrcId;
|
||||
}
|
||||
|
||||
/// RecordRegionStart - Indicate the start of a region.
|
||||
@ -3891,7 +3968,7 @@ public:
|
||||
void EndModule() {
|
||||
if (shouldEmitMovesModule || shouldEmitTableModule) {
|
||||
const std::vector<Function *> Personalities = MMI->getPersonalities();
|
||||
for (unsigned i =0; i < Personalities.size(); ++i)
|
||||
for (unsigned i = 0; i < Personalities.size(); ++i)
|
||||
EmitCommonEHFrame(Personalities[i], i);
|
||||
|
||||
for (std::vector<FunctionEHFrameInfo>::iterator I = EHFrames.begin(),
|
||||
@ -4324,11 +4401,13 @@ unsigned DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col,
|
||||
return DD->RecordSourceLine(Line, Col, Src);
|
||||
}
|
||||
|
||||
/// RecordSource - Register a source file with debug info. Returns an source
|
||||
/// ID.
|
||||
unsigned DwarfWriter::RecordSource(const std::string &Dir,
|
||||
const std::string &File) {
|
||||
return DD->RecordSource(Dir, File);
|
||||
/// getOrCreateSourceID - Look up the source id with the given directory and
|
||||
/// source file names. If none currently exists, create a new id and insert it
|
||||
/// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps
|
||||
/// as well.
|
||||
unsigned DwarfWriter::getOrCreateSourceID(const std::string &DirName,
|
||||
const std::string &FileName) {
|
||||
return DD->getOrCreateSourceID(DirName, FileName);
|
||||
}
|
||||
|
||||
/// RecordRegionStart - Indicate the start of a region.
|
||||
|
@ -319,8 +319,8 @@ bool FastISel::SelectCall(User *I) {
|
||||
DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
|
||||
if (DW && DW->ValidDebugInfo(SPI->getContext())) {
|
||||
DICompileUnit CU(cast<GlobalVariable>(SPI->getContext()));
|
||||
unsigned SrcFile = DW->RecordSource(CU.getDirectory(),
|
||||
CU.getFilename());
|
||||
unsigned SrcFile = DW->getOrCreateSourceID(CU.getDirectory(),
|
||||
CU.getFilename());
|
||||
unsigned Line = SPI->getLine();
|
||||
unsigned Col = SPI->getColumn();
|
||||
unsigned ID = DW->RecordSourceLine(Line, Col, SrcFile);
|
||||
@ -361,8 +361,8 @@ bool FastISel::SelectCall(User *I) {
|
||||
// (most?) gdb expects.
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
|
||||
unsigned SrcFile = DW->RecordSource(CompileUnit.getDirectory(),
|
||||
CompileUnit.getFilename());
|
||||
unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(),
|
||||
CompileUnit.getFilename());
|
||||
|
||||
// Record the source line but does not create a label for the normal
|
||||
// function start. It will be emitted at asm emission time. However,
|
||||
|
@ -1287,8 +1287,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
|
||||
GlobalVariable *CU_GV = cast<GlobalVariable>(DSP->getCompileUnit());
|
||||
if (DW && (useDEBUG_LOC || useLABEL) && !CU_GV->isDeclaration()) {
|
||||
DICompileUnit CU(cast<GlobalVariable>(DSP->getCompileUnit()));
|
||||
unsigned SrcFile = DW->RecordSource(CU.getDirectory(),
|
||||
CU.getFilename());
|
||||
unsigned SrcFile = DW->getOrCreateSourceID(CU.getDirectory(),
|
||||
CU.getFilename());
|
||||
|
||||
unsigned Line = DSP->getLine();
|
||||
unsigned Col = DSP->getColumn();
|
||||
|
@ -335,8 +335,8 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf,
|
||||
|
||||
if (DW && DW->ValidDebugInfo(SPI->getContext())) {
|
||||
DICompileUnit CU(cast<GlobalVariable>(SPI->getContext()));
|
||||
unsigned SrcFile = DW->RecordSource(CU.getDirectory(),
|
||||
CU.getFilename());
|
||||
unsigned SrcFile = DW->getOrCreateSourceID(CU.getDirectory(),
|
||||
CU.getFilename());
|
||||
unsigned idx = MF->getOrCreateDebugLocID(SrcFile,
|
||||
SPI->getLine(),
|
||||
SPI->getColumn());
|
||||
@ -354,8 +354,8 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf,
|
||||
if (DW->ValidDebugInfo(SP)) {
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
DICompileUnit CU(Subprogram.getCompileUnit());
|
||||
unsigned SrcFile = DW->RecordSource(CU.getDirectory(),
|
||||
CU.getFilename());
|
||||
unsigned SrcFile = DW->getOrCreateSourceID(CU.getDirectory(),
|
||||
CU.getFilename());
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
DL = DebugLoc::get(MF->getOrCreateDebugLocID(SrcFile, Line, 0));
|
||||
}
|
||||
@ -3892,16 +3892,16 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
DwarfWriter *DW = DAG.getDwarfWriter();
|
||||
DbgStopPointInst &SPI = cast<DbgStopPointInst>(I);
|
||||
if (DW && DW->ValidDebugInfo(SPI.getContext())) {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
DAG.setRoot(DAG.getDbgStopPoint(getRoot(),
|
||||
SPI.getLine(),
|
||||
SPI.getColumn(),
|
||||
SPI.getContext()));
|
||||
DICompileUnit CU(cast<GlobalVariable>(SPI.getContext()));
|
||||
unsigned SrcFile = DW->RecordSource(CU.getDirectory(), CU.getFilename());
|
||||
unsigned idx = DAG.getMachineFunction().
|
||||
getOrCreateDebugLocID(SrcFile,
|
||||
SPI.getLine(),
|
||||
SPI.getColumn());
|
||||
unsigned SrcFile = DW->getOrCreateSourceID(CU.getDirectory(),
|
||||
CU.getFilename());
|
||||
unsigned idx = MF.getOrCreateDebugLocID(SrcFile,
|
||||
SPI.getLine(), SPI.getColumn());
|
||||
setCurDebugLoc(DebugLoc::get(idx));
|
||||
}
|
||||
return 0;
|
||||
@ -3940,10 +3940,11 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
if (SP && DW->ValidDebugInfo(SP)) {
|
||||
// llvm.dbg.func.start implicitly defines a dbg_stoppoint which is
|
||||
// what (most?) gdb expects.
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
|
||||
unsigned SrcFile = DW->RecordSource(CompileUnit.getDirectory(),
|
||||
CompileUnit.getFilename());
|
||||
unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(),
|
||||
CompileUnit.getFilename());
|
||||
|
||||
// Record the source line but does not create a label for the normal
|
||||
// function start. It will be emitted at asm emission time. However,
|
||||
@ -3957,8 +3958,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
getRoot(), LabelID));
|
||||
}
|
||||
|
||||
setCurDebugLoc(DebugLoc::get(DAG.getMachineFunction().
|
||||
getOrCreateDebugLocID(SrcFile, Line, 0)));
|
||||
setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user