Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- LibCxx.cpp --------------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "LibCxx.h"
10
11
#include "lldb/Core/Debugger.h"
12
#include "lldb/Core/FormatEntity.h"
13
#include "lldb/Core/ValueObject.h"
14
#include "lldb/Core/ValueObjectConstResult.h"
15
#include "lldb/DataFormatters/FormattersHelpers.h"
16
#include "lldb/DataFormatters/StringPrinter.h"
17
#include "lldb/DataFormatters/TypeSummary.h"
18
#include "lldb/DataFormatters/VectorIterator.h"
19
#include "lldb/Target/ProcessStructReader.h"
20
#include "lldb/Target/SectionLoadList.h"
21
#include "lldb/Target/Target.h"
22
#include "lldb/Utility/ConstString.h"
23
#include "lldb/Utility/DataBufferHeap.h"
24
#include "lldb/Utility/Endian.h"
25
#include "lldb/Utility/Status.h"
26
#include "lldb/Utility/Stream.h"
27
28
#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
29
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
30
#include <tuple>
31
32
using namespace lldb;
33
using namespace lldb_private;
34
using namespace lldb_private::formatters;
35
36
bool lldb_private::formatters::LibcxxOptionalSummaryProvider(
37
0
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
38
0
  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
39
0
  if (!valobj_sp)
40
0
    return false;
41
42
  // An optional either contains a value or not, the member __engaged_ is
43
  // a bool flag, it is true if the optional has a value and false otherwise.
44
0
  ValueObjectSP engaged_sp(
45
0
      valobj_sp->GetChildMemberWithName(ConstString("__engaged_"), true));
46
47
0
  if (!engaged_sp)
48
0
    return false;
49
50
0
  llvm::StringRef engaged_as_cstring(
51
0
      engaged_sp->GetValueAsUnsigned(0) == 1 ? "true" : "false");
52
53
0
  stream.Printf(" Has Value=%s ", engaged_as_cstring.data());
54
55
0
  return true;
56
0
}
57
58
bool lldb_private::formatters::LibcxxFunctionSummaryProvider(
59
73
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
60
61
73
  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
62
63
73
  if (!valobj_sp)
64
0
    return false;
65
66
73
  ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef());
67
73
  Process *process = exe_ctx.GetProcessPtr();
68
69
73
  if (process == nullptr)
70
0
    return false;
71
72
73
  CPPLanguageRuntime *cpp_runtime = CPPLanguageRuntime::Get(*process);
73
74
73
  if (!cpp_runtime)
75
0
    return false;
76
77
73
  CPPLanguageRuntime::LibCppStdFunctionCallableInfo callable_info =
78
73
      cpp_runtime->FindLibCppStdFunctionCallableInfo(valobj_sp);
79
80
73
  switch (callable_info.callable_case) {
81
0
  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Invalid:
82
0
    stream.Printf(" __f_ = %" PRIu64, callable_info.member__f_pointer_value);
83
0
    return false;
84
0
    break;
85
67
  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Lambda:
86
67
    stream.Printf(
87
67
        " Lambda in File %s at Line %u",
88
67
        callable_info.callable_line_entry.file.GetFilename().GetCString(),
89
67
        callable_info.callable_line_entry.line);
90
67
    break;
91
0
  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::CallableObject:
92
0
    stream.Printf(
93
0
        " Function in File %s at Line %u",
94
0
        callable_info.callable_line_entry.file.GetFilename().GetCString(),
95
0
        callable_info.callable_line_entry.line);
96
0
    break;
97
6
  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::FreeOrMemberFunction:
98
6
    stream.Printf(" Function = %s ",
99
6
                  callable_info.callable_symbol.GetName().GetCString());
100
6
    break;
101
73
  }
102
103
73
  return true;
104
73
}
105
106
bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
107
114
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
108
114
  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
109
114
  if (!valobj_sp)
110
0
    return false;
111
114
  ValueObjectSP ptr_sp(
112
114
      valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
113
114
  ValueObjectSP count_sp(valobj_sp->GetChildAtNamePath(
114
114
      {ConstString("__cntrl_"), ConstString("__shared_owners_")}));
115
114
  ValueObjectSP weakcount_sp(valobj_sp->GetChildAtNamePath(
116
114
      {ConstString("__cntrl_"), ConstString("__shared_weak_owners_")}));
117
118
114
  if (!ptr_sp)
119
0
    return false;
120
121
114
  if (ptr_sp->GetValueAsUnsigned(0) == 0) {
122
12
    stream.Printf("nullptr");
123
12
    return true;
124
102
  } else {
125
102
    bool print_pointee = false;
126
102
    Status error;
127
102
    ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
128
102
    if (pointee_sp && 
error.Success()101
) {
129
101
      if (pointee_sp->DumpPrintableRepresentation(
130
101
              stream, ValueObject::eValueObjectRepresentationStyleSummary,
131
101
              lldb::eFormatInvalid,
132
101
              ValueObject::PrintableRepresentationSpecialCases::eDisable,
133
101
              false))
134
101
        print_pointee = true;
135
101
    }
136
102
    if (!print_pointee)
137
1
      stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
138
102
  }
139
140
102
  if (count_sp)
141
83
    stream.Printf(" strong=%" PRIu64, 1 + count_sp->GetValueAsUnsigned(0));
142
143
102
  if (weakcount_sp)
144
102
    stream.Printf(" weak=%" PRIu64, 1 + weakcount_sp->GetValueAsUnsigned(0));
145
146
102
  return true;
147
114
}
148
149
bool lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
150
90
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
151
90
  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
