@@ -26,12 +26,96 @@ static const char *GetUserCodeStartMarker() {
26
26
}
27
27
static const char *GetUserCodeEndMarker () { return " \n /*__LLDB_USER_END__*/" ; }
28
28
29
- static void WrapExpression (lldb_private::Stream &wrapped_stream,
30
- const char *orig_text, bool needs_object_ptr,
31
- bool static_method, bool is_class, bool weak_self,
32
- const EvaluateExpressionOptions &options,
33
- llvm::StringRef os_version,
34
- uint32_t &first_body_line) {
29
+
30
+ struct CallsAndArgs {
31
+ std::string lldb_user_expr;
32
+ std::string lldb_trampoline;
33
+ std::string lldb_sink;
34
+ std::string lldb_call;
35
+ };
36
+
37
+ // / Constructs the signatures for the expression evaluation functions based on
38
+ // / the metadata variables in scope.
39
+ // / For every outermost metadata pointer in scope ($τ_0_0, $τ_0_1, etc), we want
40
+ // / to generate:
41
+ // /
42
+ // / - A $__lldb_user_expr signature that takes in that many metadata pointers:
43
+ // /
44
+ // / func $__lldb_user_expr<T0, T1, ..., Tn>
45
+ // / (_ $__lldb_arg: UnsafeMutablePointer<(T0, T1, ..., Tn)>)
46
+ // /
47
+ // / - A $__lldb_trampoline signature like the above, but that also takes in a
48
+ // / pointer to self:
49
+ // /
50
+ // / func $__lldb_trampoline<T0, T1, ..., Tn>
51
+ // / (_ $__lldb_arg: UnsafeMutablePointer<(T0, T1, ..., Tn)>,
52
+ // / _ $__lldb_injected_self: inout $__lldb_context)
53
+ // /
54
+ // / - A $__lldb_sink signature that matches the number of parameters of the
55
+ // / trampoline:
56
+ // /
57
+ // / func $__lldb_sink(_ $__lldb_arg : UnsafeMutablePointer<Any>,
58
+ // / _: $__lldb_builtin_ptr_t, // the self variable
59
+ // / _: $__lldb_builtin_ptr_t, // T0
60
+ // / _: $__lldb_builtin_ptr_t, // T1
61
+ // / ...,
62
+ // / _: $__lldb_builtin_ptr_t) // Tn
63
+ // /
64
+ // / - And a matching call to the sink function:
65
+ // /
66
+ // / lldb_sink($__lldb_arg, $__lldb_injected_self, $τ_0_0, $τ_0_1, ..., $τ_0_n)
67
+ static CallsAndArgs MakeGenericSignaturesAndCalls (
68
+ llvm::ArrayRef<SwiftASTManipulator::VariableInfo> local_variables) {
69
+ llvm::SmallVector<SwiftASTManipulator::VariableInfo> metadata_variables;
70
+ for (auto &var : local_variables)
71
+ if (var.IsOutermostMetadataPointer ())
72
+ metadata_variables.push_back (var);
73
+
74
+ std::string generic_param_list;
75
+ llvm::raw_string_ostream generic_param_list_stream (generic_param_list);
76
+ for (size_t i = 0 ; i < metadata_variables.size (); ++i)
77
+ generic_param_list_stream << " T" << i << " ," ;
78
+
79
+ if (!generic_param_list.empty ())
80
+ generic_param_list.pop_back ();
81
+
82
+ std::string user_expr;
83
+ llvm::raw_string_ostream user_expr_stream (user_expr);
84
+ user_expr_stream << " func $__lldb_user_expr<" << generic_param_list
85
+ << " >(_ $__lldb_arg: UnsafeMutablePointer<("
86
+ << generic_param_list << " )>)" ;
87
+
88
+
89
+ std::string trampoline;
90
+ llvm::raw_string_ostream trampoline_stream (trampoline);
91
+ trampoline_stream << " func $__lldb_trampoline<" << generic_param_list
92
+ << " >(_ $__lldb_arg: UnsafeMutablePointer<("
93
+ << generic_param_list
94
+ << " )>, _ $__lldb_injected_self: inout $__lldb_context)" ;
95
+
96
+ std::string sink;
97
+ std::string call;
98
+ llvm::raw_string_ostream sink_stream (sink);
99
+ llvm::raw_string_ostream call_stream (call);
100
+ sink_stream << " func $__lldb_sink(_ $__lldb_arg : "
101
+ " UnsafeMutablePointer<Any>, _: $__lldb_builtin_ptr_t" ;
102
+ call_stream << " $__lldb_sink($__lldb_arg, $__lldb_injected_self" ;
103
+ for (auto &var : metadata_variables) {
104
+ sink_stream << " , _: $__lldb_builtin_ptr_t" ;
105
+ call_stream << " , " << var.GetName ().str ();
106
+ }
107
+ sink_stream << " )" ;
108
+ call_stream << " )" ;
109
+
110
+ return {user_expr, trampoline, sink, call};
111
+ }
112
+
113
+ void WrapExpression (
114
+ lldb_private::Stream &wrapped_stream, const char *orig_text,
115
+ bool needs_object_ptr, bool static_method, bool is_class, bool weak_self,
116
+ const EvaluateExpressionOptions &options, llvm::StringRef os_version,
117
+ uint32_t &first_body_line,
118
+ llvm::ArrayRef<SwiftASTManipulator::VariableInfo> local_variables) {
35
119
first_body_line = 0 ; // set to invalid
36
120
// TODO make the extension private so we're not polluting the class
37
121
static unsigned int counter = 0 ;
142
226
}
143
227
)" ,
144
228
GetUserCodeStartMarker (), text,
145
- GetUserCodeEndMarker (), SwiftASTManipulator::GetErrorName ());
229
+ GetUserCodeEndMarker (),
230
+ SwiftASTManipulator::GetErrorName ());
146
231
147
232
if (needs_object_ptr || static_method) {
148
233
const char *func_decorator = " " ;
@@ -201,41 +286,41 @@ do {
201
286
// FIXME: the current approach names the generic parameter "T", use the
202
287
// user's name for the generic parameter, so they can refer to it in
203
288
// their expression.
289
+ auto c = MakeGenericSignaturesAndCalls (local_variables);
204
290
wrapped_stream.Printf (
205
291
R"(
206
292
extension %s$__lldb_context {
207
293
@LLDBDebuggerFunction %s
208
- %s func $__lldb_user_expr_%u<T>(_ $__lldb_arg: UnsafeMutablePointer<(T)>) {
294
+ %s %s {
209
295
%s
210
296
}
211
297
}
212
298
213
299
@LLDBDebuggerFunction %s
214
- func $__lldb_trampoline<T>(_ $__lldb_arg: UnsafeMutablePointer<(T)>,
215
- _ $__lldb_injected_self: inout $__lldb_context) {
300
+ %s {
216
301
do {
217
- $__lldb_injected_self.$__lldb_user_expr_%u (
302
+ $__lldb_injected_self.$__lldb_user_expr (
218
303
$__lldb_arg
219
304
)
220
305
}
221
306
}
222
307
223
308
224
309
@LLDBDebuggerFunction %s
225
- func $__lldb_sink(_ $__lldb_arg : UnsafeMutablePointer<Any>,
226
- _: $__lldb_builtin_ptr_t,
227
- _: $__lldb_builtin_ptr_t) {
310
+ %s {
228
311
}
229
312
230
313
231
314
@LLDBDebuggerFunction %s
232
315
func $__lldb_expr(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
233
- $__lldb_sink($__lldb_arg, $__lldb_injected_self, $τ_0_0)
316
+ %s
234
317
}
235
318
)" ,
236
319
optional_extension, availability.c_str (), func_decorator,
237
- current_counter, wrapped_expr_text.GetData (), availability.c_str (),
238
- current_counter, availability.c_str (), availability.c_str ());
320
+ c.lldb_user_expr .c_str (), wrapped_expr_text.GetData (),
321
+ availability.c_str (), c.lldb_trampoline .c_str (),
322
+ availability.c_str (), c.lldb_sink .c_str (), availability.c_str (),
323
+ c.lldb_call .c_str ());
239
324
240
325
} else {
241
326
wrapped_stream.Printf (R"(
@@ -270,6 +355,7 @@ func $__lldb_expr(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
270
355
first_body_line = 4 ;
271
356
}
272
357
}
358
+
273
359
// / Format the OS name the way that Swift availability attributes do.
274
360
static llvm::StringRef getAvailabilityName (const llvm::Triple &triple) {
275
361
swift::LangOptions lang_options;
@@ -285,16 +371,11 @@ uint32_t SwiftExpressionSourceCode::GetNumBodyLines() {
285
371
}
286
372
287
373
bool SwiftExpressionSourceCode::GetText (
288
- std::string &text,
289
- lldb::LanguageType wrapping_language,
290
- bool needs_object_ptr,
291
- bool static_method,
292
- bool is_class,
293
- bool weak_self,
294
- const EvaluateExpressionOptions &options,
295
- ExecutionContext &exe_ctx,
296
- uint32_t &first_body_line) const
297
- {
374
+ std::string &text, lldb::LanguageType wrapping_language,
375
+ bool needs_object_ptr, bool static_method, bool is_class, bool weak_self,
376
+ const EvaluateExpressionOptions &options, ExecutionContext &exe_ctx,
377
+ uint32_t &first_body_line,
378
+ llvm::ArrayRef<SwiftASTManipulator::VariableInfo> local_variables) const {
298
379
Target *target = exe_ctx.GetTargetPtr ();
299
380
300
381
@@ -364,7 +445,7 @@ bool SwiftExpressionSourceCode::GetText(
364
445
std::string full_body = m_prefix + m_body;
365
446
WrapExpression (wrap_stream, full_body.c_str (), needs_object_ptr,
366
447
static_method, is_class, weak_self, localOptions,
367
- os_vers.str (), first_body_line);
448
+ os_vers.str (), first_body_line, local_variables );
368
449
369
450
text = wrap_stream.GetString ().str ();
370
451
} else {
0 commit comments