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 context_free = 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 (context_free)
927+ eval_options.SetUseContextFreeSwiftPrintObject ();
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,17 @@ 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+ Log *log (GetLog (LLDBLog::DataFormatters | LLDBLog::Expressions));
955963 formatters::StringPrinter::ReadStringAndDumpToStreamOptions dump_options;
956964 dump_options.SetEscapeNonPrintables (false );
957965 dump_options.SetQuote (' \0 ' );
958966 dump_options.SetPrefixToken (nullptr );
959967 if (formatters::swift::String_SummaryProvider (
960- *result_sp. get (), result ,
968+ *result_sp, strm ,
961969 TypeSummaryOptions ()
962970 .SetLanguage (lldb::eLanguageTypeSwift)
963971 .SetCapping (eTypeSummaryUncapped),
@@ -973,6 +981,15 @@ llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr(
973981 return llvm::createStringError (" expression produced unprintable string" );
974982}
975983
984+ llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr (
985+ ValueObject &object, std::string &expr_string, Stream &strm) {
986+ auto result_or_err = RunObjectDescription (object, expr_string, GetProcess ());
987+ if (!result_or_err)
988+ return result_or_err.takeError ();
989+
990+ return DumpString (*result_or_err, strm);
991+ }
992+
976993static bool IsVariable (ValueObject &object) {
977994 if (object.IsSynthetic ())
978995 return IsVariable (*object.GetNonSyntheticValue ());
@@ -1002,11 +1019,80 @@ static bool IsSwiftReferenceType(ValueObject &object) {
10021019 return false ;
10031020}
10041021
1022+ static llvm::Error PrintObjectViaPointer (Stream &strm, ValueObject &object,
1023+ Process &process) {
1024+ Flags flags (object.GetCompilerType ().GetTypeInfo ());
1025+ addr_t addr = LLDB_INVALID_ADDRESS;
1026+ if (flags.Test (eTypeInstanceIsPointer)) {
1027+ // Objects are pointers.
1028+ addr = object.GetValueAsUnsigned (LLDB_INVALID_ADDRESS);
1029+ addr = process.FixDataAddress (addr);
1030+ } else {
1031+ // Get the address of non-object values (structs, enums).
1032+ auto addr_and_type = object.GetAddressOf (false );
1033+ if (addr_and_type.type != eAddressTypeLoad) {
1034+ return llvm::createStringError (" address-of value object failed" );
1035+ }
1036+ addr = addr_and_type.address ;
1037+ }
1038+
1039+ if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
1040+ return llvm::createStringError (" invalid address 0x%x" , addr);
1041+
1042+ StringRef mangled_type_name = object.GetMangledTypeName ();
1043+ // Swift APIs that receive mangled names require the prefix removed.
1044+ mangled_type_name.consume_front (" $s" );
1045+ mangled_type_name.consume_front (" $e" ); // Embedded Swift prefix
1046+
1047+ std::string expr_string =
1048+ llvm::formatv (
1049+ " Swift._DebuggerSupport.stringForPrintObject(UnsafeRawPointer("
1050+ " bitPattern: {0}), mangledTypeName: \" {1}\" )" ,
1051+ addr, mangled_type_name)
1052+ .str ();
1053+
1054+ auto result_or_err = RunObjectDescription (object, expr_string, process, true );
1055+ if (!result_or_err)
1056+ return result_or_err.takeError ();
1057+
1058+ // A `(Bool, String)` tuple, where the bool indicates success/failure.
1059+ auto result_sp = *result_or_err;
1060+ auto success_sp = result_sp->GetChildAtIndex (0 );
1061+ auto description_sp = result_sp->GetChildAtIndex (1 );
1062+
1063+ StreamString string_result;
1064+ auto err = DumpString (description_sp, string_result);
1065+ if (err) {
1066+ return llvm::joinErrors (
1067+ std::move (err),
1068+ llvm::createStringError (" decoding of description String failed" ));
1069+ }
1070+
1071+ Status status;
1072+ if (!success_sp->IsLogicalTrue (status))
1073+ // The Bool is false, which means the String is an error message.
1074+ return llvm::createStringError (string_result.GetData ());
1075+
1076+ strm.PutCString (string_result.GetString ());
1077+ return llvm::Error::success ();
1078+ }
1079+
10051080llvm::Error SwiftLanguageRuntime::GetObjectDescription (Stream &str,
10061081 ValueObject &object) {
10071082 if (object.IsUninitializedReference ())
10081083 return llvm::createStringError (" <uninitialized>" );
10091084
1085+ Log *log = GetLog (LLDBLog::DataFormatters | LLDBLog::Expressions);
1086+ if (GetProcess ().GetTarget ().GetSwiftUseContextFreePrintObject ()) {
1087+ if (auto err = PrintObjectViaPointer (str, object, GetProcess ())) {
1088+ LLDB_LOG_ERROR (log, std::move (err),
1089+ " stringForPrintObject(_:mangledTypeName) failed: {0}" );
1090+ } else {
1091+ LLDB_LOG (log, " stringForPrintObject(_:mangledTypeName:) succeeded" );
1092+ return llvm::Error::success ();
1093+ }
1094+ }
1095+
10101096 std::string expr_string;
10111097
10121098 if (::IsVariable (object) || ::IsSwiftResultVariable (object.GetName ())) {
0 commit comments