152
90
  if (!valobj_sp)
153
0
    return false;
154
155
90
  ValueObjectSP ptr_sp(
156
90
      valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
157
90
  if (!ptr_sp)
158
0
    return false;
159
160
90
  ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
161
90
  if (!ptr_sp)
162
0
    return false;
163
164
90
  if (ptr_sp->GetValueAsUnsigned(0) == 0) {
165
12
    stream.Printf("nullptr");
166
12
    return true;
167
78
  } else {
168
78
    bool print_pointee = false;
169
78
    Status error;
170
78
    ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
171
78
    if (pointee_sp && error.Success()) {
172
78
      if (pointee_sp->DumpPrintableRepresentation(
173
78
              stream, ValueObject::eValueObjectRepresentationStyleSummary,
174
78
              lldb::eFormatInvalid,
175
78
              ValueObject::PrintableRepresentationSpecialCases::eDisable,
176
78
              false))
177
78
        print_pointee = true;
178
78
    }
179
78
    if (!print_pointee)
180
0
      stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
181
78
  }
182
183
78
  return true;
184
90
}
185
186
/*
187
 (lldb) fr var ibeg --raw --ptr-depth 1
188
 (std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int,
189
 std::__1::basic_string<char, std::__1::char_traits<char>,
190
 std::__1::allocator<char> > >, std::__1::__tree_node<std::__1::pair<int,
191
 std::__1::basic_string<char, std::__1::char_traits<char>,
192
 std::__1::allocator<char> > >, void *> *, long> >) ibeg = {
193
 __i_ = {
194
 __ptr_ = 0x0000000100103870 {
195
 std::__1::__tree_node_base<void *> = {
196
 std::__1::__tree_end_node<std::__1::__tree_node_base<void *> *> = {
197
 __left_ = 0x0000000000000000
198
 }
199
 __right_ = 0x0000000000000000
200
 __parent_ = 0x00000001001038b0
201
 __is_black_ = true
202
 }
203
 __value_ = {
204
 first = 0
205
 second = { std::string }
206
 */
207
208
lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
209
    LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
210
12
    : SyntheticChildrenFrontEnd(*valobj_sp), m_pair_ptr(), m_pair_sp() {
211
12
  if (valobj_sp)
212
12
    Update();
213
12
}
214
215
24
bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
216
24
  m_pair_sp.reset();
217
24
  m_pair_ptr = nullptr;
218
219
24
  ValueObjectSP valobj_sp = m_backend.GetSP();
220
24
  if (!valobj_sp)
221
0
    return false;
222
223
24
  TargetSP target_sp(valobj_sp->GetTargetSP());
224
225
24
  if (!target_sp)
226
0
    return false;
227
228
24
  if (!valobj_sp)
229
0
    return false;
230
231
24
  static ConstString g___i_("__i_");
232
233
  // this must be a ValueObject* because it is a child of the ValueObject we
234
  // are producing children for it if were a ValueObjectSP, we would end up
235
  // with a loop (iterator -> synthetic -> child -> parent == iterator) and
236
  // that would in turn leak memory by never allowing the ValueObjects to die
237
  // and free their memory
238
24
  m_pair_ptr = valobj_sp
239
24
                   ->GetValueForExpressionPath(
240
24
                       ".__i_.__ptr_->__value_", nullptr, nullptr,
241
24
                       ValueObject::GetValueForExpressionPathOptions()
242
24
                           .DontCheckDotVsArrowSyntax()
243
24
                           .SetSyntheticChildrenTraversal(
244
24
                               ValueObject::GetValueForExpressionPathOptions::
245
24
                                   SyntheticChildrenTraversal::None),
246
24
                       nullptr)
247
24
                   .get();
248
249
24
  if (!m_pair_ptr) {
250
24
    m_pair_ptr = valobj_sp
251
24
                     ->GetValueForExpressionPath(
252
24
                         ".__i_.__ptr_", nullptr, nullptr,
253
24
                         ValueObject::GetValueForExpressionPathOptions()
254
24
                             .DontCheckDotVsArrowSyntax()
255
24
                             .SetSyntheticChildrenTraversal(
256
24
                                 ValueObject::GetValueForExpressionPathOptions::
257
24
                                     SyntheticChildrenTraversal::None),
258
24
                         nullptr)
259
24
                     .get();
260
24
    if (m_pair_ptr) {
261
24
      auto __i_(valobj_sp->GetChildMemberWithName(g___i_, true));
262
24
      if (!__i_) {
263
0
        m_pair_ptr = nullptr;
264
0
        return false;
265
0
      }
266
24
      CompilerType pair_type(
267
24
          __i_->GetCompilerType().GetTypeTemplateArgument(0));
268
24
      std::string name;
269
24
      uint64_t bit_offset_ptr;
270
24
      uint32_t bitfield_bit_size_ptr;
271
24
      bool is_bitfield_ptr;
272
24
      pair_type = pair_type.GetFieldAtIndex(
273
24
          0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr);
274
24
      if (!pair_type) {
275
0
        m_pair_ptr = nullptr;
276
0
        return false;
277
0
      }
278
279
24
      auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS));
280
24
      m_pair_ptr = nullptr;
