1818#include " lldb/Target/Target.h"
1919#include " lldb/Utility/StreamString.h"
2020
21+ #include " swift/AST/ASTContext.h"
22+ #include " swift/AST/ASTMangler.h"
2123#include " swift/Basic/LangOptions.h"
2224#include " swift/Demangling/Demangle.h"
2325#include " swift/Demangling/Demangler.h"
@@ -30,8 +32,11 @@ using namespace lldb_private;
3032
3133namespace lldb_private {
3234std::optional<std::pair<unsigned , unsigned >>
33- ParseSwiftGenericParameter (llvm::StringRef name) {
34- if (!name.consume_front (" $τ_" ))
35+ ParseSwiftGenericParameter (llvm::StringRef name, bool expect_dollar_prefix) {
36+ if (expect_dollar_prefix && !name.consume_front (" $" ))
37+ return {};
38+
39+ if (!name.consume_front (" τ_" ))
3540 return {};
3641
3742 auto pair = name.split (' _' );
@@ -165,6 +170,127 @@ static llvm::Expected<llvm::SmallVector<MetadataInfo>> CollectMetadataInfos(
165170 }
166171 return metadata_info;
167172}
173+
174+ // / Returns a map from the index and depth to the archetype name, for example,
175+ // / given: struct S<T, U> {} This function returns {{0, 0} -> T, {0, 1} -> U}.
176+ static llvm::DenseMap<std::pair<unsigned , unsigned >, llvm::StringRef>
177+ MakeIndexAndDepthToArchetypeMap (
178+ llvm::ArrayRef<swift::Requirement> requirements) {
179+ llvm::DenseMap<std::pair<unsigned , unsigned >, llvm::StringRef> map;
180+ for (auto &req : requirements) {
181+ if (req.getKind () != swift::RequirementKind::Conformance)
182+ continue ;
183+ auto type = req.getFirstType ();
184+ auto *generic_type =
185+ llvm::dyn_cast<swift::GenericTypeParamType>(type.getPointer ());
186+ if (!generic_type)
187+ continue ;
188+
189+ unsigned depth = generic_type->getDepth ();
190+ unsigned index = generic_type->getIndex ();
191+ auto name = generic_type->getName ().str ();
192+ map.insert ({{depth, index}, name});
193+ }
194+ return map;
195+ }
196+
197+ struct ParsedWitnessTable {
198+ // / The full name of the variable in debug info. For example:
199+ // / $WTτ_0_0$SubType$$MangledProtocol.
200+ llvm::StringRef full_name;
201+ // / The archetype name, for example T.SubType
202+ std::string archetype_name;
203+ // / The mangled protocol name.
204+ llvm::StringRef mangled_protocol_name;
205+ // / The "display" protocol name.
206+ std::string protocol_name;
207+ ParsedWitnessTable (llvm::StringRef full_name, std::string archetype_name,
208+ llvm::StringRef mangled_protocol_name,
209+ std::string protocol_name)
210+ : full_name(full_name), archetype_name(archetype_name),
211+ mangled_protocol_name (mangled_protocol_name),
212+ protocol_name(protocol_name) {}
213+ };
214+
215+ // / Parses the witness table artificial variables.
216+ static llvm::Expected<llvm::SmallVector<ParsedWitnessTable>> ParseWitnessInfos (
217+ llvm::ArrayRef<SwiftASTManipulator::VariableInfo> local_variables,
218+ llvm::ArrayRef<swift::Requirement> requirements) {
219+ llvm::SmallVector<ParsedWitnessTable> witness_tables;
220+ auto indexes_to_archetype = MakeIndexAndDepthToArchetypeMap (requirements);
221+ for (auto &local_variable : local_variables) {
222+ if (!local_variable.IsWitnessTable ())
223+ continue ;
224+
225+ // Full name looks something like "$WTτ_0_0$SubType$$MangledProtocol.".
226+ auto full_name = local_variable.GetName ().str ();
227+ auto [metadata_name, mangled_protocol_name] = full_name.split (" $$" );
228+
229+ if (metadata_name.empty () || mangled_protocol_name.empty () ||
230+ !SwiftLanguageRuntime::IsSwiftMangledName (mangled_protocol_name))
231+ return llvm::createStringError (
232+ " malformed witness table name in debug info" );
233+
234+ metadata_name = metadata_name.drop_front (StringRef (" $WT" ).size ());
235+ auto [front, back] = metadata_name.split (' $' );
236+ auto maybe_depth_and_index =
237+ ParseSwiftGenericParameter (front, /* expect_dollar_prefix*/ false );
238+ if (!maybe_depth_and_index)
239+ return llvm::createStringError (
240+ " malformed witness table name in debug info" );
241+
242+ auto [depth, index] = *maybe_depth_and_index;
243+
244+ auto it = indexes_to_archetype.find ({depth, index});
245+ if (it == indexes_to_archetype.end ())
246+ return llvm::createStringError (
247+ " malformed witness table name in debug info" );
248+
249+ std::string archetype_name = it->getSecond ().str ();
250+ if (!back.empty ())
251+ archetype_name += " ." + back.str ();
252+ std::replace (archetype_name.begin (), archetype_name.end (), ' $' , ' .' );
253+ auto protocol_name =
254+ swift::Demangle::demangleSymbolAsString (mangled_protocol_name);
255+ witness_tables.emplace_back (full_name, archetype_name,
256+ mangled_protocol_name, protocol_name);
257+ }
258+
259+ // Order the witness tables according to the requirements, otherwise we risk
260+ // passing the witness table pointers in the wrong order when generating the
261+ // expression.
262+ llvm::SmallVector<ParsedWitnessTable> ordered_witness_tables;
263+ for (auto &Requirement : requirements) {
264+ if (Requirement.getKind () != swift::RequirementKind::Conformance)
265+ continue ;
266+ swift::ProtocolDecl *ProtocolDecl = Requirement.getProtocolDecl ();
267+ auto protocol_type = ProtocolDecl->getDeclaredType ();
268+ auto type = Requirement.getFirstType ();
269+ auto &ast_ctx = type->getASTContext ();
270+ swift::Mangle::ASTMangler mangler (ast_ctx, true );
271+ std::string mangled_protocol_name =
272+ mangler.mangleTypeForDebugger (protocol_type, nullptr );
273+ std::string name;
274+ if (auto *generic_type =
275+ llvm::dyn_cast<swift::GenericTypeParamType>(type.getPointer ()))
276+ name = generic_type->getName ().str ();
277+ else if (auto *dependent =
278+ llvm::dyn_cast<swift::DependentMemberType>(type.getPointer ()))
279+ name = dependent->getString ();
280+
281+ for (auto &parsed_witness_table : witness_tables) {
282+ if (name == parsed_witness_table.archetype_name &&
283+ mangled_protocol_name == parsed_witness_table.mangled_protocol_name ) {
284+ ordered_witness_tables.emplace_back (std::move (parsed_witness_table));
285+ }
286+ }
287+ }
288+ assert (ordered_witness_tables.size () == witness_tables.size () &&
289+ " Ordered witness table size does not match" );
290+
291+ return ordered_witness_tables;
292+ }
293+
168294// / Constructs the signatures for the expression evaluation functions based on
169295// / the metadata variables in scope and any variadic functiontion parameters.
170296// / For every outermost metadata pointer in scope ($τ_0_0, $τ_0_1, etc), we want
@@ -208,10 +334,27 @@ static llvm::Expected<CallsAndArgs> MakeGenericSignaturesAndCalls(
208334 return llvm::createStringError (llvm::errc::not_supported,
209335 " Inconsistent generic signature" );
210336
211- auto maybe_metadata_infos = CollectMetadataInfos (metadata_variables, generic_sig);
212- if (!maybe_metadata_infos)
213- return maybe_metadata_infos.takeError ();
214- auto metadata_infos = *maybe_metadata_infos;
337+ auto self = llvm::find_if (
338+ local_variables, [](const SwiftASTManipulator::VariableInfo &variable) {
339+ return variable.IsSelf ();
340+ });
341+ llvm::SmallVector<ParsedWitnessTable> witness_infos;
342+ if (self && self->GetUnboundType ()) {
343+ auto bound_generic = llvm::cast<swift::NominalOrBoundGenericNominalType>(
344+ self->GetUnboundType ().getPointer ());
345+ auto decl = bound_generic->getDecl ();
346+ auto requirements = decl->getGenericRequirements ();
347+ auto witness_infos_or_err = ParseWitnessInfos (local_variables, requirements);
348+ if (!witness_infos_or_err)
349+ return witness_infos_or_err.takeError ();
350+ witness_infos = *witness_infos_or_err;
351+ }
352+
353+ auto metatada_infos_or_err =
354+ CollectMetadataInfos (metadata_variables, generic_sig);
355+ if (!metatada_infos_or_err)
356+ return metatada_infos_or_err.takeError ();
357+ auto metadata_infos = *metatada_infos_or_err;
215358
216359 llvm::SmallDenseMap<std::pair<unsigned , unsigned >, llvm::SmallString<4 >> subs;
217360 std::string generic_params;
@@ -230,11 +373,17 @@ static llvm::Expected<CallsAndArgs> MakeGenericSignaturesAndCalls(
230373 s_generic_params << sig_archetype_name << " ," ;
231374 subs.insert ({{depth, index}, sig_archetype_name});
232375 }
376+ std::string type_constraints;
377+ llvm::raw_string_ostream s_type_constraints (type_constraints);
378+ for (auto &wi : witness_infos)
379+ s_type_constraints << wi.archetype_name << " : " << wi.protocol_name << " ," ;
233380
234381 if (!generic_params.empty ())
235382 generic_params.pop_back ();
236383 if (!generic_params_no_packs.empty ())
237384 generic_params_no_packs.pop_back ();
385+ if (!type_constraints.empty ())
386+ type_constraints.pop_back ();
238387
239388 std::string user_expr;
240389 llvm::raw_string_ostream user_expr_stream (user_expr);
@@ -250,6 +399,8 @@ static llvm::Expected<CallsAndArgs> MakeGenericSignaturesAndCalls(
250399 << *pack_type;
251400 }
252401 user_expr_stream << " )" ;
402+ if (!type_constraints.empty ())
403+ user_expr_stream << " where " << type_constraints;
253404
254405 std::string trampoline;
255406 llvm::raw_string_ostream trampoline_stream (trampoline);
@@ -259,6 +410,8 @@ static llvm::Expected<CallsAndArgs> MakeGenericSignaturesAndCalls(
259410 if (needs_object_ptr)
260411 trampoline_stream << " , _ $__lldb_injected_self: inout $__lldb_context" ;
261412 trampoline_stream << " )" ;
413+ if (!type_constraints.empty ())
414+ trampoline_stream << " where " << type_constraints;
262415
263416 std::string sink;
264417 std::string call;
@@ -291,6 +444,12 @@ static llvm::Expected<CallsAndArgs> MakeGenericSignaturesAndCalls(
291444 sink_stream << " , _: $__lldb_builtin_ptr_t" ;
292445 call_stream << " , " << var->GetName ().str ();
293446 }
447+
448+ for (auto &wi : witness_infos) {
449+ sink_stream << " , _: $__lldb_builtin_ptr_t" ;
450+ call_stream << " , " << wi.full_name ;
451+ }
452+
294453 sink_stream << " )" ;
295454 call_stream << " )" ;
296455
0 commit comments