4848#include " lldb/Utility/Log.h"
4949#include " lldb/Utility/OptionParsing.h"
5050#include " lldb/Utility/Status.h"
51+ #include " lldb/Utility/StreamString.h"
5152#include " lldb/Utility/StructuredData.h"
5253#include " lldb/Utility/Timer.h"
5354#include " lldb/ValueObject/ValueObject.h"
@@ -835,7 +836,7 @@ SwiftLanguageRuntime::GetObjectDescriptionExpr_Ref(ValueObject &object) {
835836 object.GetValueAsUnsigned (0 )).str ();
836837
837838 if (log)
838- log->Printf (" [GetObjectDescriptionExpr_Result ] expression: %s" ,
839+ log->Printf (" [GetObjectDescriptionExpr_Ref ] expression: %s" ,
839840 expr_string.GetData ());
840841 return expr_str;
841842}
@@ -911,25 +912,27 @@ std::string SwiftLanguageRuntime::GetObjectDescriptionExpr_Copy(
911912 return expr_string;
912913}
913914
914- llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr (
915- ValueObject &object, std::string &expr_string, Stream &result) {
915+ static llvm::Expected<ValueObjectSP>
916+ runObjectDescription (ValueObject &object, std::string &expr_string,
917+ Process &process, bool disable_availability = false ) {
916918 Log *log (GetLog (LLDBLog::DataFormatters | LLDBLog::Expressions));
917919 ValueObjectSP result_sp;
918920 EvaluateExpressionOptions eval_options;
919921 eval_options.SetUnwindOnError (true );
920922 eval_options.SetLanguage (lldb::eLanguageTypeSwift);
921923 eval_options.SetSuppressPersistentResult (true );
922924 eval_options.SetIgnoreBreakpoints (true );
923- eval_options.SetTimeout (GetProcess ().GetUtilityExpressionTimeout ());
925+ eval_options.SetTimeout (process.GetUtilityExpressionTimeout ());
926+ if (disable_availability)
927+ eval_options.SetDisableAvailability ();
924928
925929 StackFrameSP frame_sp = object.GetFrameSP ();
926930 if (!frame_sp)
927- frame_sp =
928- GetProcess ().GetThreadList ().GetSelectedThread ()->GetSelectedFrame (
929- DoNoSelectMostRelevantFrame);
931+ frame_sp = process.GetThreadList ().GetSelectedThread ()->GetSelectedFrame (
932+ DoNoSelectMostRelevantFrame);
930933 if (!frame_sp)
931934 return llvm::createStringError (" no execution context to run expression in" );
932- auto eval_result = GetProcess () .GetTarget ().EvaluateExpression (
935+ auto eval_result = process .GetTarget ().EvaluateExpression (
933936 expr_string, frame_sp.get (), result_sp, eval_options);
934937
935938 LLDB_LOG (log, " [RunObjectDescriptionExpr] {0}" , toString (eval_result));
@@ -952,12 +955,28 @@ llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr(
952955 return llvm::createStringError (" expression produced invalid result type" );
953956 }
954957
958+ return result_sp;
959+ }
960+
961+ static llvm::Error dumpString (ValueObjectSP result_sp, Stream &strm);
962+
963+ llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr (
964+ ValueObject &object, std::string &expr_string, Stream &strm) {
965+ auto result_or_err = runObjectDescription (object, expr_string, GetProcess ());
966+ if (!result_or_err)
967+ return result_or_err.takeError ();
968+
969+ return dumpString (*result_or_err, strm);
970+ }
971+
972+ static llvm::Error dumpString (ValueObjectSP result_sp, Stream &strm) {
973+ Log *log (GetLog (LLDBLog::DataFormatters | LLDBLog::Expressions));
955974 formatters::StringPrinter::ReadStringAndDumpToStreamOptions dump_options;
956975 dump_options.SetEscapeNonPrintables (false );
957976 dump_options.SetQuote (' \0 ' );
958977 dump_options.SetPrefixToken (nullptr );
959978 if (formatters::swift::String_SummaryProvider (
960- *result_sp. get (), result ,
979+ *result_sp, strm ,
961980 TypeSummaryOptions ()
962981 .SetLanguage (lldb::eLanguageTypeSwift)
963982 .SetCapping (eTypeSummaryUncapped),
@@ -1002,11 +1021,82 @@ static bool IsSwiftReferenceType(ValueObject &object) {
10021021 return false ;
10031022}
10041023
1024+ static bool printObjectViaPointer (Stream &strm, ValueObject &object,
1025+ Process &process) {
1026+ Log *log = GetLog (LLDBLog::DataFormatters | LLDBLog::Expressions);
1027+
1028+ Flags flags (object.GetCompilerType ().GetTypeInfo ());
1029+ addr_t addr = LLDB_INVALID_ADDRESS;
1030+ if (flags.Test (eTypeInstanceIsPointer)) {
1031+ // Objects are pointers.
1032+ addr = object.GetValueAsUnsigned (LLDB_INVALID_ADDRESS);
1033+ } else {
1034+ // Get the address of non-object values (structs, enums).
1035+ auto addr_and_type = object.GetAddressOf (false );
1036+ if (addr_and_type.type != eAddressTypeLoad) {
1037+ LLDB_LOG (log, " address-of value object failed, preventing use of "
1038+ " stringForPrintObject(_:mangledTypeName:)" );
1039+ return false ;
1040+ }
1041+ addr = addr_and_type.address ;
1042+ }
1043+
1044+ if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
1045+ return false ;
1046+
1047+ StringRef mangled_type_name = object.GetMangledTypeName ();
1048+ // Swift's APIs that accept mangled names require the "$s" prefix removed.
1049+ mangled_type_name.consume_front (" $s" );
1050+
1051+ std::string expr_string =
1052+ llvm::formatv (
1053+ " Swift._DebuggerSupport.stringForPrintObject(UnsafeRawPointer("
1054+ " bitPattern: {0}), mangledTypeName: \" {1}\" )" ,
1055+ addr, mangled_type_name)
1056+ .str ();
1057+
1058+ auto result_or_err = runObjectDescription (object, expr_string, process, true );
1059+ if (!result_or_err) {
1060+ LLDB_LOG_ERROR (log, result_or_err.takeError (),
1061+ " stringForPrintObject(_:mangledTypeName:) failed: {0}" );
1062+ return false ;
1063+ }
1064+
1065+ // A `(Bool, String)` tuple, where the bool indicates success/failure.
1066+ auto result_sp = *result_or_err;
1067+ auto success_sp = result_sp->GetChildAtIndex (0 );
1068+ auto description_sp = result_sp->GetChildAtIndex (1 );
1069+
1070+ StreamString dump_stream;
1071+ auto err = dumpString (description_sp, dump_stream);
1072+ if (err) {
1073+ LLDB_LOG_ERROR (log, std::move (err),
1074+ " decoding result of "
1075+ " stringForPrintObject(_:mangledTypeName:) failed: {0}" );
1076+ return false ;
1077+ }
1078+
1079+ Status status;
1080+ if (!success_sp->IsLogicalTrue (status)) {
1081+ LLDB_LOGF (log,
1082+ " stringForPrintObject(_:mangledTypeName:) produced error: %s" ,
1083+ dump_stream.GetData ());
1084+ return false ;
1085+ }
1086+
1087+ LLDB_LOG (log, " stringForPrintObject(_:mangledTypeName:) succeeded" );
1088+ strm.PutCString (dump_stream.GetString ());
1089+ return true ;
1090+ }
1091+
10051092llvm::Error SwiftLanguageRuntime::GetObjectDescription (Stream &str,
10061093 ValueObject &object) {
10071094 if (object.IsUninitializedReference ())
10081095 return llvm::createStringError (" <uninitialized>" );
10091096
1097+ if (tryPointerPrintObject (str, object, GetProcess ()))
1098+ return llvm::Error::success ();
1099+
10101100 std::string expr_string;
10111101
10121102 if (::IsVariable (object) || ::IsSwiftResultVariable (object.GetName ())) {
0 commit comments