@@ -135,20 +135,25 @@ static bool makeStringGutsSummary(
135
135
static ConstString g__storage (" _storage" );
136
136
static ConstString g__value (" _value" );
137
137
138
+ auto error = [&](std::string message) {
139
+ stream << " <cannot decode string: " << message << " >" ;
140
+ return true ;
141
+ };
142
+
138
143
ProcessSP process (valobj.GetProcessSP ());
139
144
if (!process)
140
- return false ;
145
+ return error ( " no live process " ) ;
141
146
142
147
auto ptrSize = process->GetAddressByteSize ();
143
148
144
149
auto object_sp = valobj.GetChildMemberWithName (g__object, true );
145
150
if (!object_sp)
146
- return false ;
151
+ return error ( " unexpected layout " ) ;
147
152
148
153
// We retrieve String contents by first extracting the
149
154
// platform-independent 128-bit raw value representation from
150
155
// _StringObject, then interpreting that.
151
- Status error ;
156
+ Status status ;
152
157
uint64_t raw0;
153
158
uint64_t raw1;
154
159
@@ -160,12 +165,12 @@ static bool makeStringGutsSummary(
160
165
auto countAndFlagsBits = object_sp->GetChildAtNamePath (
161
166
{g__countAndFlagsBits, g__value});
162
167
if (!countAndFlagsBits)
163
- return false ;
168
+ return error ( " unexpected layout " ) ;
164
169
raw0 = countAndFlagsBits->GetValueAsUnsigned (0 );
165
170
166
171
auto object = object_sp->GetChildMemberWithName (g__object, true );
167
172
if (!object)
168
- return false ;
173
+ return error ( " unexpected layout (object) " ) ;
169
174
raw1 = object->GetValueAsUnsigned (0 );
170
175
} else if (ptrSize == 4 ) {
171
176
// On 32-bit platforms, we emulate what `_StringObject.rawBits`
@@ -179,23 +184,23 @@ static bool makeStringGutsSummary(
179
184
180
185
auto count_sp = object_sp->GetChildAtNamePath ({g__count, g__value});
181
186
if (!count_sp)
182
- return false ;
187
+ return error ( " unexpected layout (count) " ) ;
183
188
uint64_t count = count_sp->GetValueAsUnsigned (0 );
184
189
185
190
auto discriminator_sp =
186
191
object_sp->GetChildAtNamePath ({g__discriminator, g__value});
187
192
if (!discriminator_sp)
188
- return false ;
193
+ return error ( " unexpected layout (discriminator) " ) ;
189
194
uint64_t discriminator = discriminator_sp->GetValueAsUnsigned (0 ) & 0xff ;
190
195
191
196
auto flags_sp = object_sp->GetChildAtNamePath ({g__flags, g__value});
192
197
if (!flags_sp)
193
- return false ;
198
+ return error ( " unexpected layout (flags) " ) ;
194
199
uint64_t flags = flags_sp->GetValueAsUnsigned (0 ) & 0xffff ;
195
200
196
201
auto variant_sp = object_sp->GetChildMemberWithName (g__variant, true );
197
202
if (!variant_sp)
198
- return false ;
203
+ return error ( " unexpected layout (variant) " ) ;
199
204
200
205
llvm::StringRef variantCase = variant_sp->GetValueAsCString ();
201
206
@@ -208,18 +213,18 @@ static bool makeStringGutsSummary(
208
213
static ConstString g_bridged (" bridged" );
209
214
auto anyobject_sp = variant_sp->GetChildMemberWithName (g_bridged, true );
210
215
if (!anyobject_sp)
211
- return false ;
216
+ return error ( " unexpected layout (bridged) " ) ;
212
217
payload_sp = anyobject_sp->GetChildAtIndex (0 , true ); // "instance"
213
218
} else {
214
- // Unknown variant.
215
- return false ;
219
+ return error (" unknown variant" );
216
220
}
217
221
if (!payload_sp)
218
- return false ;
222
+ return error (" no payload" );
223
+
219
224
uint64_t pointerBits = payload_sp->GetValueAsUnsigned (LLDB_INVALID_ADDRESS);
220
225
221
226
if (pointerBits == LLDB_INVALID_ADDRESS)
222
- return false ;
227
+ return error ( " invalid payload " ) ;
223
228
224
229
if ((discriminator & 0xB0 ) == 0xA0 ) {
225
230
raw0 = count | (pointerBits << 32 );
@@ -229,8 +234,7 @@ static bool makeStringGutsSummary(
229
234
raw1 = pointerBits | (discriminator << 56 );
230
235
}
231
236
} else {
232
- lldbassert (false && " Unsupported pointer bit-width" );
233
- return false ;
237
+ return error (" unsupported pointer size" );
234
238
}
235
239
236
240
// Copied from StringObject.swift
@@ -306,7 +310,7 @@ static bool makeStringGutsSummary(
306
310
uint64_t count = (raw1 >> 56 ) & 0b1111 ;
307
311
uint64_t maxCount = (ptrSize == 8 ? 15 : 10 );
308
312
if (count > maxCount)
309
- return false ;
313
+ return error ( " count > maxCount " ) ;
310
314
311
315
uint64_t rawBuffer[2 ] = {raw0, raw1};
312
316
auto *buffer = (uint8_t *)&rawBuffer;
@@ -326,10 +330,16 @@ static bool makeStringGutsSummary(
326
330
uint64_t count = raw0 & 0x0000FFFFFFFFFFFF ;
327
331
uint16_t flags = raw0 >> 48 ;
328
332
lldb::addr_t objectAddress = (raw1 & 0x0FFFFFFFFFFFFFFF );
333
+ // Catch a zero-initialized string.
334
+ if (!objectAddress) {
335
+ stream << " <uninitialized>" ;
336
+ return true ;
337
+ }
338
+
329
339
if ((flags & 0x1000 ) != 0 ) { // Tail-allocated / biased address
330
340
// Tail-allocation is only for natively stored or literals.
331
341
if ((discriminator & 0b0111'0000 ) != 0 )
332
- return false ;
342
+ return error ( " unexpected discriminator " ) ;
333
343
uint64_t bias = (ptrSize == 8 ? 32 : 20 );
334
344
auto address = objectAddress + bias;
335
345
applySlice (address, count, slice);
@@ -344,9 +354,9 @@ static bool makeStringGutsSummary(
344
354
return false ;
345
355
uint64_t startOffset = (ptrSize == 8 ? 24 : 12 );
346
356
auto address = objectAddress + startOffset;
347
- lldb::addr_t start = process->ReadPointerFromMemory (address, error );
348
- if (error .Fail ())
349
- return false ;
357
+ lldb::addr_t start = process->ReadPointerFromMemory (address, status );
358
+ if (status .Fail ())
359
+ return error (status. AsCString ()) ;
350
360
351
361
applySlice (address, count, slice);
352
362
return readStringFromAddress (
@@ -355,13 +365,13 @@ static bool makeStringGutsSummary(
355
365
356
366
// Native/shared strings should already have been handled.
357
367
if ((discriminator & 0b0111'0000 ) == 0 )
358
- return false ;
368
+ return error ( " unexpected discriminator " ) ;
359
369
360
370
if ((discriminator & 0b1110'0000 ) == 0b0100'0000 ) { // 010xxxxx: Bridged
361
371
TypeSystemClangSP clang_ts_sp =
362
372
ScratchTypeSystemClang::GetForTarget (process->GetTarget ());
363
373
if (!clang_ts_sp)
364
- return false ;
374
+ return error ( " no Clang type system " ) ;
365
375
366
376
CompilerType id_type = clang_ts_sp->GetBasicType (lldb::eBasicTypeObjCID);
367
377
@@ -371,19 +381,19 @@ static bool makeStringGutsSummary(
371
381
auto nsstring = ValueObject::CreateValueObjectFromData (
372
382
" nsstring" , DE, valobj.GetExecutionContextRef (), id_type);
373
383
if (!nsstring || nsstring->GetError ().Fail ())
374
- return false ;
384
+ return error ( " could not create NSString value object " ) ;
375
385
376
386
return NSStringSummaryProvider(*nsstring.get (), stream, summary_options);
377
387
}
378
388
379
389
if ((discriminator & 0b1111'1000 ) == 0b0001'1000 ) { // 0001xxxx: Foreign
380
390
// Not currently generated: Foreign non-bridged strings are not currently
381
391
// used in Swift.
382
- return false ;
392
+ return error ( " unexpected discriminator " ) ;
383
393
}
384
394
385
395
// Invalid discriminator.
386
- return false ;
396
+ return error ( " invalid discriminator " ) ;
387
397
}
388
398
389
399
bool lldb_private::formatters::swift::StringGuts_SummaryProvider (
0 commit comments