281
24
      if (addr && addr != LLDB_INVALID_ADDRESS) {
282
24
        TypeSystemClang *ast_ctx =
283
24
            llvm::dyn_cast_or_null<TypeSystemClang>(pair_type.GetTypeSystem());
284
24
        if (!ast_ctx)
285
0
          return false;
286
24
        CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(
287
24
            ConstString(),
288
24
            {{"ptr0",
289
24
              ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
290
24
             {"ptr1",
291
24
              ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
292
24
             {"ptr2",
293
24
              ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
294
24
             {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)},
295
24
             {"payload", pair_type}});
296
24
        llvm::Optional<uint64_t> size = tree_node_type.GetByteSize(nullptr);
297
24
        if (!size)
298
0
          return false;
299
24
        DataBufferSP buffer_sp(new DataBufferHeap(*size, 0));
300
24
        ProcessSP process_sp(target_sp->GetProcessSP());
301
24
        Status error;
302
24
        process_sp->ReadMemory(addr, buffer_sp->GetBytes(),
303
24
                               buffer_sp->GetByteSize(), error);
304
24
        if (error.Fail())
305
0
          return false;
306
24
        DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(),
307
24
                                process_sp->GetAddressByteSize());
308
24
        auto pair_sp = CreateValueObjectFromData(
309
24
            "pair", extractor, valobj_sp->GetExecutionContextRef(),
310
24
            tree_node_type);
311
24
        if (pair_sp)
312
24
          m_pair_sp = pair_sp->GetChildAtIndex(4, true);
313
24
      }
314
24
    }
315
24
  }
316
317
24
  return false;
318
24
}
319
320
size_t lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
321
12
    CalculateNumChildren() {
322
12
  return 2;
323
12
}
324
325
lldb::ValueObjectSP
326
lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetChildAtIndex(
327
24
    size_t idx) {
328
24
  if (m_pair_ptr)
329
0
    return m_pair_ptr->GetChildAtIndex(idx, true);
330
24
  if (m_pair_sp)
331
24
    return m_pair_sp->GetChildAtIndex(idx, true);
332
0
  return lldb::ValueObjectSP();
333
24
}
334
335
bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
336
0
    MightHaveChildren() {
337
0
  return true;
338
0
}
339
340
size_t lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
341
0
    GetIndexOfChildWithName(ConstString name) {
342
0
  if (name == "first")
343
0
    return 0;
344
0
  if (name == "second")
345
0
    return 1;
346
0
  return UINT32_MAX;
347
0
}
348
349
lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
350
12
    ~LibCxxMapIteratorSyntheticFrontEnd() {
351
  // this will be deleted when its parent dies (since it's a child object)
352
  // delete m_pair_ptr;
353
12
}
354
355
SyntheticChildrenFrontEnd *
356
lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator(
357
12
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
358
12
  return (valobj_sp ? new LibCxxMapIteratorSyntheticFrontEnd(valobj_sp)
359
12
                    : 
nullptr0
);
360
12
}
361
362
/*
363
 (lldb) fr var ibeg --raw --ptr-depth 1 -T
364
 (std::__1::__wrap_iter<int *>) ibeg = {
365
 (std::__1::__wrap_iter<int *>::iterator_type) __i = 0x00000001001037a0 {
366
 (int) *__i = 1
367
 }
368
 }
369
*/
370
371
SyntheticChildrenFrontEnd *
372
lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator(
373
39
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
374
39
  static ConstString g_item_name;
375
39
  if (!g_item_name)
376
4
    g_item_name.SetCString("__i");
377
39
  return (valobj_sp
378
39
              ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name)
379
39
              : 
nullptr0
);
380
39
}
381
382
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
383
    LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
384
36
    : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr) {
385
36
  if (valobj_sp)
386
36
    Update();
387
36
}
388
389
size_t lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
390
31
    CalculateNumChildren() {
391
31
  return (m_cntrl ? 1 : 
00
);
392
31
}
393
394
lldb::ValueObjectSP
395
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex(
396
38
    size_t idx) {
397
38
  if (!m_cntrl)
398
0
    return lldb::ValueObjectSP();
399
400
38
  ValueObjectSP valobj_sp = m_backend.GetSP();
401
38
  if (!valobj_sp)
402
0
    return lldb::ValueObjectSP();
403
404
38
  if (idx == 0)
405
31
    return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true);
406
407
7
  if (idx == 1) {
408
7
    if (auto ptr_sp =
409
7
            valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)) {
410
7
      Status status;
411
7
      auto value_sp = ptr_sp->Dereference(status);
412
7
      if (status.Success()) {
413
7
        auto value_type_sp =
414
7
            valobj_sp->GetCompilerType().GetTypeTemplateArgument(0);
415
7
        return value_sp->Cast(value_type_sp);
416
7
      }
417
7
    }
418
7
  }
419
420
0
  return lldb::ValueObjectSP();
421
7
}
422
423
72
bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
424
72
  m_cntrl = nullptr;
425
426
72
  ValueObjectSP valobj_sp = m_backend.GetSP();
427
72
  if (!valobj_sp)
428
0
    return false;
429
430
72
  TargetSP target_sp(valobj_sp->GetTargetSP());
431
72
  if (!target_sp)
432
0
    return false;
