diff options
author | Sean Callanan <scallanan@apple.com> | 2012-01-19 02:17:40 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2012-01-19 02:17:40 +0000 |
commit | a9bc0656072b957725d2eea7bd34b176f9a8670e (patch) | |
tree | 7732aa37b58c569888567b40c026ca733c8312af | |
parent | 44e5c39c29bbe8717f21e7be892cf0a63b795f36 (diff) | |
download | bcm5719-llvm-a9bc0656072b957725d2eea7bd34b176f9a8670e.tar.gz bcm5719-llvm-a9bc0656072b957725d2eea7bd34b176f9a8670e.zip |
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.
llvm-svn: 148457
-rw-r--r-- | lldb/include/lldb/Expression/ClangASTSource.h | 18 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/ClangASTImporter.h | 20 | ||||
-rw-r--r-- | lldb/source/Expression/ClangASTSource.cpp | 156 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h | 2 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangASTImporter.cpp | 36 |
6 files changed, 57 insertions, 177 deletions
diff --git a/lldb/include/lldb/Expression/ClangASTSource.h b/lldb/include/lldb/Expression/ClangASTSource.h index 4180f082c7a..3e5ae3d740e 100644 --- a/lldb/include/lldb/Expression/ClangASTSource.h +++ b/lldb/include/lldb/Expression/ClangASTSource.h @@ -170,24 +170,6 @@ public: const ConstString &name, ClangASTImporter::NamespaceMapSP &parent_map) const; - //------------------------------------------------------------------ - /// Look up all instances of a given Objective-C interface in all - /// symbol files and put the appropriate entries in the namespace - /// map. - /// - /// @param[in] namespace_map - /// The map to be completed. - /// - /// @param[in] name - /// The name of the namespace to be found. - /// - /// @param[in] parent_map - /// The map for the namespace's parent namespace, if there is - /// one. - //------------------------------------------------------------------ - void CompleteObjCInterfaceMap (ClangASTImporter::ObjCInterfaceMapSP &objc_interface_map, - const ConstString &name) const; - // // Helper APIs // diff --git a/lldb/include/lldb/Symbol/ClangASTImporter.h b/lldb/include/lldb/Symbol/ClangASTImporter.h index 672a9a0df2f..901081ff278 100644 --- a/lldb/include/lldb/Symbol/ClangASTImporter.h +++ b/lldb/include/lldb/Symbol/ClangASTImporter.h @@ -96,18 +96,7 @@ public: void BuildNamespaceMap (const clang::NamespaceDecl *decl); // - // Objective-C interface maps - // - - typedef std::vector <ClangASTType> ObjCInterfaceMap; - typedef lldb::SharedPtr<ObjCInterfaceMap>::Type ObjCInterfaceMapSP; - - void BuildObjCInterfaceMap (const clang::ObjCInterfaceDecl *decl); - - ObjCInterfaceMapSP GetObjCInterfaceMap (const clang::ObjCInterfaceDecl *decl); - - // - // Completers for the namespace and Objective-C interface maps + // Comleters for maps // class MapCompleter @@ -118,9 +107,6 @@ public: virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map, const ConstString &name, NamespaceMapSP &parent_map) const = 0; - - virtual void CompleteObjCInterfaceMap (ObjCInterfaceMapSP &objc_interface_map, - const ConstString &name) const = 0; }; void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer) @@ -210,7 +196,6 @@ private: typedef lldb::SharedPtr<Minion>::Type MinionSP; typedef std::map<clang::ASTContext *, MinionSP> MinionMap; typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap; - typedef std::map<const clang::ObjCInterfaceDecl *, ObjCInterfaceMapSP> ObjCInterfaceMetaMap; struct ASTContextMetadata { @@ -219,7 +204,6 @@ private: m_minions (), m_origins (), m_namespace_maps (), - m_objc_interface_maps (), m_map_completer (NULL) { } @@ -230,8 +214,6 @@ private: NamespaceMetaMap m_namespace_maps; MapCompleter *m_map_completer; - - ObjCInterfaceMetaMap m_objc_interface_maps; }; typedef lldb::SharedPtr<ASTContextMetadata>::Type ASTContextMetadataSP; diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index 5b940cf8a91..d7a19264b88 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -663,107 +663,80 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context) m_ast_context, interface_decl->getNameAsString().c_str(), selector_name.AsCString()); - - ClangASTImporter::ObjCInterfaceMapSP interface_map = m_ast_importer->GetObjCInterfaceMap(interface_decl); + SymbolContextList sc_list; + + const bool include_symbols = false; + const bool append = false; - if (interface_map) + std::string interface_name = interface_decl->getNameAsString(); + + do { - for (ClangASTImporter::ObjCInterfaceMap::iterator i = interface_map->begin(), e = interface_map->end(); - i != e; - ++i) + 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) { - lldb::clang_type_t backing_type = i->GetOpaqueQualType(); + SymbolContext candidate_sc; - if (!backing_type) + if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc)) continue; - QualType backing_qual_type = QualType::getFromOpaquePtr(backing_type); - - const ObjCInterfaceType *backing_interface_type = backing_qual_type.getTypePtr()->getAs<ObjCInterfaceType>(); - - if (!backing_interface_type) + if (!candidate_sc.function) 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); + const char *candidate_name = candidate_sc.function->GetName().AsCString(); - DeclContext::lookup_const_result lookup_result = backing_interface_decl->lookup(backing_decl_name); + const char *cursor = candidate_name; - if (lookup_result.first == lookup_result.second) + if (*cursor != '+' && *cursor != '-') continue; - ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(*lookup_result.first); + ++cursor; - if (!method_decl) + if (*cursor != '[') continue; - Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &backing_ast_context, *lookup_result.first); + ++cursor; - 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); + size_t interface_len = interface_name.length(); - if (!copied_method_decl) + if (strncmp(cursor, interface_name.c_str(), interface_len)) continue; - if (log) - { - ASTDumper dumper((Decl*)copied_method_decl); - log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id, dumper.GetCString()); - } + cursor += interface_len; - context.AddNamedDecl(copied_method_decl); + if (*cursor == ' ' || *cursor == '(') + sc_list.Append(candidate_sc); } } - - 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); + while (0); for (uint32_t i = 0, e = sc_list.GetSize(); i != e; @@ -809,7 +782,7 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context) 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 @@ ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespac } } -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/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h index 9638b311765..3aa1c13e289 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -124,7 +124,7 @@ struct DWARFMappedHash 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/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 7ebd02600ad..529fe4200bd 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3949,7 +3949,7 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry 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/lldb/source/Symbol/ClangASTImporter.cpp b/lldb/source/Symbol/ClangASTImporter.cpp index 59c2f6a737d..917827006b9 100644 --- a/lldb/source/Symbol/ClangASTImporter.cpp +++ b/lldb/source/Symbol/ClangASTImporter.cpp @@ -306,38 +306,6 @@ ClangASTImporter::MapCompleter::~MapCompleter () 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 @@ clang::Decl 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(); |