From 8458d1033d56e4bc23267eb73830f267a14e1b7e Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 7 Mar 2025 12:55:34 -0800 Subject: [PATCH] [lldb] Resolve Swift-implemented Objective-C classes using Swift runtime if the Objective-C runtime fails. If an Objective-C class is lazy, the Objective-C runtie may not have materialized class metadata for it. However, if the class is actually implemented in Swift, we can still resolve it using the Swift runtime. We should probably also add the same logic to the Objective-C runtime, but I don't want risk adding an inifinite recursion at this point in the release. rdar://145253225 --- .../ExpressionParser/Swift/SwiftREPL.cpp | 25 +++- .../Language/Swift/SwiftHashedContainer.cpp | 30 +++-- ...ftLanguageRuntimeDynamicTypeResolution.cpp | 116 +++++++++--------- .../TypeSystem/Swift/SwiftASTContext.cpp | 38 +++--- .../TypeSystem/Swift/SwiftASTContext.h | 37 +++--- .../Swift/TypeSystemSwiftTypeRef.cpp | 29 ++--- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.h | 12 +- .../TestFirstExprModuleLoad.py | 5 - .../TestSwiftFirstExprModuleLoad.py | 20 +++ .../swift/first_expr_module_load/main.swift | 7 +- .../Swift/Inputs/No.swiftmodule-ObjC.swift | 2 +- lldb/test/Shell/SwiftREPL/DictBridging.test | 7 +- lldb/test/Shell/SwiftREPL/SetBridging.test | 4 +- 13 files changed, 185 insertions(+), 147 deletions(-) delete mode 100644 lldb/test/API/lang/swift/first_expr_module_load/TestFirstExprModuleLoad.py create mode 100644 lldb/test/API/lang/swift/first_expr_module_load/TestSwiftFirstExprModuleLoad.py diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftREPL.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftREPL.cpp index 53e8df708720b..2a630b8758224 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftREPL.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftREPL.cpp @@ -501,13 +501,30 @@ bool SwiftREPL::PrintOneVariable(Debugger &debugger, StreamFileSP &output_sp, options.SetRevealEmptyAggregates(false); options.SetHidePointerValue(true); options.SetVariableFormatDisplayLanguage(lldb::eLanguageTypeSwift); - options.SetDeclPrintingHelper([](ConstString type_name, - ConstString var_name, - const DumpValueObjectOptions &options, - Stream &stream) -> bool { + options.SetDeclPrintingHelper([&](ConstString type_name, + ConstString var_name, + const DumpValueObjectOptions &options, + Stream &stream) -> bool { if (!type_name || !var_name) return false; + // Try to get the SwiftASTContext representation of the type. It + // will hide Objective-C implemention details that are not + // publicly declared in the SDK. + if (valobj_sp) { + auto static_valobj_sp = valobj_sp->GetStaticValue(); + auto dynamic_valobj_sp = + valobj_sp->GetDynamicValue(lldb::eDynamicCanRunTarget); + if (static_valobj_sp && dynamic_valobj_sp) { + CompilerType static_type = static_valobj_sp->GetCompilerType(); + CompilerType dynamic_type = dynamic_valobj_sp->GetCompilerType(); + auto ts = + dynamic_type.GetTypeSystem().dyn_cast_or_null(); + if (ts && + ts->IsImportedType(dynamic_type.GetOpaqueQualType(), nullptr)) + type_name = static_type.GetDisplayTypeName(); + } + } std::string type_name_str(type_name ? type_name.GetCString() : ""); for (auto iter = type_name_str.find(" *"); iter != std::string::npos; iter = type_name_str.find(" *")) { diff --git a/lldb/source/Plugins/Language/Swift/SwiftHashedContainer.cpp b/lldb/source/Plugins/Language/Swift/SwiftHashedContainer.cpp index dc2cf26ac8972..6dae38baba908 100644 --- a/lldb/source/Plugins/Language/Swift/SwiftHashedContainer.cpp +++ b/lldb/source/Plugins/Language/Swift/SwiftHashedContainer.cpp @@ -200,6 +200,9 @@ HashedCollectionConfig::RegisterSummaryProviders( AddCXXSummary(swift_category_sp, summaryProvider, m_summaryProviderName.AsCString(), m_emptyStorage_demangled, flags, false); + AddCXXSummary(swift_category_sp, summaryProvider, + m_summaryProviderName.AsCString(), + m_nativeStorageRoot_demangled, flags, false); AddCXXSummary(swift_category_sp, summaryProvider, m_summaryProviderName.AsCString(), m_deferredBridgedStorage_demangledRegex, flags, true); @@ -231,6 +234,9 @@ HashedCollectionConfig::RegisterSyntheticChildrenCreators( AddCXXSynthetic(swift_category_sp, creator, m_syntheticChildrenName.AsCString(), m_nativeStorage_demangledRegex, flags, true); + AddCXXSynthetic(swift_category_sp, creator, + m_syntheticChildrenName.AsCString(), + m_nativeStorageRoot_demangled, flags, false); AddCXXSynthetic(swift_category_sp, creator, m_syntheticChildrenName.AsCString(), m_emptyStorage_demangled, flags, false); @@ -648,18 +654,22 @@ HashedCollectionConfig::CreateHandler(ValueObject &valobj) const { return CreateNativeHandler(valobj_sp, storage_sp); } - ValueObjectSP variant_sp = - valobj_sp->GetChildMemberWithName(g__variant, true); - if (!variant_sp) - return nullptr; + lldb::addr_t storage_location = LLDB_INVALID_ADDRESS; + if (type_name_cs == m_nativeStorageRoot_demangled) + storage_location = valobj_sp->GetPointerValue(); + else { + ValueObjectSP variant_sp = + valobj_sp->GetChildMemberWithName(g__variant, true); + if (!variant_sp) + return nullptr; - ValueObjectSP bobject_sp = - variant_sp->GetChildAtNamePath({g_object, g_rawValue}); - if (!bobject_sp) - return nullptr; + ValueObjectSP bobject_sp = + variant_sp->GetChildAtNamePath({g_object, g_rawValue}); + if (!bobject_sp) + return nullptr; - lldb::addr_t storage_location = - bobject_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); + storage_location = bobject_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); + } if (storage_location == LLDB_INVALID_ADDRESS) return nullptr; diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp index 11a68fa2dd06e..61d69d3ffb1b9 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -2022,21 +2022,6 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( return true; } -static bool IsPrivateNSClass(NodePointer node) { - if (!node || node->getKind() != Node::Kind::Type || - node->getNumChildren() == 0) - return false; - NodePointer classNode = node->getFirstChild(); - if (!classNode || classNode->getKind() != Node::Kind::Class || - classNode->getNumChildren() < 2) - return false; - for (NodePointer child : *classNode) - if (child->getKind() == Node::Kind::Identifier && child->hasText()) - return child->getText().starts_with("__NS") || - child->getText().starts_with("NSTaggedPointer"); - return false; -} - CompilerType SwiftLanguageRuntime::GetDynamicTypeAndAddress_EmbeddedClass( uint64_t instance_ptr, CompilerType class_type) { ThreadSafeReflectionContext reflection_ctx = GetReflectionContext(); @@ -2091,44 +2076,41 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class( return false; auto tss = class_type.GetTypeSystem().dyn_cast_or_null(); + if (!tss) { + // This could be an Objective-C type implemented in Swift. Get the + // Swift typesystem. + if (auto module_sp = in_value.GetModule()) { + auto type_system_or_err = + module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeSwift); + if (!type_system_or_err) { + llvm::consumeError(type_system_or_err.takeError()); + return false; + } + auto ts_sp = *type_system_or_err; + tss = + llvm::cast(ts_sp.get())->GetTypeSystemSwiftTypeRef(); + } else if (auto target_sp = in_value.GetTargetSP()) { + auto type_system_or_err = + target_sp->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeSwift); + if (!type_system_or_err) { + llvm::consumeError(type_system_or_err.takeError()); + return false; + } + auto ts_sp = *type_system_or_err; + tss = + llvm::cast(ts_sp.get())->GetTypeSystemSwiftTypeRef(); + } + } if (!tss) return false; + address.SetRawAddress(instance_ptr); auto ts = tss->GetTypeSystemSwiftTypeRef(); if (!ts) return false; - // Ask the Objective-C runtime about Objective-C types. - if (tss->IsImportedType(class_type.GetOpaqueQualType(), nullptr)) - if (auto *objc_runtime = - SwiftLanguageRuntime::GetObjCRuntime(GetProcess())) { - Value::ValueType value_type; - if (objc_runtime->GetDynamicTypeAndAddress(in_value, use_dynamic, - class_type_or_name, address, - value_type, local_buffer)) { - bool found = false; - // Return the most specific class which we can get the typeref. - ForEachSuperClassType(in_value, [&](SuperClassType sc) -> bool { - if (auto *tr = sc.get_typeref()) { - swift::Demangle::Demangler dem; - swift::Demangle::NodePointer node = tr->getDemangling(dem); - // Skip private Foundation types since it's unlikely that would be - // useful to users. - if (IsPrivateNSClass(node)) - return false; - class_type_or_name.SetCompilerType(ts->RemangleAsType( - dem, node, swift::Mangle::ManglingFlavor::Default)); - found = true; - return true; - } - return false; - }); - return found; - } - return false; - } - Log *log(GetLog(LLDBLog::Types)); - // Scope reflection_ctx to minimize its lock scope. - { + + auto resolve_swift = [&]() { + // Scope reflection_ctx to minimize its lock scope. ThreadSafeReflectionContext reflection_ctx = GetReflectionContext(); if (!reflection_ctx) return false; @@ -2172,10 +2154,17 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class( return false; } } - - LLDB_LOG(log, "dynamic type of instance_ptr {0:x} is {1}", instance_ptr, - class_type.GetMangledTypeName()); class_type_or_name.SetCompilerType(dynamic_type); + LLDB_LOG(GetLog(LLDBLog::Types), + "dynamic type of instance_ptr {0:x} is {1}", instance_ptr, + class_type.GetMangledTypeName()); + return true; + }; + + if (!resolve_swift()) { + // When returning false here, the next compatible runtime (= + // Objective-C) will get ask to resolve this type. + return false; } #ifndef NDEBUG @@ -2833,12 +2822,12 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_IndirectEnumCase( return GetDynamicTypeAndAddress(*valobj_sp, use_dynamic, class_type_or_name, address, value_type, local_buffer); - } else { - // This is most likely a statically known type. - address.SetLoadAddress(box_value, &GetProcess().GetTarget()); - value_type = Value::GetValueTypeFromAddressType(eAddressTypeLoad); - return true; } + + // This is most likely a statically known type. + address.SetLoadAddress(box_value, &GetProcess().GetTarget()); + value_type = Value::GetValueTypeFromAddressType(eAddressTypeLoad); + return true; } void SwiftLanguageRuntime::DumpTyperef(CompilerType type, @@ -3156,22 +3145,27 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress( return false; LLDB_SCOPED_TIMER(); + CompilerType val_type(in_value.GetCompilerType()); + Value::ValueType static_value_type = Value::ValueType::Invalid; // Try to import a Clang type into Swift. - if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC) - return GetDynamicTypeAndAddress_ClangType(in_value, use_dynamic, - class_type_or_name, address, - value_type, local_buffer); + if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC) { + if (GetDynamicTypeAndAddress_ClangType(in_value, use_dynamic, + class_type_or_name, address, + value_type, local_buffer)) + return true; + return GetDynamicTypeAndAddress_Class(in_value, val_type, use_dynamic, + class_type_or_name, address, + static_value_type, local_buffer); + } if (!CouldHaveDynamicValue(in_value)) return false; - CompilerType val_type(in_value.GetCompilerType()); Flags type_info(val_type.GetTypeInfo()); if (!type_info.AnySet(eTypeIsSwift)) return false; - Value::ValueType static_value_type = Value::ValueType::Invalid; bool success = false; bool is_indirect_enum_case = IsIndirectEnumCase(in_value); // Type kinds with instance metadata don't need generic type resolution. diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 1ae044814f8e2..9c518347d2a59 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -996,7 +996,7 @@ SwiftASTContext::SwiftASTContext() } #endif -SwiftASTContext::SwiftASTContext(std::string description, +SwiftASTContext::SwiftASTContext(std::string description, ModuleSP module_sp, TypeSystemSwiftTypeRefSP typeref_typesystem) : TypeSystemSwift(), m_typeref_typesystem(typeref_typesystem), m_compiler_invocation_ap(new swift::CompilerInvocation()), @@ -1006,6 +1006,7 @@ SwiftASTContext::SwiftASTContext(std::string description, "Swift AST context instantiation is disabled!"); m_description = description; + m_module = module_sp.get(); // Set the clang modules cache path. m_compiler_invocation_ap->setClangModuleCachePath( @@ -2431,7 +2432,8 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module, // If there is a target this may be a fallback scratch context. std::shared_ptr swift_ast_sp( static_cast(new SwiftASTContextForModule( - m_description, typeref_typesystem.GetTypeSystemSwiftTypeRef()))); + m_description, module.shared_from_this(), + typeref_typesystem.GetTypeSystemSwiftTypeRef()))); bool suppress_config_log = false; auto defer_log = llvm::make_scope_exit([swift_ast_sp, &suppress_config_log] { @@ -2444,7 +2446,6 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module, // This is a module AST context, mark it as such. swift_ast_sp->m_is_scratch_context = false; - swift_ast_sp->m_module = &module; swift_ast_sp->GetLanguageOptions().EnableAccessControl = false; swift_ast_sp->GetLanguageOptions().EnableCXXInterop = module.IsSwiftCxxInteropEnabled(); @@ -2781,7 +2782,8 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc, return {}; } swift_ast_sp.reset(new SwiftASTContextForExpressions( - m_description, typeref_typesystem.GetTypeSystemSwiftTypeRef())); + m_description, module_sp, + typeref_typesystem.GetTypeSystemSwiftTypeRef())); // This is a scratch AST context, mark it as such. swift_ast_sp->m_is_scratch_context = true; auto &lang_opts = swift_ast_sp->GetLanguageOptions(); @@ -2796,10 +2798,10 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc, } swift_ast_sp.reset( static_cast(new SwiftASTContextForModule( - m_description, typeref_typesystem.GetTypeSystemSwiftTypeRef()))); + m_description, module_sp, + typeref_typesystem.GetTypeSystemSwiftTypeRef()))); // This is a module AST context, mark it as such. swift_ast_sp->m_is_scratch_context = false; - swift_ast_sp->m_module = module_sp.get(); auto &lang_opts = swift_ast_sp->GetLanguageOptions(); lang_opts.EnableAccessControl = false; lang_opts.EnableCXXInterop = ShouldEnableCXXInterop(cu); @@ -4695,14 +4697,10 @@ 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. - auto ts = GetTypeSystemSwiftTypeRef(); - if (!ts) - return {}; - Module *module = ts->GetModule(); - if (!module) + if (!m_module) return {}; auto type_system_or_err = - module->GetTypeSystemForLanguage(eLanguageTypeObjC); + m_module->GetTypeSystemForLanguage(eLanguageTypeObjC); if (!type_system_or_err) { llvm::consumeError(type_system_or_err.takeError()); return {}; @@ -4714,11 +4712,16 @@ CompilerType SwiftASTContext::GetAsClangType(ConstString mangled_name) { return {}; DWARFASTParserClang *clang_ast_parser = static_cast(clang_ctx->GetDWARFParser()); + + SymbolContext sc; + m_module->CalculateSymbolContext(&sc); CompilerType clang_type; CompilerType imported_type = GetCompilerType(mangled_name); - if (auto ts = - imported_type.GetTypeSystem().dyn_cast_or_null()) - ts->IsImportedType(imported_type.GetOpaqueQualType(), &clang_type); + if (auto ts = imported_type.GetTypeSystem() + .dyn_cast_or_null()) + if (ts->IsImportedType(imported_type.GetOpaqueQualType(), nullptr)) + if (TypeSP result = ts->LookupClangType(mangled_name, sc)) + clang_type = result->GetForwardCompilerType(); // Import the Clang type into the Clang context. if (!clang_type) @@ -8930,8 +8933,9 @@ SwiftASTContext::GetASTVectorForModule(const Module *module) { } SwiftASTContextForExpressions::SwiftASTContextForExpressions( - std::string description, TypeSystemSwiftTypeRefSP typeref_typesystem) - : SwiftASTContext(std::move(description), typeref_typesystem) { + std::string description, ModuleSP module_sp, + TypeSystemSwiftTypeRefSP typeref_typesystem) + : SwiftASTContext(std::move(description), module_sp, typeref_typesystem) { assert(llvm::isa( m_typeref_typesystem.lock().get())); } diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h index 5fef1d56fb5cf..ec75eb247b829 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h @@ -182,7 +182,7 @@ class SwiftASTContext : public TypeSystemSwift { protected: // Constructors and destructors - SwiftASTContext(std::string description, + SwiftASTContext(std::string description, lldb::ModuleSP module_sp, TypeSystemSwiftTypeRefSP typeref_typesystem); public: @@ -923,6 +923,20 @@ class SwiftASTContext : public TypeSystemSwift { CompilerType GetAsClangType(ConstString mangled_name); + /// Retrieve the stored properties for the given nominal type declaration. + llvm::ArrayRef + GetStoredProperties(swift::NominalTypeDecl *nominal); + + SwiftEnumDescriptor *GetCachedEnumInfo(lldb::opaque_compiler_type_t type); + + friend class CompilerType; + + void ApplyDiagnosticOptions(); + + /// Apply a PathMappingList dictionary on all search paths in the + /// ClangImporterOptions. + void RemapClangImporterOptions(const PathMappingList &path_map); + /// Data members. /// @{ std::weak_ptr m_typeref_typesystem; @@ -993,8 +1007,6 @@ class SwiftASTContext : public TypeSystemSwift { typedef ThreadSafeDenseSet SwiftMangledNameSet; SwiftMangledNameSet m_negative_type_cache; - /// @} - /// Record the set of stored properties for each nominal type declaration /// for which we've asked this question. /// @@ -1004,19 +1016,7 @@ class SwiftASTContext : public TypeSystemSwift { llvm::DenseMap> m_stored_properties; - /// Retrieve the stored properties for the given nominal type declaration. - llvm::ArrayRef - GetStoredProperties(swift::NominalTypeDecl *nominal); - - SwiftEnumDescriptor *GetCachedEnumInfo(lldb::opaque_compiler_type_t type); - - friend class CompilerType; - - void ApplyDiagnosticOptions(); - - /// Apply a PathMappingList dictionary on all search paths in the - /// ClangImporterOptions. - void RemapClangImporterOptions(const PathMappingList &path_map); + /// @} }; /// Deprecated. @@ -1033,9 +1033,9 @@ class SwiftASTContextForModule : public SwiftASTContext { static bool classof(const TypeSystem *ts) { return ts->isA(&ID); } /// \} - SwiftASTContextForModule(std::string description, + SwiftASTContextForModule(std::string description, lldb::ModuleSP module_sp, TypeSystemSwiftTypeRefSP typeref_typesystem) - : SwiftASTContext(description, typeref_typesystem) {} + : SwiftASTContext(description, module_sp, typeref_typesystem) {} virtual ~SwiftASTContextForModule(); }; @@ -1053,6 +1053,7 @@ class SwiftASTContextForExpressions : public SwiftASTContext { /// \} SwiftASTContextForExpressions(std::string description, + lldb::ModuleSP module_sp, TypeSystemSwiftTypeRefSP typeref_typesystem); virtual ~SwiftASTContextForExpressions(); diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index a177388289070..a115be8dfc0f8 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -387,12 +387,13 @@ CompilerType TypeSystemSwiftTypeRef::GetTypeFromTypeMetadataNode( return RemangleAsType(dem, type, flavor); } -TypeSP TypeSystemSwiftTypeRef::LookupClangType(StringRef name_ref) { +TypeSP TypeSystemSwiftTypeRef::LookupClangType(StringRef name_ref, + SymbolContext sc) { llvm::SmallVector decl_context; // Make up a decl context for non-nested types. decl_context.push_back({CompilerContextKind::AnyModule, ConstString()}); decl_context.push_back({CompilerContextKind::AnyType, ConstString(name_ref)}); - return LookupClangType(name_ref, decl_context); + return LookupClangType(name_ref, decl_context, sc); } /// Look up one Clang type in a module. @@ -408,8 +409,11 @@ static TypeSP LookupClangType(Module &m, TypeSP TypeSystemSwiftTypeRef::LookupClangType( StringRef name_ref, llvm::ArrayRef decl_context, - ExecutionContext *exe_ctx) { - Module *m = GetModule(); + SymbolContext sc) { + + Module *m = sc.module_sp.get(); + if (!m) + m = GetModule(); if (!m) return {}; return ::LookupClangType(const_cast(*m), decl_context); @@ -417,23 +421,14 @@ TypeSP TypeSystemSwiftTypeRef::LookupClangType( TypeSP TypeSystemSwiftTypeRefForExpressions::LookupClangType( StringRef name_ref, llvm::ArrayRef decl_context, - ExecutionContext *exe_ctx) { + SymbolContext sc) { // Check the cache first. Negative results are also cached. TypeSP result; ConstString name(name_ref); if (m_clang_type_cache.Lookup(name.AsCString(), result)) return result; - TargetSP target_sp = GetTargetWP().lock(); - if (!target_sp) - return {}; - - ModuleSP cur_module; - if (exe_ctx) - if (StackFrame *frame = exe_ctx->GetFramePtr()) - cur_module = - frame->GetSymbolContext(lldb::eSymbolContextModule).module_sp; - + ModuleSP cur_module = sc.module_sp; auto lookup = [&](const ModuleSP &m) -> bool { // Already visited this. if (m == cur_module) @@ -453,7 +448,9 @@ TypeSP TypeSystemSwiftTypeRefForExpressions::LookupClangType( if (!lookup(cur_module)) return result; - target_sp->GetImages().ForEach(lookup); + if (TargetSP target_sp = GetTargetWP().lock()) + target_sp->GetImages().ForEach(lookup); + return result; } diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h index d6531ebca38f5..6c52e5fb76f5e 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h @@ -421,14 +421,14 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { /// Search the debug info for a non-nested Clang type with the specified name /// and cache the result. Users should prefer the version that takes in the /// decl_context. - lldb::TypeSP LookupClangType(llvm::StringRef name_ref); + lldb::TypeSP LookupClangType(llvm::StringRef name_ref, SymbolContext sc = {}); /// Search the debug info for a Clang type with the specified name and decl /// context. virtual lldb::TypeSP LookupClangType(llvm::StringRef name_ref, llvm::ArrayRef decl_context, - ExecutionContext *exe_ctx = nullptr); + SymbolContext sc = {}); /// Attempts to convert a Clang type into a Swift type. /// For example, int is converted to Int32. @@ -648,11 +648,9 @@ class TypeSystemSwiftTypeRefForExpressions : public TypeSystemSwiftTypeRef { unsigned GetGeneration() const { return m_generation; } /// Performs a target-wide search. /// \param exe_ctx is a hint for where to look first. - lldb::TypeSP - LookupClangType(llvm::StringRef name_ref, - llvm::ArrayRef decl_context, - ExecutionContext *exe_ctx) override; - + lldb::TypeSP LookupClangType(llvm::StringRef name_ref, + llvm::ArrayRef decl_context, + SymbolContext sc = {}) override; friend class SwiftASTContextForExpressions; protected: diff --git a/lldb/test/API/lang/swift/first_expr_module_load/TestFirstExprModuleLoad.py b/lldb/test/API/lang/swift/first_expr_module_load/TestFirstExprModuleLoad.py deleted file mode 100644 index df3efd0f98ed9..0000000000000 --- a/lldb/test/API/lang/swift/first_expr_module_load/TestFirstExprModuleLoad.py +++ /dev/null @@ -1,5 +0,0 @@ -import lldbsuite.test.lldbinline as lldbinline -from lldbsuite.test.decorators import * - -lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest, skipUnlessFoundation, skipIf(oslist=['windows']) -]) diff --git a/lldb/test/API/lang/swift/first_expr_module_load/TestSwiftFirstExprModuleLoad.py b/lldb/test/API/lang/swift/first_expr_module_load/TestSwiftFirstExprModuleLoad.py new file mode 100644 index 0000000000000..b29808072dbb6 --- /dev/null +++ b/lldb/test/API/lang/swift/first_expr_module_load/TestSwiftFirstExprModuleLoad.py @@ -0,0 +1,20 @@ +import lldb +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbtest as lldbtest +import lldbsuite.test.lldbutil as lldbutil + +class TestSwiftFirstExprModuleLoad(lldbtest.TestBase): + + @skipIf(oslist='windows') + @swiftTest + @skipUnlessFoundation + def test_unknown_self_objc_ref(self): + self.build() + lldbutil.run_to_source_breakpoint( + self, 'break here', lldb.SBFileSpec('main.swift')) + # FIXME: This runs into a known bug where the mangled names + # for private types from reflection metadata contain pointer + # values as discriminators, but the ones from debug info / + # Swift modules contain UUIDs. (rdar://74374120) + self.runCmd("settings set symbols.swift-validate-typesystem false") + self.expect('expr -d run -- self', substrs=['NSAttributedString']) diff --git a/lldb/test/API/lang/swift/first_expr_module_load/main.swift b/lldb/test/API/lang/swift/first_expr_module_load/main.swift index 5fe6164396714..741a4bd22b397 100644 --- a/lldb/test/API/lang/swift/first_expr_module_load/main.swift +++ b/lldb/test/API/lang/swift/first_expr_module_load/main.swift @@ -5,9 +5,10 @@ protocol MyProtocol { } extension MyProtocol { - func foo() -> String { - return "\(self)" //%self.expect('expr -d run -- self', substrs=['NSAttributedString']) - } + func foo() -> String { + print("break here") + return "\(self)" + } } extension NSAttributedString: MyProtocol {} diff --git a/lldb/test/Shell/Swift/Inputs/No.swiftmodule-ObjC.swift b/lldb/test/Shell/Swift/Inputs/No.swiftmodule-ObjC.swift index 71fc8542d57d2..25a99eb538dc5 100644 --- a/lldb/test/Shell/Swift/Inputs/No.swiftmodule-ObjC.swift +++ b/lldb/test/Shell/Swift/Inputs/No.swiftmodule-ObjC.swift @@ -11,7 +11,7 @@ func f() { // FIXME: (ObjCClass) object = {{.*}}Hello from Objective-C! let object = ObjCClass() // The Objective-C runtime recognizes this as a tagged pointer. - // CHECK-DAG: (NSNumber) inlined = {{.*}}Int64(42) + // CHECK-DAG: ({{.*}}NS{{.*}}Number) inlined = {{.*}}Int64(42) let inlined = NSNumber(value: 42) // CHECK-DAG: (CMYK) enumerator = .yellow let enumerator = yellow diff --git a/lldb/test/Shell/SwiftREPL/DictBridging.test b/lldb/test/Shell/SwiftREPL/DictBridging.test index 68ad3f2ea026c..d07d57a9c0f01 100644 --- a/lldb/test/Shell/SwiftREPL/DictBridging.test +++ b/lldb/test/Shell/SwiftREPL/DictBridging.test @@ -55,7 +55,7 @@ let d_objc1 = NSArray(object: [:] as [NSNumber: NSNumber] as NSDictionary) // Verbatim bridging let d_objc2 = NSArray(object: [1: 2] as [NSNumber: NSNumber] as NSDictionary) // DICT-LABEL: d_objc2: NSArray = 1 element { -// DICT-NEXT: [0] = 1 key/value pair { +// DICT: = 1 key/value pair { // DICT-NEXT: [0] = { // DICT-NEXT: key = Int64(1) // DICT-NEXT: value = Int64(2) @@ -66,8 +66,9 @@ let d_objc2 = NSArray(object: [1: 2] as [NSNumber: NSNumber] as NSDictionary) // Non-verbatim bridging let d_objc3 = NSArray(object: [1: 2] as [Int: Int] as NSDictionary) // DICT-LABEL: d_objc3: NSArray = 1 element { -// DICT-NEXT: [0] = 1 key/value pair { -// DICT-NEXT: [0] = (key = 1, value = 2) +// DICT: = 1 key/value pair { +// DICT: key = 1 +// DICT: value = 2 // DICT-NEXT: } // DICT-NEXT: } diff --git a/lldb/test/Shell/SwiftREPL/SetBridging.test b/lldb/test/Shell/SwiftREPL/SetBridging.test index 03fc9d26003aa..4a061bd543714 100644 --- a/lldb/test/Shell/SwiftREPL/SetBridging.test +++ b/lldb/test/Shell/SwiftREPL/SetBridging.test @@ -44,7 +44,7 @@ let s_objc1 = NSArray(object: [] as Set as NSSet) // Verbatim bridging let s_objc2 = NSArray(object: [1] as Set as NSSet) // SET-LABEL: s_objc2: NSArray = 1 element { -// SET-NEXT: [0] = 1 value { +// SET: = 1 value { // SET-NEXT: [0] = Int64(1) // SET-NEXT: } // SET-NEXT: } @@ -52,7 +52,7 @@ let s_objc2 = NSArray(object: [1] as Set as NSSet) // Non-verbatim bridging let s_objc3 = NSArray(object: [1] as Set as NSSet) // SET-LABEL: s_objc3: NSArray = 1 element { -// SET-NEXT: [0] = 1 value { +// SET: = 1 value { // SET-NEXT: [0] = 1 // SET-NEXT: } // SET-NEXT: }