433
434
72
  lldb::ValueObjectSP cntrl_sp(
435
72
      valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"), true));
436
437
72
  m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular
438
                            // dependency
439
72
  return false;
440
72
}
441
442
bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
443
1
    MightHaveChildren() {
444
1
  return true;
445
1
}
446
447
size_t lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
448
7
    GetIndexOfChildWithName(ConstString name) {
449
7
  if (name == "__ptr_")
450
0
    return 0;
451
7
  if (name == "$$dereference$$")
452
7
    return 1;
453
0
  return UINT32_MAX;
454
7
}
455
456
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
457
36
    ~LibcxxSharedPtrSyntheticFrontEnd() = default;
458
459
SyntheticChildrenFrontEnd *
460
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator(
461
36
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
462
36
  return (valobj_sp ? new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp)
463
36
                    : 
nullptr0
);
464
36
}
465
466
lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
467
    LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
468
24
    : SyntheticChildrenFrontEnd(*valobj_sp) {
469
24
  if (valobj_sp)
470
24
    Update();
471
24
}
472
473
lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
474
0
    ~LibcxxUniquePtrSyntheticFrontEnd() = default;
475
476
SyntheticChildrenFrontEnd *
477
lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator(
478
24
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
479
24
  return (valobj_sp ? new LibcxxUniquePtrSyntheticFrontEnd(valobj_sp)
480
24
                    : 
nullptr0
);
481
24
}
482
483
size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
484
24
    CalculateNumChildren() {
485
24
  return (m_value_ptr_sp ? 1 : 
00
);
486
24
}
487
488
lldb::ValueObjectSP
489
lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::GetChildAtIndex(
490
30
    size_t idx) {
491
30
  if (!m_value_ptr_sp)
492
0
    return lldb::ValueObjectSP();
493
494
30
  if (idx == 0)
495
24
    return m_value_ptr_sp;
496
497
6
  if (idx == 1) {
498
6
    Status status;
499
6
    auto value_sp = m_value_ptr_sp->Dereference(status);
500
6
    if (status.Success()) {
501
6
      return value_sp;
502
6
    }
503
6
  }
504
505
0
  return lldb::ValueObjectSP();
506
6
}
507
508
48
bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() {
509
48
  ValueObjectSP valobj_sp = m_backend.GetSP();
510
48
  if (!valobj_sp)
511
0
    return false;
512
513
48
  ValueObjectSP ptr_sp(
514
48
      valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
515
48
  if (!ptr_sp)
516
0
    return false;
517
518
48
  m_value_ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
519
520
48
  return false;
521
48
}
522
523
bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
524
0
    MightHaveChildren() {
525
0
  return true;
526
0
}
527
528
size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
529
6
    GetIndexOfChildWithName(ConstString name) {
530
6
  if (name == "__value_")
531
0
    return 0;
532
6
  if (name == "$$dereference$$")
533
6
    return 1;
534
0
  return UINT32_MAX;
535
6
}
536
537
bool lldb_private::formatters::LibcxxContainerSummaryProvider(
538
1.16k
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
539
1.16k
  if (valobj.IsPointerType()) {
540
54
    uint64_t value = valobj.GetValueAsUnsigned(0);
541
54
    if (!value)
542
0
      return false;
543
54
    stream.Printf("0x%016" PRIx64 " ", value);
544
54
  }
545
1.16k
  return FormatEntity::FormatStringRef("size=${svar%#}", stream, nullptr,
546
1.16k
                                       nullptr, nullptr, &valobj, false, false);
547
1.16k
}
548
549
// the field layout in a libc++ string (cap, side, data or data, size, cap)
550
enum LibcxxStringLayoutMode {
551
  eLibcxxStringLayoutModeCSD = 0,
552
  eLibcxxStringLayoutModeDSC = 1,
553
  eLibcxxStringLayoutModeInvalid = 0xffff
554
};
555
556
/// Determine the size in bytes of \p valobj (a libc++ std::string object) and
557
/// extract its data payload. Return the size + payload pair.
558
static llvm::Optional<std::pair<uint64_t, ValueObjectSP>>
559
851
ExtractLibcxxStringInfo(ValueObject &valobj) {
560
851
  ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0}));
561
851
  if (!D)
562
0
    return {};
563
564
851
  ValueObjectSP layout_decider(
565
851
      D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0})));
566
567
  // this child should exist
568
851
  if (!layout_decider)
569
0
    return {};
570
571
851
  ConstString g_data_name("__data_");
572
851
  ConstString g_size_name("__size_");
573
851
  bool short_mode = false; // this means the string is in short-mode and the
574
                           // data is stored inline
575
851
  LibcxxStringLayoutMode layout = (layout_decider->GetName() == g_data_name)
576
851
                                      ? 
eLibcxxStringLayoutModeDSC0
577
851
                                      : eLibcxxStringLayoutModeCSD;
578
851
  uint64_t size_mode_value = 0;
579
580
851
  if (layout == eLibcxxStringLayoutModeDSC) {
581
0
    ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 1, 0}));
582
0
    if (!size_mode)
583
0
      return {};
584
585
0
    if (size_mode->GetName() != g_size_name) {
586
      // we are hitting the padding structure, move along
587
0
      size_mode = D->GetChildAtIndexPath({1, 1, 1});
588
0
      if (!size_mode)
589
0
        return {};
590
0
    }
591
592
0
    size_mode_value = (size_mode->GetValueAsUnsigned(0));
