18
18
#include " lldb/Target/Target.h"
19
19
#include " lldb/Utility/StreamString.h"
20
20
21
+ #include " swift/AST/ASTContext.h"
22
+ #include " swift/AST/ASTMangler.h"
21
23
#include " swift/Basic/LangOptions.h"
22
24
#include " swift/Demangling/Demangle.h"
23
25
#include " swift/Demangling/Demangler.h"
@@ -30,8 +32,11 @@ using namespace lldb_private;
30
32
31
33
namespace lldb_private {
32
34
std::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 (" τ_" ))
35
40
return {};
36
41
37
42
auto pair = name.split (' _' );
@@ -165,6 +170,127 @@ static llvm::Expected<llvm::SmallVector<MetadataInfo>> CollectMetadataInfos(
165
170
}
166
171
return metadata_info;
167
172
}
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
+
168
294
// / Constructs the signatures for the expression evaluation functions based on
169
295
// / the metadata variables in scope and any variadic functiontion parameters.
170
296
// / For every outermost metadata pointer in scope ($τ_0_0, $τ_0_1, etc), we want
@@ -208,10 +334,27 @@ static llvm::Expected<CallsAndArgs> MakeGenericSignaturesAndCalls(
208
334
return llvm::createStringError (llvm::errc::not_supported,
209
335
" Inconsistent generic signature" );
210
336
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;
215
358
216
359
llvm::SmallDenseMap<std::pair<unsigned , unsigned >, llvm::SmallString<4 >> subs;
217
360
std::string generic_params;
@@ -230,11 +373,17 @@ static llvm::Expected<CallsAndArgs> MakeGenericSignaturesAndCalls(
230
373
s_generic_params << sig_archetype_name << " ," ;
231
374
subs.insert ({{depth, index }, sig_archetype_name});
232
375
}
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 << " ," ;
233
380
234
381
if (!generic_params.empty ())
235
382
generic_params.pop_back ();
236
383
if (!generic_params_no_packs.empty ())
237
384
generic_params_no_packs.pop_back ();
385
+ if (!type_constraints.empty ())
386
+ type_constraints.pop_back ();
238
387
239
388
std::string user_expr;
240
389
llvm::raw_string_ostream user_expr_stream (user_expr);
@@ -250,6 +399,8 @@ static llvm::Expected<CallsAndArgs> MakeGenericSignaturesAndCalls(
250
399
<< *pack_type;
251
400
}
252
401
user_expr_stream << " )" ;
402
+ if (!type_constraints.empty ())
403
+ user_expr_stream << " where " << type_constraints;
253
404
254
405
std::string trampoline;
255
406
llvm::raw_string_ostream trampoline_stream (trampoline);
@@ -259,6 +410,8 @@ static llvm::Expected<CallsAndArgs> MakeGenericSignaturesAndCalls(
259
410
if (needs_object_ptr)
260
411
trampoline_stream << " , _ $__lldb_injected_self: inout $__lldb_context" ;
261
412
trampoline_stream << " )" ;
413
+ if (!type_constraints.empty ())
414
+ trampoline_stream << " where " << type_constraints;
262
415
263
416
std::string sink;
264
417
std::string call;
@@ -291,6 +444,12 @@ static llvm::Expected<CallsAndArgs> MakeGenericSignaturesAndCalls(
291
444
sink_stream << " , _: $__lldb_builtin_ptr_t" ;
292
445
call_stream << " , " << var->GetName ().str ();
293
446
}
447
+
448
+ for (auto &wi : witness_infos) {
449
+ sink_stream << " , _: $__lldb_builtin_ptr_t" ;
450
+ call_stream << " , " << wi.full_name ;
451
+ }
452
+
294
453
sink_stream << " )" ;
295
454
call_stream << " )" ;
296
455
0 commit comments