Factor out the code that parses ObjC Method names into a static method

in ObjCLanguageRuntime.
Add the category-free name of symbols to the Symtab name-to-index list.

llvm-svn: 137600
This commit is contained in:
Jim Ingham
2011-08-15 01:32:22 +00:00
parent 127bea8f48
commit ff5f5ff963
4 changed files with 101 additions and 44 deletions

View File

@@ -93,6 +93,12 @@ public:
virtual size_t
GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name);
// If the passed in "name" is an ObjC method, return true. Also, fill in any of the
// sub-parts that are passed in non-NULL. The base_name means the name stripped of
// category attributes.
static bool
ParseMethodName (const char *name, ConstString *class_name, ConstString *method_name, ConstString *base_name);
protected:
//------------------------------------------------------------------
// Classes that inherit from ObjCLanguageRuntime can see and modify these

View File

@@ -13,6 +13,7 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
@@ -791,51 +792,22 @@ DWARFCompileUnit::Index
{
if (name)
{
if ((name[0] == '-' || name[0] == '+') && name[1] == '[')
ConstString objc_class_name;
ConstString objc_method_name;
ConstString objc_base_name;
if (ObjCLanguageRuntime::ParseMethodName (name,
&objc_class_name,
&objc_method_name,
&objc_base_name))
{
int name_len = strlen (name);
// Objective C methods must have at least:
// "-[" or "+[" prefix
// One character for a class name
// One character for the space between the class name
// One character for the method name
// "]" suffix
if (name_len >= 6 && name[name_len - 1] == ']')
objc_class_selectors.Insert(objc_class_name, die_info);
func_selectors.Insert (objc_method_name, die_info);
if (!objc_base_name.IsEmpty())
{
const char *method_name = strchr (name, ' ');
if (method_name)
{
ConstString class_name (name + 2, method_name - name - 2);
// Keep a map of the objective C class name to all selector
// DIEs
objc_class_selectors.Insert(class_name, die_info);
// Skip the space
++method_name;
// Extract the objective C basename and add it to the
// accelerator tables
size_t method_name_len = name_len - (method_name - name) - 1;
func_selectors.Insert (ConstString (method_name, method_name_len), die_info);
// Also see if this is a "category" on our class. If so strip off the category name,
// and add the class name without it to the basename table.
const char *first_paren = (char *) memchr (name, '(', method_name - name);
if (first_paren)
{
const char *second_paren = (char *) memchr (first_paren, ')', method_name - first_paren);
if (second_paren)
{
std::string buffer (name, first_paren - name);
buffer.append (second_paren + 1);
ConstString uncategoried_name (buffer.c_str());
func_basenames.Insert (uncategoried_name, die_info);
func_fullnames.Insert (uncategoried_name, die_info);
}
}
}
func_basenames.Insert (objc_base_name, die_info);
func_fullnames.Insert (objc_base_name, die_info);
}
}
// If we have a mangled name, then the DW_AT_name attribute
@@ -853,7 +825,8 @@ DWARFCompileUnit::Index
{
if (specification_die_offset != DW_INVALID_OFFSET)
{
const DWARFDebugInfoEntry *specification_die = m_dwarf2Data->DebugInfo()->GetDIEPtr (specification_die_offset, NULL);
const DWARFDebugInfoEntry *specification_die
= m_dwarf2Data->DebugInfo()->GetDIEPtr (specification_die_offset, NULL);
if (specification_die)
{
parent = specification_die->GetParent();

View File

@@ -14,6 +14,7 @@
#include "lldb/Core/Timer.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symtab.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
using namespace lldb;
using namespace lldb_private;
@@ -308,6 +309,20 @@ Symtab::InitNameIndexes()
entry.cstring = mangled.GetDemangledName().GetCString();
if (entry.cstring && entry.cstring[0])
m_name_to_index.Append (entry);
// If the demangled name turns out to be an ObjC name, and
// is a category name, add the version without categories to the index too.
ConstString objc_base_name;
if (ObjCLanguageRuntime::ParseMethodName (entry.cstring,
NULL,
NULL,
&objc_base_name)
&& !objc_base_name.IsEmpty())
{
entry.cstring = objc_base_name.GetCString();
m_name_to_index.Append (entry);
}
}
m_name_to_index.Sort();
}

View File

@@ -100,3 +100,66 @@ ObjCLanguageRuntime::GetByteOffsetForIvar (ClangASTType &parent_qual_type, const
return LLDB_INVALID_IVAR_OFFSET;
}
bool
ObjCLanguageRuntime::ParseMethodName (const char *name,
ConstString *class_name,
ConstString *method_name,
ConstString *base_name)
{
if (class_name) { class_name->Clear(); }
if (method_name) { method_name->Clear(); }
if (base_name) { base_name->Clear(); }
if (name && (name[0] == '-' || name[0] == '+') && name[1] == '[')
{
int name_len = strlen (name);
// Objective C methods must have at least:
// "-[" or "+[" prefix
// One character for a class name
// One character for the space between the class name
// One character for the method name
// "]" suffix
if (name_len >= 6 && name[name_len - 1] == ']')
{
const char *method_name_ptr;
method_name_ptr = strchr (name, ' ');
if (method_name_ptr)
{
if (class_name)
class_name->SetCStringWithLength (name + 2, method_name_ptr - name - 2);
// Skip the space
++method_name_ptr;
// Extract the objective C basename and add it to the
// accelerator tables
size_t method_name_len = name_len - (method_name_ptr - name) - 1;
if (method_name)
method_name->SetCStringWithLength (method_name_ptr, method_name_len);
// Also see if this is a "category" on our class. If so strip off the category name,
// and add the class name without it to the basename table.
if (base_name)
{
const char *first_paren = (char *) memchr (name, '(', method_name_ptr - name);
if (first_paren)
{
const char *second_paren = (char *) memchr (first_paren, ')', method_name_ptr - first_paren);
if (second_paren)
{
std::string buffer (name, first_paren - name);
buffer.append (second_paren + 1);
base_name->SetCString (buffer.c_str());
}
}
}
}
return true;
}
return false;
}
else
return false;
}