593
0
    short_mode = ((size_mode_value & 0x80) == 0);
594
851
  } else {
595
851
    ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 0, 0}));
596
851
    if (!size_mode)
597
0
      return {};
598
599
851
    size_mode_value = (size_mode->GetValueAsUnsigned(0));
600
851
    short_mode = ((size_mode_value & 1) == 0);
601
851
  }
602
603
851
  if (short_mode) {
604
701
    ValueObjectSP s(D->GetChildAtIndex(1, true));
605
701
    if (!s)
606
0
      return {};
607
701
    ValueObjectSP location_sp = s->GetChildAtIndex(
608
701
        (layout == eLibcxxStringLayoutModeDSC) ? 
00
: 1, true);
609
701
    const uint64_t size = (layout == eLibcxxStringLayoutModeDSC)
610
701
                              ? 
size_mode_value0
611
701
                              : ((size_mode_value >> 1) % 256);
612
613
    // When the small-string optimization takes place, the data must fit in the
614
    // inline string buffer (23 bytes on x86_64/Darwin). If it doesn't, it's
615
    // likely that the string isn't initialized and we're reading garbage.
616
701
    ExecutionContext exe_ctx(location_sp->GetExecutionContextRef());
617
701
    const llvm::Optional<uint64_t> max_bytes =
618
701
        location_sp->GetCompilerType().GetByteSize(
619
701
            exe_ctx.GetBestExecutionContextScope());
620
701
    if (!max_bytes || size > *max_bytes || 
!location_sp694
)
621
7
      return {};
622
623
694
    return std::make_pair(size, location_sp);
624
701
  }
625
626
150
  ValueObjectSP l(D->GetChildAtIndex(0, true));
627
150
  if (!l)
628
0
    return {};
629
  // we can use the layout_decider object as the data pointer
630
150
  ValueObjectSP location_sp = (layout == eLibcxxStringLayoutModeDSC)
631
150
                                  ? 
layout_decider0
632
150
                                  : l->GetChildAtIndex(2, true);
633
150
  ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
634
150
  const unsigned capacity_index =
635
150
      (layout == eLibcxxStringLayoutModeDSC) ? 
20
: 0;
636
150
  ValueObjectSP capacity_vo(l->GetChildAtIndex(capacity_index, true));
637
150
  if (!size_vo || !location_sp || !capacity_vo)
638
0
    return {};
639
150
  const uint64_t size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
640
150
  const uint64_t capacity =
641
150
      capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
642
150
  if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET ||
643
150
      capacity < size)
644
7
    return {};
645
143
  return std::make_pair(size, location_sp);
646
150
}
647
648
static bool
649
LibcxxWStringSummaryProvider(ValueObject &valobj, Stream &stream,
650
                             const TypeSummaryOptions &summary_options,
651
92
                             ValueObjectSP location_sp, size_t size) {
652
92
  if (size == 0) {
653
20
    stream.Printf("L\"\"");
654
20
    return true;
655
20
  }
656
72
  if (!location_sp)
657
0
    return false;
658
659
72
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
660
72
  if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
661
72
    const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
662
72
    if (size > max_size) {
663
0
      size = max_size;
664
0
      options.SetIsTruncated(true);
665
0
    }
666
72
  }
667
668
72
  DataExtractor extractor;
669
72
  const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
670
72
  if (bytes_read < size)
671
0
    return false;
672
673
  // std::wstring::size() is measured in 'characters', not bytes
674
72
  TypeSystemClang *ast_context =
675
72
      ScratchTypeSystemClang::GetForTarget(*valobj.GetTargetSP());
676
72
  if (!ast_context)
677
0
    return false;
678
679
72
  auto wchar_t_size =
680
72
      ast_context->GetBasicType(lldb::eBasicTypeWChar).GetByteSize(nullptr);
681
72
  if (!wchar_t_size)
682
0
    return false;
683
684
72
  options.SetData(std::move(extractor));
685
72
  options.SetStream(&stream);
686
72
  options.SetPrefixToken("L");
687
72
  options.SetQuote('"');
688
72
  options.SetSourceSize(size);
689
72
  options.SetBinaryZeroIsTerminator(false);
690
691
72
  switch (*wchar_t_size) {
692
0
  case 1:
693
0
    return StringPrinter::ReadBufferAndDumpToStream<
694
0
        lldb_private::formatters::StringPrinter::StringElementType::UTF8>(
695
0
        options);
696
0
    break;
697
698
0
  case 2:
699
0
    return StringPrinter::ReadBufferAndDumpToStream<
700
0
        lldb_private::formatters::StringPrinter::StringElementType::UTF16>(
701
0
        options);
702
0
    break;
703
704
72
  case 4:
705
72
    return StringPrinter::ReadBufferAndDumpToStream<
706
72
        lldb_private::formatters::StringPrinter::StringElementType::UTF32>(
707
72
        options);
708
72
  }
709
0
  return false;
710
72
}
711
712
bool lldb_private::formatters::LibcxxWStringSummaryProvider(
713
    ValueObject &valobj, Stream &stream,
714
26
    const TypeSummaryOptions &summary_options) {
715
26
  auto string_info = ExtractLibcxxStringInfo(valobj);
716
26
  if (!string_info)
717
0
    return false;
718
26
  uint64_t size;
719
26
  ValueObjectSP location_sp;
720
26
  std::tie(size, location_sp) = *string_info;
721
722
26
  return ::LibcxxWStringSummaryProvider(valobj, stream, summary_options,
723
26
                                        location_sp, size);
724
26
}
725
726
template <StringPrinter::StringElementType element_type>
727
static bool
728
LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
729
                            const TypeSummaryOptions &summary_options,
