diff options
-rw-r--r-- | lldb/include/lldb/Target/ObjCLanguageRuntime.h | 6 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp | 61 | ||||
-rw-r--r-- | lldb/source/Symbol/Symtab.cpp | 15 | ||||
-rw-r--r-- | lldb/source/Target/ObjCLanguageRuntime.cpp | 63 |
4 files changed, 101 insertions, 44 deletions
diff --git a/lldb/include/lldb/Target/ObjCLanguageRuntime.h b/lldb/include/lldb/Target/ObjCLanguageRuntime.h index 5dc88b6bda0..0b8a4997c05 100644 --- a/lldb/include/lldb/Target/ObjCLanguageRuntime.h +++ b/lldb/include/lldb/Target/ObjCLanguageRuntime.h @@ -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 diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index 4da77792d23..479a662ba44 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -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(); diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp index e12cc4cfa26..bd98f3276a4 100644 --- a/lldb/source/Symbol/Symtab.cpp +++ b/lldb/source/Symbol/Symtab.cpp @@ -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(); } diff --git a/lldb/source/Target/ObjCLanguageRuntime.cpp b/lldb/source/Target/ObjCLanguageRuntime.cpp index cfc9b95886d..4326910f1cd 100644 --- a/lldb/source/Target/ObjCLanguageRuntime.cpp +++ b/lldb/source/Target/ObjCLanguageRuntime.cpp @@ -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; +} |