forked from OSchip/llvm-project
Added support to the expression parser for finding
Objective-C types and enums in modules. We now have a three-stage fallback when looking for methods and properties: first the DWARF, second the modules, third the runtime. <rdar://problem/18782288> llvm-svn: 223939
This commit is contained in:
parent
80b279e624
commit
dc00334dc3
|
@ -708,6 +708,8 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
|
||||||
else
|
else
|
||||||
m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, types);
|
m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, types);
|
||||||
|
|
||||||
|
bool found_a_type = false;
|
||||||
|
|
||||||
if (types.GetSize())
|
if (types.GetSize())
|
||||||
{
|
{
|
||||||
lldb::TypeSP type_sp = types.GetTypeAtIndex(0);
|
lldb::TypeSP type_sp = types.GetTypeAtIndex(0);
|
||||||
|
@ -736,8 +738,62 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
|
||||||
}
|
}
|
||||||
|
|
||||||
context.AddTypeDecl(copied_clang_type);
|
context.AddTypeDecl(copied_clang_type);
|
||||||
|
|
||||||
|
found_a_type = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!found_a_type)
|
||||||
|
{
|
||||||
|
// Try the modules next.
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor())
|
||||||
|
{
|
||||||
|
bool append = false;
|
||||||
|
uint32_t max_matches = 1;
|
||||||
|
std::vector <clang::NamedDecl *> decls;
|
||||||
|
|
||||||
|
if (!modules_decl_vendor->FindDecls(name,
|
||||||
|
append,
|
||||||
|
max_matches,
|
||||||
|
decls))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (log)
|
||||||
|
{
|
||||||
|
log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in the modules",
|
||||||
|
current_id,
|
||||||
|
name.GetCString());
|
||||||
|
}
|
||||||
|
|
||||||
|
clang::NamedDecl *const decl_from_modules = decls[0];
|
||||||
|
|
||||||
|
if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
|
||||||
|
llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
|
||||||
|
llvm::isa<clang::EnumConstantDecl>(decl_from_modules))
|
||||||
|
{
|
||||||
|
clang::Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
|
||||||
|
clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
|
||||||
|
|
||||||
|
if (!copied_named_decl)
|
||||||
|
{
|
||||||
|
if (log)
|
||||||
|
log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the modules",
|
||||||
|
current_id);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.AddNamedDecl(copied_named_decl);
|
||||||
|
|
||||||
|
found_a_type = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_a_type)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -897,30 +953,43 @@ FindObjCMethodDeclsWithOrigin (unsigned int current_id,
|
||||||
|
|
||||||
DeclarationName original_decl_name(original_selector);
|
DeclarationName original_decl_name(original_selector);
|
||||||
|
|
||||||
ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name);
|
llvm::SmallVector<NamedDecl *, 1> methods;
|
||||||
|
|
||||||
if (result.empty())
|
ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl);
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!result[0])
|
if (ObjCMethodDecl *instance_method_decl = original_interface_decl->lookupInstanceMethod(original_selector))
|
||||||
return false;
|
|
||||||
|
|
||||||
for (NamedDecl *named_decl : result)
|
|
||||||
{
|
{
|
||||||
|
methods.push_back(instance_method_decl);
|
||||||
|
}
|
||||||
|
else if (ObjCMethodDecl *class_method_decl = original_interface_decl->lookupClassMethod(original_selector))
|
||||||
|
{
|
||||||
|
methods.push_back(class_method_decl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (methods.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NamedDecl *named_decl : methods)
|
||||||
|
{
|
||||||
|
if (!named_decl)
|
||||||
|
continue;
|
||||||
|
|
||||||
ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl);
|
ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl);
|
||||||
|
|
||||||
if (!result_method)
|
if (!result_method)
|
||||||
return false;
|
continue;
|
||||||
|
|
||||||
Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method);
|
Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method);
|
||||||
|
|
||||||
if (!copied_decl)
|
if (!copied_decl)
|
||||||
return false;
|
continue;
|
||||||
|
|
||||||
ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
|
ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
|
||||||
|
|
||||||
if (!copied_method_decl)
|
if (!copied_method_decl)
|
||||||
return false;
|
continue;
|
||||||
|
|
||||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
|
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
|
||||||
|
|
||||||
|
@ -1173,7 +1242,40 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// Check the runtime only if the debug information didn't have a complete interface.
|
// Check the modules only if the debug information didn't have a complete interface.
|
||||||
|
|
||||||
|
if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor())
|
||||||
|
{
|
||||||
|
ConstString interface_name(interface_decl->getNameAsString().c_str());
|
||||||
|
bool append = false;
|
||||||
|
uint32_t max_matches = 1;
|
||||||
|
std::vector <clang::NamedDecl *> decls;
|
||||||
|
|
||||||
|
if (!modules_decl_vendor->FindDecls(interface_name,
|
||||||
|
append,
|
||||||
|
max_matches,
|
||||||
|
decls))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ObjCInterfaceDecl *interface_decl_from_modules = dyn_cast<ObjCInterfaceDecl>(decls[0]);
|
||||||
|
|
||||||
|
if (!interface_decl_from_modules)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (FindObjCMethodDeclsWithOrigin(current_id,
|
||||||
|
context,
|
||||||
|
interface_decl_from_modules,
|
||||||
|
m_ast_context,
|
||||||
|
m_ast_importer,
|
||||||
|
"in modules"))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (0);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Check the runtime only if the debug information didn't have a complete interface and the modules don't get us anywhere.
|
||||||
|
|
||||||
lldb::ProcessSP process(m_target->GetProcessSP());
|
lldb::ProcessSP process(m_target->GetProcessSP());
|
||||||
|
|
||||||
|
@ -1339,7 +1441,47 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// Check the runtime only if the debug information didn't have a complete interface.
|
// Check the modules only if the debug information didn't have a complete interface.
|
||||||
|
|
||||||
|
ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor();
|
||||||
|
|
||||||
|
if (!modules_decl_vendor)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bool append = false;
|
||||||
|
uint32_t max_matches = 1;
|
||||||
|
std::vector <clang::NamedDecl *> decls;
|
||||||
|
|
||||||
|
if (!modules_decl_vendor->FindDecls(class_name,
|
||||||
|
append,
|
||||||
|
max_matches,
|
||||||
|
decls))
|
||||||
|
break;
|
||||||
|
|
||||||
|
DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_modules(dyn_cast<ObjCInterfaceDecl>(decls[0]));
|
||||||
|
|
||||||
|
if (!interface_decl_from_modules.IsValid())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (log)
|
||||||
|
log->Printf("CAS::FOPD[%d] trying module (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
|
||||||
|
current_id,
|
||||||
|
static_cast<const void*>(interface_decl_from_modules.decl),
|
||||||
|
static_cast<void*>(&interface_decl_from_modules->getASTContext()));
|
||||||
|
|
||||||
|
if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
|
||||||
|
context,
|
||||||
|
*m_ast_context,
|
||||||
|
m_ast_importer,
|
||||||
|
interface_decl_from_modules))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while(0);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Check the runtime only if the debug information didn't have a complete interface
|
||||||
|
// and nothing was in the modules.
|
||||||
|
|
||||||
lldb::ProcessSP process(m_target->GetProcessSP());
|
lldb::ProcessSP process(m_target->GetProcessSP());
|
||||||
|
|
||||||
|
@ -1366,22 +1508,22 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
|
||||||
decls))
|
decls))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
DeclFromUser<const ObjCInterfaceDecl> runtime_iface_decl(dyn_cast<ObjCInterfaceDecl>(decls[0]));
|
DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime(dyn_cast<ObjCInterfaceDecl>(decls[0]));
|
||||||
|
|
||||||
if (!runtime_iface_decl.IsValid())
|
if (!interface_decl_from_runtime.IsValid())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (log)
|
if (log)
|
||||||
log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
|
log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
|
||||||
current_id,
|
current_id,
|
||||||
static_cast<const void*>(runtime_iface_decl.decl),
|
static_cast<const void*>(interface_decl_from_runtime.decl),
|
||||||
static_cast<void*>(&runtime_iface_decl->getASTContext()));
|
static_cast<void*>(&interface_decl_from_runtime->getASTContext()));
|
||||||
|
|
||||||
if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
|
if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
|
||||||
context,
|
context,
|
||||||
*m_ast_context,
|
*m_ast_context,
|
||||||
m_ast_importer,
|
m_ast_importer,
|
||||||
runtime_iface_decl))
|
interface_decl_from_runtime))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while(0);
|
while(0);
|
||||||
|
|
Loading…
Reference in New Issue