730
                            std::string prefix_token, ValueObjectSP location_sp,
731
953
                            uint64_t size) {
732
733
953
  if (size == 0) {
734
60
    stream.Printf("\"\"");
735
60
    return true;
736
60
  }
737
738
893
  if (!location_sp)
739
0
    return false;
740
741
893
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
742
743
893
  if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
744
889
    const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
745
889
    if (size > max_size) {
746
15
      size = max_size;
747
15
      options.SetIsTruncated(true);
748
15
    }
749
889
  }
750
751
893
  {
752
893
    DataExtractor extractor;
753
893
    const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
754
893
    if (bytes_read < size)
755
7
      return false;
756
757
886
    options.SetData(std::move(extractor));
758
886
  }
759
0
  options.SetStream(&stream);
760
886
  if (prefix_token.empty())
761
846
    options.SetPrefixToken(nullptr);
762
40
  else
763
40
    options.SetPrefixToken(prefix_token);
764
886
  options.SetQuote('"');
765
886
  options.SetSourceSize(size);
766
886
  options.SetBinaryZeroIsTerminator(false);
767
886
  return StringPrinter::ReadBufferAndDumpToStream<element_type>(options);
768
893
}
LibCxx.cpp:bool LibcxxStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)0>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::shared_ptr<lldb_private::ValueObject>, unsigned long long)
Line
Count
Source
731
873
                            uint64_t size) {
732
733
873
  if (size == 0) {
734
20
    stream.Printf("\"\"");
735
20
    return true;
736
20
  }
737
738
853
  if (!location_sp)
739
0
    return false;
740
741
853
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
742
743
853
  if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
744
849
    const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
745
849
    if (size > max_size) {
746
15
      size = max_size;
747
15
      options.SetIsTruncated(true);
748
15
    }
749
849
  }
750
751
853
  {
752
853
    DataExtractor extractor;
753
853
    const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
754
853
    if (bytes_read < size)
755
7
      return false;
756
757
846
    options.SetData(std::move(extractor));
758
846
  }
759
0
  options.SetStream(&stream);
760
846
  if (prefix_token.empty())
761
846
    options.SetPrefixToken(nullptr);
762
0
  else
763
0
    options.SetPrefixToken(prefix_token);
764
846
  options.SetQuote('"');
765
846
  options.SetSourceSize(size);
766
846
  options.SetBinaryZeroIsTerminator(false);
767
846
  return StringPrinter::ReadBufferAndDumpToStream<element_type>(options);
768
853
}
LibCxx.cpp:bool LibcxxStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)2>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::shared_ptr<lldb_private::ValueObject>, unsigned long long)
Line
Count
Source
731
40
                            uint64_t size) {
732
733
40
  if (size == 0) {
734
20
    stream.Printf("\"\"");
735
20
    return true;
736
20
  }
737
738
20
  if (!location_sp)
739
0
    return false;
740
741
20
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
742
743
20
  if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
744
20
    const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
745
20
    if (size > max_size) {
746
0
      size = max_size;
747
0
      options.SetIsTruncated(true);
748
0
    }
749
20
  }
750
751
20
  {
752
20
    DataExtractor extractor;
753
20
    const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
754
20
    if (bytes_read < size)
755
0
      return false;
756
757
20
    options.SetData(std::move(extractor));
758
20
  }
759
0
  options.SetStream(&stream);
760
20
  if (prefix_token.empty())
761
0
    options.SetPrefixToken(nullptr);
762
20
  else
763
20
    options.SetPrefixToken(prefix_token);
764
20
  options.SetQuote('"');
765
20
  options.SetSourceSize(size);
766
20
  options.SetBinaryZeroIsTerminator(false);
767
20
  return StringPrinter::ReadBufferAndDumpToStream<element_type>(options);
768
20
}
LibCxx.cpp:bool LibcxxStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)3>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::shared_ptr<lldb_private::ValueObject>, unsigned long long)
Line
Count
Source
731
40
                            uint64_t size) {
732
733
40
  if (size == 0) {
734
20
    stream.Printf("\"\"");
735
20
    return true;
736
20
  }
737
738
20
  if (!location_sp)
739
0
    return false;
740
741
20
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
742
743
20
  if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
744
20
    const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
745
20
    if (size > max_size) {
746
0
      size = max_size;
747
0
      options.SetIsTruncated(true);
748
0
    }
749
20
  }
750
751
20
  {
752
20
    DataExtractor extractor;
753
20
    const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
754
20
    if (bytes_read < size)
755
0
      return false;
756
757
20
    options.SetData(std::move(extractor));
758
20
  }
759
0
  options.SetStream(&stream);
760
20
  if (prefix_token.empty())
761
0
    options.SetPrefixToken(nullptr);
762
20
  else
763
20
    options.SetPrefixToken(prefix_token);
764
20
  options.SetQuote('"');
765
20
  options.SetSourceSize(size);
766
20
  options.SetBinaryZeroIsTerminator(false);
767
20
  return StringPrinter::ReadBufferAndDumpToStream<element_type>(options);
