From d7572b37c29c9adf9ff9f1c5aafbf13575e6d3ff Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 13 May 2025 09:50:35 -0700 Subject: [PATCH 1/3] [lldb] Factor our binding generic variadic types (NFC) --- .../Swift/SwiftLanguageRuntime.h | 3 + ...ftLanguageRuntimeDynamicTypeResolution.cpp | 184 +++++++++--------- .../Swift/TypeSystemSwiftTypeRef.cpp | 36 ++++ .../TypeSystem/Swift/TypeSystemSwiftTypeRef.h | 11 ++ 4 files changed, 143 insertions(+), 91 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h index 91bb9165a2518..579c8895b2214 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h @@ -273,6 +273,9 @@ class SwiftLanguageRuntime : public LanguageRuntime { Address &address, Value::ValueType &value_type, llvm::ArrayRef &local_buffer) override; + llvm::Expected BindGenericPackType(StackFrame &frame, + CompilerType pack_type, + bool *indirect = nullptr); CompilerType BindGenericTypeParameters( CompilerType unbound_type, std::function finder); diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp index 61d69d3ffb1b9..929c2f00e2521 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -1764,50 +1764,33 @@ CreatePackType(swift::Demangle::Demangler &dem, TypeSystemSwiftTypeRef &ts, return pack; } -bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( - ValueObject &in_value, CompilerType pack_type, - lldb::DynamicValueType use_dynamic, TypeAndOrName &pack_type_or_name, - Address &address, Value::ValueType &value_type) { - Log *log(GetLog(LLDBLog::Types)); +llvm::Expected +SwiftLanguageRuntime::BindGenericPackType(StackFrame &frame, + CompilerType pack_type, bool *is_indirect) { + swift::Demangle::Demangler dem; + Target &target = GetProcess().GetTarget(); + size_t ptr_size = GetProcess().GetAddressByteSize(); + ConstString func_name = frame.GetSymbolContext(eSymbolContextFunction) + .GetFunctionName(Mangled::ePreferMangled); ThreadSafeReflectionContext reflection_ctx = GetReflectionContext(); if (!reflection_ctx) - return false; - - // Return a tuple type, with one element per pack element and its - // type has all DependentGenericParamType that appear in type packs - // substituted. - - StackFrameSP frame = in_value.GetExecutionContextRef().GetFrameSP(); - if (!frame) - return false; - ConstString func_name = frame->GetSymbolContext(eSymbolContextFunction) - .GetFunctionName(Mangled::ePreferMangled); + return llvm::createStringError("no reflection context"); // Extract the generic signature from the function symbol. auto ts = pack_type.GetTypeSystem().dyn_cast_or_null(); if (!ts) - return false; + return llvm::createStringError("no type system"); auto signature = - SwiftLanguageRuntime::GetGenericSignature(func_name.GetStringRef(), *ts); - if (!signature) { - LLDB_LOG(log, "cannot decode pack_expansion type: failed to decode generic " - "signature from function name"); - return false; - } - // This type has already been resolved? - if (auto info = ts->IsSILPackType(pack_type)) - if (info->expanded) - return false; - - Target &target = GetProcess().GetTarget(); - size_t ptr_size = GetProcess().GetAddressByteSize(); - - swift::Demangle::Demangler dem; + SwiftLanguageRuntime::GetGenericSignature(func_name.GetStringRef(), *ts); + if (!signature) + return llvm::createStringError( + "cannot decode pack_expansion type: failed to decode generic signature " + "from function name"); auto expand_pack_type = [&](ConstString mangled_pack_type, bool indirect, swift::Mangle::ManglingFlavor flavor) - -> swift::Demangle::NodePointer { + -> llvm::Expected { // Find pack_type in the pack_expansions. unsigned i = 0; SwiftLanguageRuntime::GenericSignature::PackExpansion *pack_expansion = @@ -1819,11 +1802,10 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( } ++i; } - if (!pack_expansion) { - LLDB_LOG(log, "cannot decode pack_expansion type: failed to find a " - "matching type in the function signature"); - return {}; - } + if (!pack_expansion) + return llvm::createStringError( + "cannot decode pack_expansion type: failed to find a matching type " + "in the function signature"); // Extract the count. llvm::SmallString<16> buf; @@ -1831,14 +1813,12 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( os << "$pack_count_" << signature->GetCountForValuePack(i); StringRef count_var = os.str(); std::optional count = - GetTypeMetadataForTypeNameAndFrame(count_var, *frame); - if (!count) { - LLDB_LOG(log, - "cannot decode pack_expansion type: failed to find count " - "argument \"%s\" in frame", - count_var.str()); - return {}; - } + GetTypeMetadataForTypeNameAndFrame(count_var, frame); + if (!count) + return llvm::createStringError( + "cannot decode pack_expansion type: failed to find count argument " + "\"%s\" in frame", + count_var.str().c_str()); // Extract the metadata for the type packs in this value pack. llvm::SmallDenseMap, lldb::addr_t> type_packs; @@ -1861,13 +1841,13 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( os << u8"$\u03C4_" << shape.depth << '_' << shape.index; StringRef mds_var = os.str(); std::optional mds_ptr = - GetTypeMetadataForTypeNameAndFrame(mds_var, *frame); + GetTypeMetadataForTypeNameAndFrame(mds_var, frame); if (!mds_ptr) { - LLDB_LOG(log, - "cannot decode pack_expansion type: failed to find " - "metadata " - "for \"{0}\" in frame", - mds_var.str()); + LLDB_LOG(GetLog(LLDBLog::Types), + "cannot decode pack_expansion type: failed to find " + "metadata " + "for \"{0}\" in frame", + mds_var.str()); error = true; return; } @@ -1876,7 +1856,7 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( } }); if (error) - return {}; + return llvm::createStringError("cannot decode pack_expansion type"); // Walk the type packs. std::vector elements; @@ -1893,29 +1873,25 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( Status status; lldb::addr_t md = LLDB_INVALID_ADDRESS; target.ReadMemory(md_ptr, &md, ptr_size, status, true); - if (!status.Success()) { - LLDB_LOGF(log, + if (!status.Success()) + return llvm::createStringError( "cannot decode pack_expansion type: failed to read type " "pack for type %d/%d of type pack with shape %d %d", j, (unsigned)*count, depth, index); - return {}; - } auto type_ref_or_err = reflection_ctx->ReadTypeFromMetadata(md, ts->GetDescriptorFinder()); - if (!type_ref_or_err) { - LLDB_LOG_ERRORV(GetLog(LLDBLog::Types), type_ref_or_err.takeError(), - "{0}"); - LLDB_LOGF(log, - "cannot decode pack_expansion type: failed to decode type " - "metadata for type %d/%d of type pack with shape %d %d", - j, (unsigned)*count, depth, index); - return {}; - } + if (!type_ref_or_err) + return llvm::joinErrors( + llvm::createStringError( + "cannot decode pack_expansion type: failed to decode type " + "metadata for type %d/%d of type pack with shape %d %d", + j, (unsigned)*count, depth, index), + type_ref_or_err.takeError()); substitutions.insert({{depth, index}, &*type_ref_or_err}); } if (substitutions.empty()) - return {}; + return llvm::createStringError("found no substitutions"); // Replace all pack expansions with a singular type. Otherwise the // reflection context won't accept them. @@ -1932,21 +1908,15 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( // Build a TypeRef from the demangle tree. auto type_ref_or_err = reflection_ctx->GetTypeRef( dem, pack_element, ts->GetDescriptorFinder()); - if (!type_ref_or_err) { - LLDB_LOG_ERRORV(GetLog(LLDBLog::Types), type_ref_or_err.takeError(), - "{0}"); - return {}; - } + if (!type_ref_or_err) + return type_ref_or_err.takeError(); auto &type_ref = *type_ref_or_err; // Apply the substitutions. auto bound_typeref_or_err = reflection_ctx->ApplySubstitutions( type_ref, substitutions, ts->GetDescriptorFinder()); - if (!bound_typeref_or_err) { - LLDB_LOG_ERRORV(GetLog(LLDBLog::Types), bound_typeref_or_err.takeError(), - "{0}"); - return {}; - } + if (!bound_typeref_or_err) + return bound_typeref_or_err.takeError(); swift::Demangle::NodePointer node = bound_typeref_or_err->getDemangling(dem); CompilerType type = ts->RemangleAsType(dem, node, flavor); @@ -1976,12 +1946,14 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( auto flavor = SwiftLanguageRuntime::GetManglingFlavor(pack_type.GetMangledTypeName()); + bool indirect = false; // Expand all the pack types that appear in the incoming type, // either at the root level or as arguments of bound generic types. - bool indirect = false; - auto transformed = TypeSystemSwiftTypeRef::Transform( - dem, node, [&](swift::Demangle::NodePointer node) { + auto transformed = TypeSystemSwiftTypeRef::TryTransform( + dem, node, + [&](swift::Demangle::NodePointer node) + -> llvm::Expected { if (node->getKind() == swift::Demangle::Node::Kind::SILPackIndirect) indirect = true; if (node->getKind() != swift::Demangle::Node::Kind::SILPackIndirect && @@ -1994,17 +1966,48 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( node = node->getChild(0); CompilerType pack_type = ts->RemangleAsType(dem, node, flavor); ConstString mangled_pack_type = pack_type.GetMangledTypeName(); - LLDB_LOG(log, "decoded pack_expansion type: {0}", mangled_pack_type); - auto result = expand_pack_type(mangled_pack_type, indirect, flavor); - if (!result) { - LLDB_LOG(log, "failed to expand pack type: {0}", mangled_pack_type); - return node; - } - return result; + LLDB_LOG(GetLog(LLDBLog::Types), "decoded pack_expansion type: {0}", + mangled_pack_type); + return expand_pack_type(mangled_pack_type, indirect, flavor); }); - CompilerType expanded_type = ts->RemangleAsType(dem, transformed, flavor); - pack_type_or_name.SetCompilerType(expanded_type); + if (!transformed) + return transformed.takeError(); + if (is_indirect) + *is_indirect = indirect; + return ts->RemangleAsType(dem, *transformed, flavor); +} + +bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( + ValueObject &in_value, CompilerType pack_type, + lldb::DynamicValueType use_dynamic, TypeAndOrName &pack_type_or_name, + Address &address, Value::ValueType &value_type) { + Log *log(GetLog(LLDBLog::Types)); + // Return a tuple type, with one element per pack element and its + // type has all DependentGenericParamType that appear in type packs + // substituted. + + StackFrameSP frame = in_value.GetExecutionContextRef().GetFrameSP(); + if (!frame) + return false; + + // This type has already been resolved? + auto ts = + pack_type.GetTypeSystem().dyn_cast_or_null(); + if (!ts) + return false; + if (auto info = ts->IsSILPackType(pack_type)) + if (info->expanded) + return false; + + bool indirect = false; + llvm::Expected expanded_type = + BindGenericPackType(*frame, pack_type, &indirect); + if (!expanded_type) { + LLDB_LOG_ERROR(GetLog(LLDBLog::Types), expanded_type.takeError(), "{0}"); + return false; + } + pack_type_or_name.SetCompilerType(*expanded_type); AddressType address_type; lldb::addr_t addr = in_value.GetAddressOf(true, &address_type); @@ -2014,7 +2017,7 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack( addr = GetProcess().ReadPointerFromMemory(addr, status); if (status.Fail()) { LLDB_LOG(log, "failed to dereference indirect pack: {0}", - expanded_type.GetMangledTypeName()); + expanded_type->GetMangledTypeName()); return false; } } @@ -3425,7 +3428,6 @@ SwiftLanguageRuntime::GetSwiftRuntimeTypeInfo( CompilerType type, ExecutionContextScope *exe_scope, swift::reflection::TypeRef const **out_tr) { Log *log(GetLog(LLDBLog::Types)); - if (log && log->GetVerbose()) LLDB_LOG(log, "[SwiftLanguageRuntime::GetSwiftRuntimeTypeInfo] Getting " diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 3006a55163793..32c87960190c4 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1150,6 +1150,42 @@ swift::Demangle::NodePointer TypeSystemSwiftTypeRef::Transform( return fn(node); } +llvm::Expected +TypeSystemSwiftTypeRef::TryTransform( + swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, + std::function( + swift::Demangle::NodePointer)> + fn) { + if (!node) + return node; + using namespace swift::Demangle; + llvm::SmallVector children; + bool changed = false; + for (NodePointer child : *node) { + llvm::Expected transformed_or_err = TryTransform(dem, child, fn); + if (!transformed_or_err) + return transformed_or_err.takeError(); + NodePointer transformed = *transformed_or_err; + changed |= (child != transformed); + assert(transformed && "callback returned a nullptr"); + if (transformed) + children.push_back(transformed); + } + if (changed) { + // Create a new node with the transformed children. + auto kind = node->getKind(); + if (node->hasText()) + node = dem.createNodeWithAllocatedText(kind, node->getText()); + else if (node->hasIndex()) + node = dem.createNode(kind, node->getIndex()); + else + node = dem.createNode(kind); + for (NodePointer transformed_child : children) + node->addChild(transformed_child, dem); + } + return fn(node); +} + void TypeSystemSwiftTypeRef::PreOrderTraversal( swift::Demangle::NodePointer node, std::function visitor) { diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h index ccb6a43f86307..1b10082901f7d 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h @@ -366,6 +366,17 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { std::function visitor); + /// Recursively transform the demangle tree starting a \p node by + /// doing a post-order traversal and replacing each node with + /// fn(node). + /// The NodePointer passed to \p fn is guaranteed to be non-null. + static llvm::Expected + TryTransform(swift::Demangle::Demangler &dem, + swift::Demangle::NodePointer node, + std::function( + swift::Demangle::NodePointer)> + visitor); + /// A left-to-right preorder traversal. Don't visit children if /// visitor returns false. static void From 50f15f2a48716ab000b0ff906b163e5813da6a3d Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 13 May 2025 16:12:21 -0700 Subject: [PATCH 2/3] [lldb] Make variadic generic types work with TypeSystemSwiftTypeRef The missing ingredient were the reflection support for pack types, and binding pack type in BindGenericParameters(). rdar://145257088 --- .../Swift/SwiftLanguageRuntime.h | 16 ++++-- ...ftLanguageRuntimeDynamicTypeResolution.cpp | 50 +++++++++++++++---- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h index 579c8895b2214..53cd81803c80f 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h @@ -346,12 +346,20 @@ class SwiftLanguageRuntime : public LanguageRuntime { unsigned dependent_generic_param_count = 0; unsigned num_counts = 0; - unsigned GetNumValuePacks() { return count_for_value_pack.size(); } - unsigned GetNumTypePacks() { return count_for_type_pack.size(); } - unsigned GetCountForValuePack(unsigned i) { + unsigned GetNumValuePacks() const { return count_for_value_pack.size(); } + unsigned GetNumTypePacks() const { return count_for_type_pack.size(); } + unsigned GetCountForValuePack(unsigned i) const { return count_for_value_pack[i]; } - unsigned GetCountForTypePack(unsigned i) { return count_for_type_pack[i]; } + unsigned GetCountForTypePack(unsigned i) const { return count_for_type_pack[i]; } + bool HasPacks() const { return pack_expansions.size(); } + bool IsPack(unsigned depth, unsigned index) const { + if (HasPacks()) + for (auto param : generic_params) + if (param.depth == depth && param.index == index) + return param.is_pack; + return false; + } }; /// Extract the generic signature out of a mangled Swift function name. static std::optional diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp index 929c2f00e2521..0329bfc2223cd 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -1767,6 +1767,9 @@ CreatePackType(swift::Demangle::Demangler &dem, TypeSystemSwiftTypeRef &ts, llvm::Expected SwiftLanguageRuntime::BindGenericPackType(StackFrame &frame, CompilerType pack_type, bool *is_indirect) { + // This mode is used only by GetDynamicTypeAndAddress_Pack(). It would be + // cleaner if we could get rid of it. + bool rewrite_indirect_packs = (is_indirect != nullptr); swift::Demangle::Demangler dem; Target &target = GetProcess().GetTarget(); size_t ptr_size = GetProcess().GetAddressByteSize(); @@ -1788,9 +1791,10 @@ SwiftLanguageRuntime::BindGenericPackType(StackFrame &frame, "cannot decode pack_expansion type: failed to decode generic signature " "from function name"); - auto expand_pack_type = [&](ConstString mangled_pack_type, bool indirect, + auto expand_pack_type = [&](ConstString mangled_pack_type, + bool rewrite_indirect, swift::Mangle::ManglingFlavor flavor) - -> llvm::Expected { + -> llvm::Expected { // Find pack_type in the pack_expansions. unsigned i = 0; SwiftLanguageRuntime::GenericSignature::PackExpansion *pack_expansion = @@ -1923,30 +1927,31 @@ SwiftLanguageRuntime::BindGenericPackType(StackFrame &frame, // Add the substituted type to the tuple. elements.push_back({{}, type}); } - if (indirect) { + + // TODO: Could we get rid of this code path? + if (rewrite_indirect) { // Create a tuple type with all the concrete types in the pack. CompilerType tuple = ts->CreateTupleType(elements); // TODO: Remove unnecessary mangling roundtrip. // Wrap the type inside a SILPackType to mark it for GetChildAtIndex. - CompilerType sil_pack_type = ts->CreateSILPackType(tuple, indirect); + CompilerType sil_pack_type = ts->CreateSILPackType(tuple, rewrite_indirect); swift::Demangle::NodePointer global = dem.demangleSymbol(sil_pack_type.GetMangledTypeName().GetStringRef()); using Kind = Node::Kind; auto *dem_sil_pack_type = swift_demangle::ChildAtPath(global, {Kind::TypeMangling, Kind::Type}); return dem_sil_pack_type; - } else { - return CreatePackType(dem, *ts, elements); } + return CreatePackType(dem, *ts, elements); }; swift::Demangle::Context dem_ctx; auto node = dem_ctx.demangleSymbolAsNode( pack_type.GetMangledTypeName().GetStringRef()); + bool indirect = false; auto flavor = SwiftLanguageRuntime::GetManglingFlavor(pack_type.GetMangledTypeName()); - bool indirect = false; // Expand all the pack types that appear in the incoming type, // either at the root level or as arguments of bound generic types. @@ -1968,13 +1973,16 @@ SwiftLanguageRuntime::BindGenericPackType(StackFrame &frame, ConstString mangled_pack_type = pack_type.GetMangledTypeName(); LLDB_LOG(GetLog(LLDBLog::Types), "decoded pack_expansion type: {0}", mangled_pack_type); - return expand_pack_type(mangled_pack_type, indirect, flavor); + return expand_pack_type(mangled_pack_type, + rewrite_indirect_packs && indirect, flavor); }); if (!transformed) return transformed.takeError(); + if (is_indirect) *is_indirect = indirect; + return ts->RemangleAsType(dem, *transformed, flavor); } @@ -2626,7 +2634,6 @@ SwiftLanguageRuntime::BindGenericTypeParameters(StackFrame &stack_frame, LLDB_SCOPED_TIMER(); using namespace swift::Demangle; - Status error; ThreadSafeReflectionContext reflection_ctx = GetReflectionContext(); if (!reflection_ctx) { LLDB_LOG(GetLog(LLDBLog::Expressions | LLDBLog::Types), @@ -2634,6 +2641,12 @@ SwiftLanguageRuntime::BindGenericTypeParameters(StackFrame &stack_frame, return ts.GetTypeFromMangledTypename(mangled_name); } + + ConstString func_name = stack_frame.GetSymbolContext(eSymbolContextFunction) + .GetFunctionName(Mangled::ePreferMangled); + // Extract the generic signature from the function symbol. + auto generic_signature = + SwiftLanguageRuntime::GetGenericSignature(func_name.GetStringRef(), ts); Demangler dem; NodePointer canonical = TypeSystemSwiftTypeRef::GetStaticSelfType( @@ -2645,6 +2658,9 @@ SwiftLanguageRuntime::BindGenericTypeParameters(StackFrame &stack_frame, ForEachGenericParameter(canonical, [&](unsigned depth, unsigned index) { if (substitutions.count({depth, index})) return; + // Packs will be substituted in a second pass. + if (generic_signature && generic_signature->IsPack(depth, index)) + return; StreamString mdvar_name; mdvar_name.Printf(u8"$\u03C4_%d_%d", depth, index); @@ -2674,7 +2690,8 @@ SwiftLanguageRuntime::BindGenericTypeParameters(StackFrame &stack_frame, return CompilerType(); return ts.GetTypeFromMangledTypename(ConstString(mangling.result())); }; - if (substitutions.empty()) + if (substitutions.empty() && + !(generic_signature && generic_signature->HasPacks())) return get_canonical(); // Build a TypeRef from the demangle tree. @@ -2717,6 +2734,17 @@ SwiftLanguageRuntime::BindGenericTypeParameters(StackFrame &stack_frame, CompilerType bound_type = scratch_ctx->RemangleAsType(dem, node, flavor); LLDB_LOG(GetLog(LLDBLog::Expressions | LLDBLog::Types), "Bound {0} -> {1}.", mangled_name, bound_type.GetMangledTypeName()); + + if (generic_signature && generic_signature->HasPacks()) { + auto bound_type_or_err = BindGenericPackType(stack_frame, bound_type); + if (!bound_type_or_err) { + LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions | LLDBLog::Types), + bound_type_or_err.takeError(), "{0}"); + return bound_type; + } + bound_type = *bound_type_or_err; + } + return bound_type; } @@ -3449,7 +3477,7 @@ SwiftLanguageRuntime::GetSwiftRuntimeTypeInfo( // GetCanonicalType() returned an Expected. return llvm::createStringError( "could not get canonical type (possibly due to unresolved typealias)"); -} + } // Resolve all generic type parameters in the type for the current // frame. Generic parameter binding has to happen in the scratch From e48e8aad0b3b1808260e520b1f92f0e608f15ce9 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 13 May 2025 16:58:07 -0700 Subject: [PATCH 3/3] [lldb] Convert BindGenericTypeParameters to llvm::Expected --- .../Swift/SwiftExpressionParser.cpp | 30 +++++---- .../Swift/SwiftLanguageRuntime.cpp | 10 ++- .../Swift/SwiftLanguageRuntime.h | 15 ++--- ...ftLanguageRuntimeDynamicTypeResolution.cpp | 61 ++++++++----------- .../Swift/SwiftLanguageRuntimeNames.cpp | 10 ++- .../Swift/SwiftLanguageRuntimeRemoteAST.cpp | 7 ++- .../TypeSystem/Swift/SwiftASTContext.cpp | 4 +- 7 files changed, 77 insertions(+), 60 deletions(-) diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp index 53aaac127329c..c746e42df7bc0 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp @@ -470,7 +470,9 @@ static CompilerType GetSwiftTypeForVariableValueObject( if (!result) return {}; if (SwiftASTManipulator::ShouldBindGenericTypes(bind_generic_types)) - result = runtime->BindGenericTypeParameters(*stack_frame_sp, result); + result = llvm::expectedToOptional( + runtime->BindGenericTypeParameters(*stack_frame_sp, result)) + .value_or(CompilerType()); if (!result) return {}; if (!result.GetTypeSystem()->SupportsLanguage(lldb::eLanguageTypeSwift)) @@ -606,12 +608,17 @@ AddRequiredAliases(Block *block, lldb::StackFrameSP &stack_frame_sp, auto *stack_frame = stack_frame_sp.get(); if (SwiftASTManipulator::ShouldBindGenericTypes(bind_generic_types)) { - imported_self_type = swift_runtime->BindGenericTypeParameters( + auto bound_type_or_err = swift_runtime->BindGenericTypeParameters( *stack_frame, imported_self_type); - if (!imported_self_type) - return llvm::createStringError( - "Unable to add the aliases the expression needs because the Swift " - "expression parser couldn't bind the type parameters for self."); + if (!bound_type_or_err) + return llvm::joinErrors( + llvm::createStringError( + "Unable to add the aliases the expression needs because the " + "Swift expression parser couldn't bind the type parameters for " + "self."), + bound_type_or_err.takeError()); + + imported_self_type = *bound_type_or_err; } { @@ -1224,16 +1231,17 @@ AddArchetypeTypeAliases(std::unique_ptr &code_manipulator, auto flavor = SwiftLanguageRuntime::GetManglingFlavor(type_name); auto dependent_type = typeref_typesystem->CreateGenericTypeParamType( info.depth, info.index, flavor); - auto bound_type = + auto bound_type_or_err = runtime->BindGenericTypeParameters(stack_frame, dependent_type); - if (!bound_type) { - LLDB_LOG( - log, + if (!bound_type_or_err) { + LLDB_LOG_ERROR( + log, bound_type_or_err.takeError(), "[AddArchetypeTypeAliases] Could not bind dependent generic param " - "type {0}", + "type {1}: {0}", dependent_type.GetMangledTypeName()); continue; } + auto bound_type = *bound_type_or_err; LLDB_LOG(log, "[AddArchetypeTypeAliases] Binding dependent generic param " diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index 3800eebcf0dc1..77f94870b7a97 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -868,8 +868,14 @@ std::string SwiftLanguageRuntime::GetObjectDescriptionExpr_Copy( auto swift_ast_ctx = static_type.GetTypeSystem().dyn_cast_or_null(); - if (swift_ast_ctx) - static_type = BindGenericTypeParameters(*frame_sp, static_type); + if (swift_ast_ctx) { + auto bound_type_or_err = BindGenericTypeParameters(*frame_sp, static_type); + if (!bound_type_or_err) { + LLDB_LOG_ERROR(log, bound_type_or_err.takeError(), "{0}"); + return {}; + } + static_type = *bound_type_or_err; + } auto stride = 0; auto opt_stride = static_type.GetByteStride(frame_sp.get()); diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h index 53cd81803c80f..8c2e001bc514f 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h @@ -370,8 +370,8 @@ class SwiftLanguageRuntime : public LanguageRuntime { /// version of \p base_type that replaces all generic type /// parameters with bound generic types. If a generic type parameter /// cannot be resolved, the input type is returned. - CompilerType BindGenericTypeParameters(StackFrame &stack_frame, - CompilerType base_type); + llvm::Expected + BindGenericTypeParameters(StackFrame &stack_frame, CompilerType base_type); bool IsStoredInlineInBuffer(CompilerType type) override; @@ -591,13 +591,14 @@ class SwiftLanguageRuntime : public LanguageRuntime { GetRemoteASTContext(SwiftASTContext &swift_ast_ctx); /// Like \p BindGenericTypeParameters but for TypeSystemSwiftTypeRef. - CompilerType BindGenericTypeParameters(StackFrame &stack_frame, - TypeSystemSwiftTypeRef &ts, - ConstString mangled_name); + llvm::Expected + BindGenericTypeParameters(StackFrame &stack_frame, TypeSystemSwiftTypeRef &ts, + ConstString mangled_name); /// Like \p BindGenericTypeParameters but for RemoteAST. - CompilerType BindGenericTypeParametersRemoteAST(StackFrame &stack_frame, - CompilerType base_type); + llvm::Expected + BindGenericTypeParametersRemoteAST(StackFrame &stack_frame, + CompilerType base_type); bool GetDynamicTypeAndAddress_Pack(ValueObject &in_value, CompilerType pack_type, diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp index 0329bfc2223cd..6729f91f8d3c5 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -498,8 +498,10 @@ SwiftLanguageRuntime::GetMemberVariableOffsetRemoteMirrors( auto frame = instance ? instance->GetExecutionContextRef().GetFrameSP().get() : nullptr; auto ti_or_err = GetSwiftRuntimeTypeInfo(instance_type, frame); - if (!ti_or_err) + if (!ti_or_err) { LLDB_LOG_ERRORV(GetLog(LLDBLog::Types), ti_or_err.takeError(), "{0}"); + return {}; + } auto *ti = &*ti_or_err; if (auto *rti = llvm::dyn_cast_or_null(ti)) { @@ -2627,7 +2629,7 @@ CompilerType SwiftLanguageRuntime::BindGenericTypeParameters( unbound_type.GetMangledTypeName())); } -CompilerType +llvm::Expected SwiftLanguageRuntime::BindGenericTypeParameters(StackFrame &stack_frame, TypeSystemSwiftTypeRef &ts, ConstString mangled_name) { @@ -2635,12 +2637,8 @@ SwiftLanguageRuntime::BindGenericTypeParameters(StackFrame &stack_frame, using namespace swift::Demangle; ThreadSafeReflectionContext reflection_ctx = GetReflectionContext(); - if (!reflection_ctx) { - LLDB_LOG(GetLog(LLDBLog::Expressions | LLDBLog::Types), - "No reflection context available."); - return ts.GetTypeFromMangledTypename(mangled_name); - } - + if (!reflection_ctx) + return llvm::createStringError("no reflection context"); ConstString func_name = stack_frame.GetSymbolContext(eSymbolContextFunction) .GetFunctionName(Mangled::ePreferMangled); @@ -2697,24 +2695,17 @@ SwiftLanguageRuntime::BindGenericTypeParameters(StackFrame &stack_frame, // Build a TypeRef from the demangle tree. auto type_ref_or_err = reflection_ctx->GetTypeRef(dem, canonical, ts.GetDescriptorFinder()); - if (!type_ref_or_err) { - LLDB_LOG_ERROR( - GetLog(LLDBLog::Expressions | LLDBLog::Types), - type_ref_or_err.takeError(), - "Couldn't get type ref when binding generic type parameters: {0}"); - return get_canonical(); - } + if (!type_ref_or_err) + return llvm::joinErrors( + llvm::createStringError("cannot bind generic parameters"), + type_ref_or_err.takeError()); // Apply the substitutions. auto bound_type_ref_or_err = reflection_ctx->ApplySubstitutions( *type_ref_or_err, substitutions, ts.GetDescriptorFinder()); - if (!bound_type_ref_or_err) { - LLDB_LOG_ERROR( - GetLog(LLDBLog::Expressions | LLDBLog::Types), - bound_type_ref_or_err.takeError(), - "Couldn't get type ref when binding generic type parameters: {0}"); - return get_canonical(); - } + if (!bound_type_ref_or_err) + return bound_type_ref_or_err.takeError(); + NodePointer node = bound_type_ref_or_err->getDemangling(dem); // Import the type into the scratch context. Subsequent conversions @@ -2726,29 +2717,24 @@ SwiftLanguageRuntime::BindGenericTypeParameters(StackFrame &stack_frame, // the original context as to resolve type aliases correctly. auto &target = GetProcess().GetTarget(); auto scratch_ctx = TypeSystemSwiftTypeRefForExpressions::GetForTarget(target); - if (!scratch_ctx) { - LLDB_LOG(GetLog(LLDBLog::Expressions | LLDBLog::Types), - "No scratch context available."); - return ts.GetTypeFromMangledTypename(mangled_name); - } + if (!scratch_ctx) + return llvm::createStringError("No scratch context available."); + CompilerType bound_type = scratch_ctx->RemangleAsType(dem, node, flavor); LLDB_LOG(GetLog(LLDBLog::Expressions | LLDBLog::Types), "Bound {0} -> {1}.", mangled_name, bound_type.GetMangledTypeName()); if (generic_signature && generic_signature->HasPacks()) { auto bound_type_or_err = BindGenericPackType(stack_frame, bound_type); - if (!bound_type_or_err) { - LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions | LLDBLog::Types), - bound_type_or_err.takeError(), "{0}"); - return bound_type; - } + if (!bound_type_or_err) + return bound_type_or_err.takeError(); bound_type = *bound_type_or_err; } return bound_type; } -CompilerType +llvm::Expected SwiftLanguageRuntime::BindGenericTypeParameters(StackFrame &stack_frame, CompilerType base_type) { // If this is a TypeRef type, bind that. @@ -3232,7 +3218,9 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress( if (!frame) return false; - bound_type = BindGenericTypeParameters(*frame.get(), val_type); + bound_type = llvm::expectedToOptional( + BindGenericTypeParameters(*frame.get(), val_type)) + .value_or(CompilerType()); if (!bound_type) return false; } else { @@ -3486,7 +3474,10 @@ SwiftLanguageRuntime::GetSwiftRuntimeTypeInfo( if (StackFrame *frame = exe_scope->CalculateStackFrame().get()) { ExecutionContext exe_ctx; frame->CalculateExecutionContext(exe_ctx); - type = BindGenericTypeParameters(*frame, type); + auto bound_type_or_err = BindGenericTypeParameters(*frame, type); + if (!bound_type_or_err) + return bound_type_or_err.takeError(); + type = *bound_type_or_err; } // BindGenericTypeParameters imports the type into the scratch diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeNames.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeNames.cpp index 98a9c1dfd2c9a..bd2ebde6bbceb 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeNames.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeNames.cpp @@ -694,9 +694,15 @@ void SwiftLanguageRuntime::GetGenericParameterNamesForFunction( break; CompilerType generic_type = ts->CreateGenericTypeParamType(depth, index, flavor); - CompilerType bound_type = + llvm::Expected bound_type_or_err = runtime->BindGenericTypeParameters(*frame, generic_type); - type_name = bound_type.GetDisplayTypeName(); + if (!bound_type_or_err) { + LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions | LLDBLog::Types), + bound_type_or_err.takeError(), "{0}"); + break; + } + + type_name = bound_type_or_err->GetDisplayTypeName(); break; } diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeRemoteAST.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeRemoteAST.cpp index 4da692895c8e5..2a8b8ba3be2f6 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeRemoteAST.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeRemoteAST.cpp @@ -133,7 +133,9 @@ std::optional SwiftLanguageRuntime::GetMemberVariableOffsetRemoteAST( // Bind generic parameters if necessary. if (instance && swift_type->hasTypeParameter()) if (auto *frame = instance->GetExecutionContextRef().GetFrameSP().get()) - if (auto bound = BindGenericTypeParameters(*frame, instance_type)) { + if (auto bound = llvm::expectedToOptional( + BindGenericTypeParameters(*frame, instance_type)) + .value_or(CompilerType())) { LLDB_LOGF( GetLog(LLDBLog::Types), "[MemberVariableOffsetResolver] resolved non-class type = %s", @@ -266,7 +268,8 @@ SwiftLanguageRuntime::GetDynamicTypeAndAddress_ExistentialRemoteAST( } #endif -CompilerType SwiftLanguageRuntime::BindGenericTypeParametersRemoteAST( +llvm::Expected +SwiftLanguageRuntime::BindGenericTypeParametersRemoteAST( StackFrame &stack_frame, CompilerType base_type) { LLDB_SCOPED_TIMER(); diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 2afc0df806670..fe9518a8265cd 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -5863,7 +5863,9 @@ BindGenericTypeParameters(CompilerType type, ExecutionContextScope *exe_scope) { return type; ExecutionContext exe_ctx; exe_scope->CalculateExecutionContext(exe_ctx); - if (auto bound = runtime->BindGenericTypeParameters(*frame, type)) + if (auto bound = llvm::expectedToOptional( + runtime->BindGenericTypeParameters(*frame, type)) + .value_or(CompilerType())) return bound; return type; }