Skip to content

[lldb] Find public Objective-C class when reconstructing type #3188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4305,8 +4305,11 @@ CompilerType SwiftASTContext::GetAsClangType(ConstString mangled_name) {
// that look like they might be come from Objective-C (or C) as
// Clang types. LLDB's Objective-C part is very robust against
// malformed object pointers, so this isn't very risky.
Module *module = GetModule();
if (!module)
return {};
auto type_system_or_err =
GetModule()->GetTypeSystemForLanguage(eLanguageTypeObjC);
module->GetTypeSystemForLanguage(eLanguageTypeObjC);
if (!type_system_or_err) {
llvm::consumeError(type_system_or_err.takeError());
return {};
Expand All @@ -4327,8 +4330,10 @@ CompilerType SwiftASTContext::GetAsClangType(ConstString mangled_name) {
// Import the Clang type into the Clang context.
if (!clang_type)
return {};
clang_type =
clang_ast_parser->GetClangASTImporter().CopyType(*clang_ctx, clang_type);

if (clang_type.GetTypeSystem() != clang_ctx)
clang_type = clang_ast_parser->GetClangASTImporter().CopyType(*clang_ctx,
clang_type);
// Swift doesn't know pointers. Convert top-level
// Objective-C object types to object pointers for Clang.
auto qual_type =
Expand Down Expand Up @@ -4401,6 +4406,31 @@ swift::TypeBase *SwiftASTContext::ReconstructType(ConstString mangled_typename,
*ast_ctx, mangled_typename.GetStringRef())
.getPointer();

// Objective-C classes sometimes have private subclasses that are invisible to the Swift compiler because they are declared and defined in a .m file. If we can't reconstruct an ObjC type, walk up the type hierarchy until we find something we can import, or until we run out of types
while (!found_type) {
CompilerType clang_type = GetAsClangType(mangled_typename);
if (!clang_type)
break;

auto *clang_ctx =
llvm::dyn_cast_or_null<TypeSystemClang>(clang_type.GetTypeSystem());
if (!clang_ctx)
break;
auto *interface_decl = TypeSystemClang::GetAsObjCInterfaceDecl(clang_type);
if (!interface_decl)
break;
auto *super_interface_decl = interface_decl->getSuperClass();
if (!super_interface_decl)
break;
CompilerType super_type = clang_ctx->GetTypeForDecl(super_interface_decl);
if (!super_type)
break;
auto super_mangled_typename = super_type.GetMangledTypeName();
found_type = swift::Demangle::getTypeForMangling(
*ast_ctx, super_mangled_typename.GetStringRef())
.getPointer();
}

if (found_type) {
swift::TypeBase *ast_type =
ConvertSILFunctionTypesToASTFunctionTypes(found_type).getPointer();
Expand Down
11 changes: 3 additions & 8 deletions lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2780,14 +2780,9 @@ bool TypeSystemSwiftTypeRef::IsImportedType(opaque_compiler_type_t type,
return true;
};
FALLBACK(IsImportedType, (ReconstructType(type), original_type));
// Dont compare the results if there is no ClangImporter in the SwiftASTContext.
const auto &props = ModuleList::GetGlobalModuleListProperties();
if (!props.GetUseSwiftClangImporter())
return impl();

VALIDATE_AND_RETURN(impl, IsImportedType, type,
(ReconstructType(type), nullptr),
(ReconstructType(type), original_type));
// We can't validate the result because ReconstructType may call this
// function, causing an infinite loop.
return impl();
}

bool TypeSystemSwiftTypeRef::IsExistentialType(
Expand Down