768
20
}
769
770
template <StringPrinter::StringElementType element_type>
771
static bool
772
LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
773
                            const TypeSummaryOptions &summary_options,
774
825
                            std::string prefix_token) {
775
825
  auto string_info = ExtractLibcxxStringInfo(valobj);
776
825
  if (!string_info)
777
14
    return false;
778
811
  uint64_t size;
779
811
  ValueObjectSP location_sp;
780
811
  std::tie(size, location_sp) = *string_info;
781
782
811
  return LibcxxStringSummaryProvider<element_type>(
783
811
      valobj, stream, summary_options, prefix_token, location_sp, size);
784
825
}
LibCxx.cpp:bool LibcxxStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)0>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
Line
Count
Source
774
805
                            std::string prefix_token) {
775
805
  auto string_info = ExtractLibcxxStringInfo(valobj);
776
805
  if (!string_info)
777
14
    return false;
778
791
  uint64_t size;
779
791
  ValueObjectSP location_sp;
780
791
  std::tie(size, location_sp) = *string_info;
781
782
791
  return LibcxxStringSummaryProvider<element_type>(
783
791
      valobj, stream, summary_options, prefix_token, location_sp, size);
784
805
}
LibCxx.cpp:bool LibcxxStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)2>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
Line
Count
Source
774
10
                            std::string prefix_token) {
775
10
  auto string_info = ExtractLibcxxStringInfo(valobj);
776
10
  if (!string_info)
777
0
    return false;
778
10
  uint64_t size;
779
10
  ValueObjectSP location_sp;
780
10
  std::tie(size, location_sp) = *string_info;
781
782
10
  return LibcxxStringSummaryProvider<element_type>(
783
10
      valobj, stream, summary_options, prefix_token, location_sp, size);
784
10
}
LibCxx.cpp:bool LibcxxStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)3>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
Line
Count
Source
774
10
                            std::string prefix_token) {
775
10
  auto string_info = ExtractLibcxxStringInfo(valobj);
776
10
  if (!string_info)
777
0
    return false;
778
10
  uint64_t size;
779
10
  ValueObjectSP location_sp;
780
10
  std::tie(size, location_sp) = *string_info;
781
782
10
  return LibcxxStringSummaryProvider<element_type>(
783
10
      valobj, stream, summary_options, prefix_token, location_sp, size);
784
10
}
785
template <StringPrinter::StringElementType element_type>
786
static bool formatStringImpl(ValueObject &valobj, Stream &stream,
787
                             const TypeSummaryOptions &summary_options,
788
825
                             std::string prefix_token) {
789
825
  StreamString scratch_stream;
790
825
  const bool success = LibcxxStringSummaryProvider<element_type>(
791
825
      valobj, scratch_stream, summary_options, prefix_token);
792
825
  if (success)
793
804
    stream << scratch_stream.GetData();
794
21
  else
795
21
    stream << "Summary Unavailable";
796
825
  return true;
797
825
}
LibCxx.cpp:bool formatStringImpl<(lldb_private::formatters::StringPrinter::StringElementType)0>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
Line
Count
Source
788
805
                             std::string prefix_token) {
789
805
  StreamString scratch_stream;
790
805
  const bool success = LibcxxStringSummaryProvider<element_type>(
791
805
      valobj, scratch_stream, summary_options, prefix_token);
792
805
  if (success)
793
784
    stream << scratch_stream.GetData();
794
21
  else
795
21
    stream << "Summary Unavailable";
796
805
  return true;
797
805
}
LibCxx.cpp:bool formatStringImpl<(lldb_private::formatters::StringPrinter::StringElementType)2>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
Line
Count
Source
788
10
                             std::string prefix_token) {
789
10
  StreamString scratch_stream;
790
10
  const bool success = LibcxxStringSummaryProvider<element_type>(
791
10
      valobj, scratch_stream, summary_options, prefix_token);
792
10
  if (success)
793
10
    stream << scratch_stream.GetData();
794
0
  else
795
0
    stream << "Summary Unavailable";
796
10
  return true;
797
10
}
LibCxx.cpp:bool formatStringImpl<(lldb_private::formatters::StringPrinter::StringElementType)3>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
Line
Count
Source
788
10
                             std::string prefix_token) {
789
10
  StreamString scratch_stream;
790
10
  const bool success = LibcxxStringSummaryProvider<element_type>(
791
10
      valobj, scratch_stream, summary_options, prefix_token);
792
10
  if (success)
793
10
    stream << scratch_stream.GetData();
794
0
  else
795
0
    stream << "Summary Unavailable";
796
10
  return true;
797
10
}
798
799
bool lldb_private::formatters::LibcxxStringSummaryProviderASCII(
800
    ValueObject &valobj, Stream &stream,
801
805
    const TypeSummaryOptions &summary_options) {
802
805
  return formatStringImpl<StringPrinter::StringElementType::ASCII>(
803
805
      valobj, stream, summary_options, "");
804
805
}
805
806
bool lldb_private::formatters::LibcxxStringSummaryProviderUTF16(
807
    ValueObject &valobj, Stream &stream,
808
10
    const TypeSummaryOptions &summary_options) {
809
10
  return formatStringImpl<StringPrinter::StringElementType::UTF16>(
810
10
      valobj, stream, summary_options, "u");
811
10
}
812
813
bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32(
814
    ValueObject &valobj, Stream &stream,
815
10
    const TypeSummaryOptions &summary_options) {
816
10
  return formatStringImpl<StringPrinter::StringElementType::UTF32>(
817
10
      valobj, stream, summary_options, "U");
818
10
}
819
820
static std::tuple<bool, ValueObjectSP, size_t>
821
216
LibcxxExtractStringViewData(ValueObject& valobj) {
822
216
  ConstString g_data_name("__data");
823
216
  ConstString g_size_name("__size");
824
216
  auto dataobj = valobj.GetChildMemberWithName(g_data_name, true);
825
216
  auto sizeobj = valobj.GetChildMemberWithName(g_size_name, true);
826
827
216
  if (!dataobj || !sizeobj)
828
0
    return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
829
830
216
  if (!dataobj->GetError().Success() || 
!sizeobj->GetError().Success()208
)
831
8
    return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
832
833
208
  bool success{false};
834
208
  uint64_t size = sizeobj->GetValueAsUnsigned(0, &success);
835
208
  if (!success)
836
0
    return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
837
838
208
  return std::make_tuple(true,dataobj,size);
839
208
}
840
841
template <StringPrinter::StringElementType element_type>
842
static bool formatStringViewImpl(ValueObject &valobj, Stream &stream,
843
                                 const TypeSummaryOptions &summary_options,
844
150
                                 std::string prefix_token) {
845
846
150
  bool success;
847
150
  ValueObjectSP dataobj;
848
150
  size_t size;
849
150
  std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj);
850
851
150
  if (!success) {
852
8
    stream << "Summary Unavailable";
853
8
    return true;
854
8
  }
855
856
142
  return LibcxxStringSummaryProvider<element_type>(
857
142
      valobj, stream, summary_options, prefix_token, dataobj, size);
858
150
}
LibCxx.cpp:bool formatStringViewImpl<(lldb_private::formatters::StringPrinter::StringElementType)0>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
Line
Count
Source
844
90
                                 std::string prefix_token) {
845
846
90
  bool success;
847
90
  ValueObjectSP dataobj;
848
90
  size_t size;
849
90
  std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj);
850
851
90
  if (!success) {
852
8
    stream << "Summary Unavailable";
853
8
    return true;
854
8
  }
855
856
82
  return LibcxxStringSummaryProvider<element_type>(
857
82
      valobj, stream, summary_options, prefix_token, dataobj, size);
858
90
}
LibCxx.cpp:bool formatStringViewImpl<(lldb_private::formatters::StringPrinter::StringElementType)2>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
Line
Count
Source
844
30
                                 std::string prefix_token) {
845
846
30
  bool success;
847
30
  ValueObjectSP dataobj;
848
30
  size_t size;
849
30
  std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj);
850
851
30
  if (!success) {
852
0
    stream << "Summary Unavailable";
853
0
    return true;
854
0
  }
855
856
30
  return LibcxxStringSummaryProvider<element_type>(
857
30
      valobj, stream, summary_options, prefix_token, dataobj, size);
858
30
}
LibCxx.cpp:bool formatStringViewImpl<(lldb_private::formatters::StringPrinter::StringElementType)3>(lldb_private::ValueObject&, lldb_private::Stream&, lldb_private::TypeSummaryOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
Line
Count
Source
844
30
                                 std::string prefix_token) {
845
846
30
  bool success;
847
30
  ValueObjectSP dataobj;
848
30
  size_t size;
849
30
  std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj);
850
851
30
  if (!success) {
852
0
    stream << "Summary Unavailable";
853
0
    return true;
854
0
  }
855
856
30
  return LibcxxStringSummaryProvider<element_type>(
857
30
      valobj, stream, summary_options, prefix_token, dataobj, size);
858
30
}
859
860
bool lldb_private::formatters::LibcxxStringViewSummaryProviderASCII(
861
    ValueObject &valobj, Stream &stream,
862
90
    const TypeSummaryOptions &summary_options) {
863
90
  return formatStringViewImpl<StringPrinter::StringElementType::ASCII>(
864
90
      valobj, stream, summary_options, "");
865
90
}
866
867
bool lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16(
868
    ValueObject &valobj, Stream &stream,
869
30
    const TypeSummaryOptions &summary_options) {
870
30
  return formatStringViewImpl<StringPrinter::StringElementType::UTF16>(
871
30
      valobj, stream, summary_options, "u");
872
30
}
873
874
bool lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32(
875
    ValueObject &valobj, Stream &stream,
876
30
    const TypeSummaryOptions &summary_options) {
877
30
  return formatStringViewImpl<StringPrinter::StringElementType::UTF32>(
878
30
      valobj, stream, summary_options, "U");
879
30
}
880
881
bool lldb_private::formatters::LibcxxWStringViewSummaryProvider(
882
    ValueObject &valobj, Stream &stream,
883
66
    const TypeSummaryOptions &summary_options) {
884
885
66
  bool success;
886
66
  ValueObjectSP dataobj;
887
66
  size_t size;
888
66
  std::tie( success, dataobj, size ) = LibcxxExtractStringViewData(valobj);
889
890
66
  if (!success) {
891
0
    stream << "Summary Unavailable";
892
0
    return true;
893
0
  }
894
895
896
66
  return ::LibcxxWStringSummaryProvider(valobj, stream, summary_options,
897
66
                                        dataobj, size);
898
66
}