mirror of
https://github.com/intel/llvm.git
synced 2026-01-14 03:50:17 +08:00
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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user