forked from OSchip/llvm-project
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
This commit is contained in:
parent
44e5c39c29
commit
a9bc065607
|
|
@ -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
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
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 @@ 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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue