@@ -274,6 +274,215 @@ void SwiftLanguageRuntime::ModulesDidLoad(const ModuleList &module_list) {
274274 });
275275}
276276
277+ static bool GetObjectDescription_ResultVariable (Process *process, Stream &str,
278+ ValueObject &object) {
279+ Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
280+
281+ StreamString expr_string;
282+ expr_string.Printf (" Swift._DebuggerSupport.stringForPrintObject(%s)" ,
283+ object.GetName ().GetCString ());
284+
285+ if (log)
286+ log->Printf (" [GetObjectDescription_ResultVariable] expression: %s" ,
287+ expr_string.GetData ());
288+
289+ ValueObjectSP result_sp;
290+ EvaluateExpressionOptions eval_options;
291+ eval_options.SetLanguage (lldb::eLanguageTypeSwift);
292+ eval_options.SetResultIsInternal (true );
293+ eval_options.SetGenerateDebugInfo (true );
294+ eval_options.SetTimeout (g_po_function_timeout);
295+ auto eval_result = process->GetTarget ().EvaluateExpression (
296+ expr_string.GetData (),
297+ process->GetThreadList ().GetSelectedThread ()->GetSelectedFrame ().get (),
298+ result_sp, eval_options);
299+
300+ if (log) {
301+ switch (eval_result) {
302+ case eExpressionCompleted:
303+ log->Printf (" [GetObjectDescription_ResultVariable] eExpressionCompleted" );
304+ break ;
305+ case eExpressionSetupError:
306+ log->Printf (
307+ " [GetObjectDescription_ResultVariable] eExpressionSetupError" );
308+ break ;
309+ case eExpressionParseError:
310+ log->Printf (
311+ " [GetObjectDescription_ResultVariable] eExpressionParseError" );
312+ break ;
313+ case eExpressionDiscarded:
314+ log->Printf (" [GetObjectDescription_ResultVariable] eExpressionDiscarded" );
315+ break ;
316+ case eExpressionInterrupted:
317+ log->Printf (
318+ " [GetObjectDescription_ResultVariable] eExpressionInterrupted" );
319+ break ;
320+ case eExpressionHitBreakpoint:
321+ log->Printf (
322+ " [GetObjectDescription_ResultVariable] eExpressionHitBreakpoint" );
323+ break ;
324+ case eExpressionTimedOut:
325+ log->Printf (" [GetObjectDescription_ResultVariable] eExpressionTimedOut" );
326+ break ;
327+ case eExpressionResultUnavailable:
328+ log->Printf (
329+ " [GetObjectDescription_ResultVariable] eExpressionResultUnavailable" );
330+ break ;
331+ case eExpressionStoppedForDebug:
332+ log->Printf (
333+ " [GetObjectDescription_ResultVariable] eExpressionStoppedForDebug" );
334+ break ;
335+ }
336+ }
337+
338+ // sanitize the result of the expression before moving forward
339+ if (!result_sp) {
340+ if (log)
341+ log->Printf (" [GetObjectDescription_ResultVariable] expression generated "
342+ " no result" );
343+ return false ;
344+ }
345+ if (result_sp->GetError ().Fail ()) {
346+ if (log)
347+ log->Printf (" [GetObjectDescription_ResultVariable] expression generated "
348+ " error: %s" ,
349+ result_sp->GetError ().AsCString ());
350+ return false ;
351+ }
352+ if (false == result_sp->GetCompilerType ().IsValid ()) {
353+ if (log)
354+ log->Printf (" [GetObjectDescription_ResultVariable] expression generated "
355+ " invalid type" );
356+ return false ;
357+ }
358+
359+ lldb_private::formatters::StringPrinter::ReadStringAndDumpToStreamOptions
360+ dump_options;
361+ dump_options.SetEscapeNonPrintables (false ).SetQuote (' \0 ' ).SetPrefixToken (
362+ nullptr );
363+ if (lldb_private::formatters::swift::String_SummaryProvider (
364+ *result_sp.get (), str, TypeSummaryOptions ()
365+ .SetLanguage (lldb::eLanguageTypeSwift)
366+ .SetCapping (eTypeSummaryUncapped),
367+ dump_options)) {
368+ if (log)
369+ log->Printf (" [GetObjectDescription_ResultVariable] expression completed "
370+ " successfully" );
371+ return true ;
372+ } else {
373+ if (log)
374+ log->Printf (" [GetObjectDescription_ResultVariable] expression generated "
375+ " invalid string data" );
376+ return false ;
377+ }
378+ }
379+
380+ static bool GetObjectDescription_ObjectReference (Process *process, Stream &str,
381+ ValueObject &object) {
382+ Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
383+
384+ StreamString expr_string;
385+ expr_string.Printf (" Swift._DebuggerSupport.stringForPrintObject(Swift."
386+ " unsafeBitCast(0x%" PRIx64 " , to: AnyObject.self))" ,
387+ object.GetValueAsUnsigned (0 ));
388+
389+ if (log)
390+ log->Printf (" [GetObjectDescription_ObjectReference] expression: %s" ,
391+ expr_string.GetData ());
392+
393+ ValueObjectSP result_sp;
394+ EvaluateExpressionOptions eval_options;
395+ eval_options.SetLanguage (lldb::eLanguageTypeSwift);
396+ eval_options.SetResultIsInternal (true );
397+ eval_options.SetGenerateDebugInfo (true );
398+ eval_options.SetTimeout (g_po_function_timeout);
399+ auto eval_result = process->GetTarget ().EvaluateExpression (
400+ expr_string.GetData (),
401+ process->GetThreadList ().GetSelectedThread ()->GetSelectedFrame ().get (),
402+ result_sp, eval_options);
403+
404+ if (log) {
405+ switch (eval_result) {
406+ case eExpressionCompleted:
407+ log->Printf (
408+ " [GetObjectDescription_ObjectReference] eExpressionCompleted" );
409+ break ;
410+ case eExpressionSetupError:
411+ log->Printf (
412+ " [GetObjectDescription_ObjectReference] eExpressionSetupError" );
413+ break ;
414+ case eExpressionParseError:
415+ log->Printf (
416+ " [GetObjectDescription_ObjectReference] eExpressionParseError" );
417+ break ;
418+ case eExpressionDiscarded:
419+ log->Printf (
420+ " [GetObjectDescription_ObjectReference] eExpressionDiscarded" );
421+ break ;
422+ case eExpressionInterrupted:
423+ log->Printf (
424+ " [GetObjectDescription_ObjectReference] eExpressionInterrupted" );
425+ break ;
426+ case eExpressionHitBreakpoint:
427+ log->Printf (
428+ " [GetObjectDescription_ObjectReference] eExpressionHitBreakpoint" );
429+ break ;
430+ case eExpressionTimedOut:
431+ log->Printf (" [GetObjectDescription_ObjectReference] eExpressionTimedOut" );
432+ break ;
433+ case eExpressionResultUnavailable:
434+ log->Printf (" [GetObjectDescription_ObjectReference] "
435+ " eExpressionResultUnavailable" );
436+ break ;
437+ case eExpressionStoppedForDebug:
438+ log->Printf (
439+ " [GetObjectDescription_ObjectReference] eExpressionStoppedForDebug" );
440+ break ;
441+ }
442+ }
443+
444+ // sanitize the result of the expression before moving forward
445+ if (!result_sp) {
446+ if (log)
447+ log->Printf (" [GetObjectDescription_ObjectReference] expression generated "
448+ " no result" );
449+ return false ;
450+ }
451+ if (result_sp->GetError ().Fail ()) {
452+ if (log)
453+ log->Printf (" [GetObjectDescription_ObjectReference] expression generated "
454+ " error: %s" ,
455+ result_sp->GetError ().AsCString ());
456+ return false ;
457+ }
458+ if (false == result_sp->GetCompilerType ().IsValid ()) {
459+ if (log)
460+ log->Printf (" [GetObjectDescription_ObjectReference] expression generated "
461+ " invalid type" );
462+ return false ;
463+ }
464+
465+ lldb_private::formatters::StringPrinter::ReadStringAndDumpToStreamOptions
466+ dump_options;
467+ dump_options.SetEscapeNonPrintables (false ).SetQuote (' \0 ' ).SetPrefixToken (
468+ nullptr );
469+ if (lldb_private::formatters::swift::String_SummaryProvider (
470+ *result_sp.get (), str, TypeSummaryOptions ()
471+ .SetLanguage (lldb::eLanguageTypeSwift)
472+ .SetCapping (eTypeSummaryUncapped),
473+ dump_options)) {
474+ if (log)
475+ log->Printf (" [GetObjectDescription_ObjectReference] expression completed "
476+ " successfully" );
477+ return true ;
478+ } else {
479+ if (log)
480+ log->Printf (" [GetObjectDescription_ObjectReference] expression generated "
481+ " invalid string data" );
482+ return false ;
483+ }
484+ }
485+
277486static const ExecutionContextRef *GetSwiftExeCtx (ValueObject &valobj) {
278487 return (valobj.GetPreferredDisplayLanguage () == eLanguageTypeSwift)
279488 ? &valobj.GetExecutionContextRef ()
@@ -440,12 +649,61 @@ static bool GetObjectDescription_ObjectCopy(SwiftLanguageRuntime *runtime,
440649 return true ;
441650}
442651
652+ static bool IsSwiftResultVariable (ConstString name) {
653+ if (name) {
654+ llvm::StringRef name_sr (name.GetStringRef ());
655+ if (name_sr.size () > 2 &&
656+ (name_sr.startswith (" $R" ) || name_sr.startswith (" $E" )) &&
657+ ::isdigit (name_sr[2 ]))
658+ return true;
659+ }
660+ return false ;
661+ }
662+
663+ static bool IsSwiftReferenceType (ValueObject &object) {
664+ CompilerType object_type (object.GetCompilerType ());
665+ if (llvm::dyn_cast_or_null<SwiftASTContext>(object_type.GetTypeSystem ())) {
666+ Flags type_flags (object_type.GetTypeInfo ());
667+ if (type_flags.AllSet (eTypeIsClass | eTypeHasValue |
668+ eTypeInstanceIsPointer))
669+ return true ;
670+ }
671+ return false ;
672+ }
673+
443674bool SwiftLanguageRuntime::GetObjectDescription (Stream &str,
444675 ValueObject &object) {
445676 if (object.IsUninitializedReference ()) {
446677 str.Printf (" <uninitialized>" );
447678 return true ;
448679 }
680+
681+ if (::IsSwiftResultVariable (object.GetName ())) {
682+ // if this thing is a Swift expression result variable, it has two
683+ // properties:
684+ // a) its name is something we can refer to in expressions for free
685+ // b) its type may be something we can't actually talk about in expressions
686+ // so, just use the result variable's name in the expression and be done
687+ // with it
688+ StreamString probe_stream;
689+ if (GetObjectDescription_ResultVariable (m_process, probe_stream, object)) {
690+ str.Printf (" %s" , probe_stream.GetData ());
691+ return true ;
692+ }
693+ } else if (::IsSwiftReferenceType (object)) {
694+ // if this is a Swift class, it has two properties:
695+ // a) we do not need its type name, AnyObject is just as good
696+ // b) its value is something we can directly use to refer to it
697+ // so, just use the ValueObject's pointer-value and be done with it
698+ StreamString probe_stream;
699+ if (GetObjectDescription_ObjectReference (m_process, probe_stream, object)) {
700+ str.Printf (" %s" , probe_stream.GetData ());
701+ return true ;
702+ }
703+ }
704+
705+ // in general, don't try to use the name of the ValueObject as it might end up
706+ // referring to the wrong thing
449707 return GetObjectDescription_ObjectCopy (this , m_process, str, object);
450708}
451709
0 commit comments