Fixed a problem where maintaining the ObjCInterfaceMap
for each ObjCInterfaceDecl was imposing performance
penalties for Objective-C apps. Instead, we now use
the normal function query mechanisms, which use the
relevant accelerator tables.
This fix also includes some modifications to the
SymbolFile which allow us to find Objective-C methods
and report their Clang Decls correctly.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@148457 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangASTSource.cpp b/source/Expression/ClangASTSource.cpp
index 5b940cf..d7a1926 100644
--- a/source/Expression/ClangASTSource.cpp
+++ b/source/Expression/ClangASTSource.cpp
@@ -663,107 +663,80 @@
m_ast_context,
interface_decl->getNameAsString().c_str(),
selector_name.AsCString());
-
- ClangASTImporter::ObjCInterfaceMapSP interface_map = m_ast_importer->GetObjCInterfaceMap(interface_decl);
-
- if (interface_map)
- {
- for (ClangASTImporter::ObjCInterfaceMap::iterator i = interface_map->begin(), e = interface_map->end();
- i != e;
- ++i)
- {
- lldb::clang_type_t backing_type = i->GetOpaqueQualType();
-
- if (!backing_type)
- continue;
-
- QualType backing_qual_type = QualType::getFromOpaquePtr(backing_type);
-
- const ObjCInterfaceType *backing_interface_type = backing_qual_type.getTypePtr()->getAs<ObjCInterfaceType>();
-
- if (!backing_interface_type)
- continue;
-
- const ObjCInterfaceDecl *backing_interface_decl = backing_interface_type->getDecl();
-
- if (!backing_interface_decl)
- continue;
-
- if (backing_interface_decl->decls_begin() == backing_interface_decl->decls_end())
- continue; // don't waste time creating a DeclarationName here
-
- clang::ASTContext &backing_ast_context = backing_interface_decl->getASTContext();
-
- llvm::SmallVector<clang::IdentifierInfo *, 3> selector_components;
- int num_arguments = 0;
-
- if (decl_name.isObjCZeroArgSelector())
- {
- selector_components.push_back (&backing_ast_context.Idents.get(decl_name.getAsString().c_str()));
- }
- else if (decl_name.isObjCOneArgSelector())
- {
- selector_components.push_back (&backing_ast_context.Idents.get(decl_name.getAsString().c_str()));
- num_arguments = 1;
- }
- else
- {
- clang::Selector sel = decl_name.getObjCSelector();
-
- for (unsigned i = 0, e = sel.getNumArgs();
- i != e;
- ++i)
- {
- llvm::StringRef r = sel.getNameForSlot(i);
-
- selector_components.push_back (&backing_ast_context.Idents.get(r.str().c_str()));
- num_arguments++;
- }
- }
-
- Selector backing_selector = backing_interface_decl->getASTContext().Selectors.getSelector(num_arguments, selector_components.data());
- DeclarationName backing_decl_name = DeclarationName(backing_selector);
-
- DeclContext::lookup_const_result lookup_result = backing_interface_decl->lookup(backing_decl_name);
-
- if (lookup_result.first == lookup_result.second)
- continue;
-
- ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(*lookup_result.first);
-
- if (!method_decl)
- continue;
-
- Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &backing_ast_context, *lookup_result.first);
-
- if (!copied_decl)
- {
- if (log)
- log->Printf(" CAS::FOMD[%d] couldn't import method from symbols", current_id);
- continue;
- }
-
- ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl> (copied_decl);
-
- if (!copied_method_decl)
- continue;
-
- if (log)
- {
- ASTDumper dumper((Decl*)copied_method_decl);
- log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id, dumper.GetCString());
- }
-
- context.AddNamedDecl(copied_method_decl);
- }
- }
-
SymbolContextList sc_list;
const bool include_symbols = false;
const bool append = false;
- m_target->GetImages().FindFunctions(selector_name, lldb::eFunctionNameTypeSelector, include_symbols, append, sc_list);
+ std::string interface_name = interface_decl->getNameAsString();
+
+ do
+ {
+ StreamString ms;
+ ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString());
+ ms.Flush();
+ ConstString instance_method_name(ms.GetData());
+
+ m_target->GetImages().FindFunctions(instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, append, sc_list);
+
+ if (sc_list.GetSize())
+ break;
+
+ ms.Clear();
+ ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString());
+ ms.Flush();
+ ConstString class_method_name(ms.GetData());
+
+ m_target->GetImages().FindFunctions(class_method_name, lldb::eFunctionNameTypeFull, include_symbols, append, sc_list);
+
+ if (sc_list.GetSize())
+ break;
+
+ // Fall back and check for methods in categories. If we find methods this way, we need to check that they're actually in
+ // categories on the desired class.
+
+ SymbolContextList candidate_sc_list;
+
+ m_target->GetImages().FindFunctions(selector_name, lldb::eFunctionNameTypeSelector, include_symbols, append, candidate_sc_list);
+
+ for (uint32_t ci = 0, ce = candidate_sc_list.GetSize();
+ ci != ce;
+ ++ci)
+ {
+ SymbolContext candidate_sc;
+
+ if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc))
+ continue;
+
+ if (!candidate_sc.function)
+ continue;
+
+ const char *candidate_name = candidate_sc.function->GetName().AsCString();
+
+ const char *cursor = candidate_name;
+
+ if (*cursor != '+' && *cursor != '-')
+ continue;
+
+ ++cursor;
+
+ if (*cursor != '[')
+ continue;
+
+ ++cursor;
+
+ size_t interface_len = interface_name.length();
+
+ if (strncmp(cursor, interface_name.c_str(), interface_len))
+ continue;
+
+ cursor += interface_len;
+
+ if (*cursor == ' ' || *cursor == '(')
+ sc_list.Append(candidate_sc);
+ }
+ }
+ while (0);
for (uint32_t i = 0, e = sc_list.GetSize();
i != e;
@@ -809,7 +782,7 @@
ASTDumper dumper((Decl*)copied_method_decl);
log->Printf(" CAS::FOMD[%d] found (in debug info) %s", current_id, dumper.GetCString());
}
-
+
context.AddNamedDecl(copied_method_decl);
}
}
@@ -970,29 +943,6 @@
}
}
-void
-ClangASTSource::CompleteObjCInterfaceMap (ClangASTImporter::ObjCInterfaceMapSP &objc_interface_map,
- const ConstString &name) const
-{
- SymbolContext null_sc;
-
- TypeList types;
-
- m_target->GetImages().FindTypes(null_sc, name, true, UINT32_MAX, types);
-
- for (uint32_t i = 0, e = types.GetSize();
- i != e;
- ++i)
- {
- lldb::TypeSP mapped_type_sp = types.GetTypeAtIndex(i);
-
- if (!mapped_type_sp || !mapped_type_sp->GetClangFullType())
- continue;
-
- objc_interface_map->push_back (ClangASTType(mapped_type_sp->GetClangAST(), mapped_type_sp->GetClangFullType()));
- }
-}
-
NamespaceDecl *
ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls)
{
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index 9638b31..3aa1c13 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -124,7 +124,7 @@
for (size_t i=0; i<count; ++i)
{
const dw_tag_t die_tag = die_info_array[i].tag;
- if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+ if (die_tag == 0 || die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
{
if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation)
{
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 7ebd026..529fe42 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -3949,7 +3949,7 @@
if (try_resolving_type)
{
- if (type_cu->Supports_DW_AT_APPLE_objc_complete_type())
+ if (must_be_implementation && type_cu->Supports_DW_AT_APPLE_objc_complete_type())
try_resolving_type = type_die->GetAttributeValueAsUnsigned (this, type_cu, DW_AT_APPLE_objc_complete_type, 0);
if (try_resolving_type)
diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp
index 59c2f6a..9178270 100644
--- a/source/Symbol/ClangASTImporter.cpp
+++ b/source/Symbol/ClangASTImporter.cpp
@@ -306,38 +306,6 @@
return;
}
-ClangASTImporter::ObjCInterfaceMapSP
-ClangASTImporter::GetObjCInterfaceMap (const clang::ObjCInterfaceDecl *decl)
-{
- ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
-
- ObjCInterfaceMetaMap &objc_interface_maps = context_md->m_objc_interface_maps;
-
- ObjCInterfaceMetaMap::iterator iter = objc_interface_maps.find(decl);
-
- if (iter != objc_interface_maps.end())
- return iter->second;
- else
- return ObjCInterfaceMapSP();
-}
-
-void
-ClangASTImporter::BuildObjCInterfaceMap (const clang::ObjCInterfaceDecl *decl)
-{
- ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
-
- ObjCInterfaceMapSP new_map(new ObjCInterfaceMap);
-
- if (context_md->m_map_completer)
- {
- std::string namespace_string = decl->getDeclName().getAsString();
-
- context_md->m_map_completer->CompleteObjCInterfaceMap(new_map, ConstString(namespace_string.c_str()));
- }
-
- context_md->m_objc_interface_maps[decl] = new_map;
-}
-
void
ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from)
{
@@ -455,9 +423,7 @@
if (isa<ObjCInterfaceDecl>(from))
{
ObjCInterfaceDecl *to_interface_decl = dyn_cast<ObjCInterfaceDecl>(to);
-
- m_master.BuildObjCInterfaceMap(to_interface_decl);
-
+
to_interface_decl->setHasExternalLexicalStorage();
to_interface_decl->setHasExternalVisibleStorage();