Rework adding function names to the dwarf accelerator tables, allow

multiple dies per function and support C++ basenames.

llvm-svn: 144304
This commit is contained in:
Eric Christopher 2011-11-10 19:25:34 +00:00
parent c5c49466a1
commit d9843b34e6
3 changed files with 86 additions and 71 deletions

View File

@ -75,9 +75,15 @@ void DwarfAccelTable::ComputeBucketCount(void) {
void DwarfAccelTable::FinalizeTable(AsmPrinter *Asm, const char *Prefix) {
// Create the individual hash data outputs.
for (StringMap<DIEArray>::const_iterator
for (StringMap<DIEArray>::iterator
EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) {
struct HashData *Entry = new HashData((*EI).getKeyData());
// Unique the entries.
std::sort((*EI).second.begin(), (*EI).second.end());
(*EI).second.erase(std::unique((*EI).second.begin(), (*EI).second.end()),
(*EI).second.end());
for (DIEArray::const_iterator DI = (*EI).second.begin(),
DE = (*EI).second.end();
DI != DE; ++DI)

View File

@ -62,7 +62,7 @@ class CompileUnit {
/// AccelNames - A map of names for the name accelerator table.
///
StringMap<DIE*> AccelNames;
StringMap<std::vector<DIE*> > AccelNames;
StringMap<std::vector<DIE*> > AccelObjC;
StringMap<DIE*> AccelNamespace;
StringMap<DIE*> AccelTypes;
@ -84,7 +84,9 @@ public:
DIE* getCUDie() const { return CUDie.get(); }
const StringMap<DIE*> &getGlobalTypes() const { return GlobalTypes; }
const StringMap<DIE*> &getAccelNames() const { return AccelNames; }
const StringMap<std::vector<DIE*> > &getAccelNames() const {
return AccelNames;
}
const StringMap<std::vector<DIE*> > &getAccelObjC() const {
return AccelObjC;
}
@ -101,7 +103,10 @@ public:
/// addAccelName - Add a new name to the name accelerator table.
void addAccelName(StringRef Name, DIE *Die) { AccelNames[Name] = Die; }
void addAccelName(StringRef Name, DIE *Die) {
std::vector<DIE*> &DIEs = AccelNames[Name];
DIEs.push_back(Die);
}
void addAccelObjC(StringRef Name, DIE *Die) {
std::vector<DIE*> &DIEs = AccelObjC[Name];
DIEs.push_back(Die);

View File

@ -198,6 +198,63 @@ static StringRef getRealLinkageName(StringRef LinkageName) {
return LinkageName;
}
static bool isObjCClass(StringRef Name) {
return Name.startswith("+") || Name.startswith("-");
}
static bool hasObjCCategory(StringRef Name) {
if (!isObjCClass(Name)) return false;
size_t pos = Name.find(')');
if (pos != std::string::npos) {
if (Name[pos+1] != ' ') return false;
return true;
}
return false;
}
static void getObjCClassCategory(StringRef In, StringRef &Class,
StringRef &Category) {
if (!hasObjCCategory(In)) {
Class = In.slice(In.find('[') + 1, In.find(' '));
Category = "";
return;
}
Class = In.slice(In.find('[') + 1, In.find('('));
Category = In.slice(In.find('[') + 1, In.find(' '));
return;
}
static StringRef getObjCMethodName(StringRef In) {
return In.slice(In.find(' ') + 1, In.find(']'));
}
// Add the various names to the Dwarf accelerator table names.
static void addSubprogramNames(CompileUnit *TheCU, DISubprogram SP,
DIE* Die) {
if (!SP.isDefinition()) return;
TheCU->addAccelName(SP.getName(), Die);
// If the linkage name is different than the name, go ahead and output
// that as well into the name table.
if (SP.getLinkageName() != "" && SP.getName() != SP.getLinkageName())
TheCU->addAccelName(SP.getLinkageName(), Die);
// If this is an Objective-C selector name add it to the ObjC accelerator
// too.
if (isObjCClass(SP.getName())) {
StringRef Class, Category;
getObjCClassCategory(SP.getName(), Class, Category);
TheCU->addAccelObjC(Class, Die);
if (Category != "")
TheCU->addAccelObjC(Category, Die);
// Also add the base method name to the name table.
TheCU->addAccelName(getObjCMethodName(SP.getName()), Die);
}
}
/// updateSubprogramScopeDIE - Find DIE for the given subprogram and
/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.
/// If there are global variables in this scope then create and insert
@ -257,6 +314,10 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU,
MachineLocation Location(RI->getFrameRegister(*Asm->MF));
SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
// Add name to the name table, we do this here because we're guaranteed
// to have concrete versions of our DW_TAG_subprogram nodes.
addSubprogramNames(SPCU, SP, SPDie);
return SPDie;
}
@ -384,6 +445,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU,
return ScopeDIE;
}
/// constructScopeDIE - Construct a DIE for this scope.
DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) {
if (!Scope || !Scope->getScopeNode())
@ -441,16 +504,6 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) {
if (DS.isSubprogram())
TheCU->addPubTypes(DISubprogram(DS));
if (DS.isSubprogram() && !Scope->isAbstractScope()) {
DISubprogram SP = DISubprogram(DS);
TheCU->addAccelName(SP.getName(), ScopeDIE);
// If the linkage name is different than the name, go ahead and output
// that as well into the name table.
if (SP.getLinkageName() != "" && SP.getName() != SP.getLinkageName())
TheCU->addAccelName(SP.getLinkageName(), ScopeDIE);
}
return ScopeDIE;
}
@ -531,38 +584,6 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) {
return NewCU;
}
static bool isObjCClass(StringRef Name) {
return Name.startswith("+") || Name.startswith("-");
}
static bool hasObjCCategory(StringRef Name) {
if (!isObjCClass(Name)) return false;
size_t pos = Name.find(')');
if (pos != std::string::npos) {
if (Name[pos+1] != ' ') return false;
return true;
}
return false;
}
static void getObjCClassCategory(StringRef In, StringRef &Class,
StringRef &Category) {
if (!hasObjCCategory(In)) {
Class = In.slice(In.find('[') + 1, In.find(' '));
Category = "";
return;
}
Class = In.slice(In.find('[') + 1, In.find('('));
Category = In.slice(In.find('[') + 1, In.find(' '));
return;
}
static StringRef getObjCMethodName(StringRef In) {
return In.slice(In.find(' ') + 1, In.find(']'));
}
/// construct SubprogramDIE - Construct subprogram DIE.
void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU,
const MDNode *N) {
@ -597,25 +618,6 @@ void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU,
// Add to context owner.
TheCU->addToContextOwner(SubprogramDie, SP.getContext());
// Add to Accel Names
TheCU->addAccelName(SP.getName(), SubprogramDie);
// If the linkage name is different than the name, go ahead and output
// that as well into the name table.
if (SP.getLinkageName() != "" && SP.getName() != SP.getLinkageName())
TheCU->addAccelName(SP.getLinkageName(), SubprogramDie);
// If this is an Objective-C selector name add it to the ObjC accelerator too.
if (isObjCClass(SP.getName())) {
StringRef Class, Category;
getObjCClassCategory(SP.getName(), Class, Category);
TheCU->addAccelObjC(Class, SubprogramDie);
if (Category != "")
TheCU->addAccelObjC(Category, SubprogramDie);
// Also add the base method name to the name table.
TheCU->addAccelName(getObjCMethodName(SP.getName()), SubprogramDie);
}
return;
}
@ -1763,12 +1765,14 @@ void DwarfDebug::emitAccelNames() {
for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
E = CUMap.end(); I != E; ++I) {
CompileUnit *TheCU = I->second;
const StringMap<DIE*> &Names = TheCU->getAccelNames();
for (StringMap<DIE*>::const_iterator
const StringMap<std::vector<DIE*> > &Names = TheCU->getAccelNames();
for (StringMap<std::vector<DIE*> >::const_iterator
GI = Names.begin(), GE = Names.end(); GI != GE; ++GI) {
const char *Name = GI->getKeyData();
DIE *Entity = GI->second;
AT.AddName(Name, Entity);
std::vector<DIE *> Entities = GI->second;
for (std::vector<DIE *>::const_iterator DI = Entities.begin(),
DE = Entities.end(); DI != DE; ++DI)
AT.AddName(Name, (*DI));
}
}