Coverage Report

Created: 2023-09-12 09:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- CxxStringTypes.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 "CxxStringTypes.h"
10
11
#include "llvm/Support/ConvertUTF.h"
12
13
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
14
#include "lldb/Core/ValueObject.h"
15
#include "lldb/Core/ValueObjectConstResult.h"
16
#include "lldb/DataFormatters/FormattersHelpers.h"
17
#include "lldb/DataFormatters/StringPrinter.h"
18
#include "lldb/DataFormatters/TypeSummary.h"
19
#include "lldb/Host/Time.h"
20
#include "lldb/Target/SectionLoadList.h"
21
#include "lldb/Target/Target.h"
22
#include "lldb/Target/Thread.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 <algorithm>
29
#include <optional>
30
31
using namespace lldb;
32
using namespace lldb_private;
33
using namespace lldb_private::formatters;
34
35
using StringElementType = StringPrinter::StringElementType;
36
37
static constexpr std::pair<const char *, Format>
38
50
getElementTraits(StringElementType ElemType) {
39
50
  switch (ElemType) {
40
12
  case StringElementType::UTF8:
41
12
    return std::make_pair("u8", lldb::eFormatUnicode8);
42
18
  case StringElementType::UTF16:
43
18
    return std::make_pair("u", lldb::eFormatUnicode16);
44
20
  case StringElementType::UTF32:
45
20
    return std::make_pair("U", lldb::eFormatUnicode32);
46
0
  default:
47
0
    return std::make_pair(nullptr, lldb::eFormatInvalid);
48
50
  }
49
50
}
50
51
template <StringElementType ElemType>
52
50
static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
53
50
  Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
54
50
  if (!valobj_addr.IsValid())
55
0
    return false;
56
57
50
  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
58
50
  options.SetLocation(valobj_addr);
59
50
  options.SetTargetSP(valobj.GetTargetSP());
60
50
  options.SetStream(&stream);
61
50
  options.SetPrefixToken(getElementTraits(ElemType).first);
62
63
50
  if (!StringPrinter::ReadStringAndDumpToStream<ElemType>(options))
64
2
    stream.Printf("Summary Unavailable");
65
66
50
  return true;
67
50
}
CxxStringTypes.cpp:bool CharStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)1>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
52
12
static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
53
12
  Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
54
12
  if (!valobj_addr.IsValid())
55
0
    return false;
56
57
12
  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
58
12
  options.SetLocation(valobj_addr);
59
12
  options.SetTargetSP(valobj.GetTargetSP());
60
12
  options.SetStream(&stream);
61
12
  options.SetPrefixToken(getElementTraits(ElemType).first);
62
63
12
  if (!StringPrinter::ReadStringAndDumpToStream<ElemType>(options))
64
0
    stream.Printf("Summary Unavailable");
65
66
12
  return true;
67
12
}
CxxStringTypes.cpp:bool CharStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)2>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
52
18
static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
53
18
  Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
54
18
  if (!valobj_addr.IsValid())
55
0
    return false;
56
57
18
  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
58
18
  options.SetLocation(valobj_addr);
59
18
  options.SetTargetSP(valobj.GetTargetSP());
60
18
  options.SetStream(&stream);
61
18
  options.SetPrefixToken(getElementTraits(ElemType).first);
62
63
18
  if (!StringPrinter::ReadStringAndDumpToStream<ElemType>(options))
64
0
    stream.Printf("Summary Unavailable");
65
66
18
  return true;
67
18
}
CxxStringTypes.cpp:bool CharStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)3>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
52
20
static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
53
20
  Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
54
20
  if (!valobj_addr.IsValid())
55
0
    return false;
56
57
20
  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
58
20
  options.SetLocation(valobj_addr);
59
20
  options.SetTargetSP(valobj.GetTargetSP());
60
20
  options.SetStream(&stream);
61
20
  options.SetPrefixToken(getElementTraits(ElemType).first);
62
63
20
  if (!StringPrinter::ReadStringAndDumpToStream<ElemType>(options))
64
2
    stream.Printf("Summary Unavailable");
65
66
20
  return true;
67
20
}
68
69
template <StringElementType ElemType>
70
270
static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) {
71
270
  DataExtractor data;
72
270
  Status error;
73
270
  valobj.GetData(data, error);
74
75
270
  if (error.Fail())
76
0
    return false;
77
78
270
  std::string value;
79
270
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
80
81
270
  constexpr auto ElemTraits = getElementTraits(ElemType);
82
270
  valobj.GetValueAsCString(ElemTraits.second, value);
83
84
270
  if (!value.empty())
85
270
    stream.Printf("%s ", value.c_str());
86
87
270
  options.SetData(std::move(data));
88
270
  options.SetStream(&stream);
89
270
  options.SetPrefixToken(ElemTraits.first);
90
270
  options.SetQuote('\'');
91
270
  options.SetSourceSize(1);
92
270
  options.SetBinaryZeroIsTerminator(false);
93
94
270
  return StringPrinter::ReadBufferAndDumpToStream<ElemType>(options);
95
270
}
CxxStringTypes.cpp:bool CharSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)1>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
70
6
static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) {
71
6
  DataExtractor data;
72
6
  Status error;
73
6
  valobj.GetData(data, error);
74
75
6
  if (error.Fail())
76
0
    return false;
77
78
6
  std::string value;
79
6
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
80
81
6
  constexpr auto ElemTraits = getElementTraits(ElemType);
82
6
  valobj.GetValueAsCString(ElemTraits.second, value);
83
84
6
  if (!value.empty())
85
6
    stream.Printf("%s ", value.c_str());
86
87
6
  options.SetData(std::move(data));
88
6
  options.SetStream(&stream);
89
6
  options.SetPrefixToken(ElemTraits.first);
90
6
  options.SetQuote('\'');
91
6
  options.SetSourceSize(1);
92
6
  options.SetBinaryZeroIsTerminator(false);
93
94
6
  return StringPrinter::ReadBufferAndDumpToStream<ElemType>(options);
95
6
}
CxxStringTypes.cpp:bool CharSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)2>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
70
250
static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) {
71
250
  DataExtractor data;
72
250
  Status error;
73
250
  valobj.GetData(data, error);
74
75
250
  if (error.Fail())
76
0
    return false;
77
78
250
  std::string value;
79
250
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
80
81
250
  constexpr auto ElemTraits = getElementTraits(ElemType);
82
250
  valobj.GetValueAsCString(ElemTraits.second, value);
83
84
250
  if (!value.empty())
85
250
    stream.Printf("%s ", value.c_str());
86
87
250
  options.SetData(std::move(data));
88
250
  options.SetStream(&stream);
89
250
  options.SetPrefixToken(ElemTraits.first);
90
250
  options.SetQuote('\'');
91
250
  options.SetSourceSize(1);
92
250
  options.SetBinaryZeroIsTerminator(false);
93
94
250
  return StringPrinter::ReadBufferAndDumpToStream<ElemType>(options);
95
250
}
CxxStringTypes.cpp:bool CharSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)3>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
70
14
static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) {
71
14
  DataExtractor data;
72
14
  Status error;
73
14
  valobj.GetData(data, error);
74
75
14
  if (error.Fail())
76
0
    return false;
77
78
14
  std::string value;
79
14
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
80
81
14
  constexpr auto ElemTraits = getElementTraits(ElemType);
82
14
  valobj.GetValueAsCString(ElemTraits.second, value);
83
84
14
  if (!value.empty())
85
14
    stream.Printf("%s ", value.c_str());
86
87
14
  options.SetData(std::move(data));
88
14
  options.SetStream(&stream);
89
14
  options.SetPrefixToken(ElemTraits.first);
90
14
  options.SetQuote('\'');
91
14
  options.SetSourceSize(1);
92
14
  options.SetBinaryZeroIsTerminator(false);
93
94
14
  return StringPrinter::ReadBufferAndDumpToStream<ElemType>(options);
95
14
}
96
97
bool lldb_private::formatters::Char8StringSummaryProvider(
98
12
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
99
12
  return CharStringSummaryProvider<StringElementType::UTF8>(valobj, stream);
100
12
}
101
102
bool lldb_private::formatters::Char16StringSummaryProvider(
103
18
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
104
18
  return CharStringSummaryProvider<StringElementType::UTF16>(valobj, stream);
105
18
}
106
107
bool lldb_private::formatters::Char32StringSummaryProvider(
108
20
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
109
20
  return CharStringSummaryProvider<StringElementType::UTF32>(valobj, stream);
110
20
}
111
112
bool lldb_private::formatters::WCharStringSummaryProvider(
113
16
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
114
16
  Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
115
16
  if (!valobj_addr.IsValid())
116
0
    return false;
117
118
  // Get a wchar_t basic type from the current type system
119
16
  CompilerType wchar_compiler_type =
120
16
      valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
121
122
16
  if (!wchar_compiler_type)
123
0
    return false;
124
125
  // Safe to pass nullptr for exe_scope here.
126
16
  std::optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
127
16
  if (!size)
128
0
    return false;
129
16
  const uint32_t wchar_size = *size;
130
131
16
  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
132
16
  options.SetLocation(valobj_addr);
133
16
  options.SetTargetSP(valobj.GetTargetSP());
134
16
  options.SetStream(&stream);
135
16
  options.SetPrefixToken("L");
136
137
16
  switch (wchar_size) {
138
0
  case 8:
139
0
    return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF8>(
140
0
        options);
141
0
  case 16:
142
0
    return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF16>(
143
0
        options);
144
16
  case 32:
145
16
    return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF32>(
146
16
        options);
147
0
  default:
148
0
    stream.Printf("size for wchar_t is not valid");
149
0
    return true;
150
16
  }
151
0
  return true;
152
16
}
153
154
bool lldb_private::formatters::Char8SummaryProvider(
155
6
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
156
6
  return CharSummaryProvider<StringElementType::UTF8>(valobj, stream);
157
6
}
158
159
bool lldb_private::formatters::Char16SummaryProvider(
160
250
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
161
250
  return CharSummaryProvider<StringElementType::UTF16>(valobj, stream);
162
250
}
163
164
bool lldb_private::formatters::Char32SummaryProvider(
165
14
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
166
14
  return CharSummaryProvider<StringElementType::UTF32>(valobj, stream);
167
14
}
168
169
bool lldb_private::formatters::WCharSummaryProvider(
170
14
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
171
14
  DataExtractor data;
172
14
  Status error;
173
14
  valobj.GetData(data, error);
174
175
14
  if (error.Fail())
176
0
    return false;
177
178
  // Get a wchar_t basic type from the current type system
179
14
  CompilerType wchar_compiler_type =
180
14
      valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
181
182
14
  if (!wchar_compiler_type)
183
0
    return false;
184
185
    // Safe to pass nullptr for exe_scope here.
186
14
  std::optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
187
14
  if (!size)
188
0
    return false;
189
14
  const uint32_t wchar_size = *size;
190
191
14
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
192
14
  options.SetData(std::move(data));
193
14
  options.SetStream(&stream);
194
14
  options.SetPrefixToken("L");
195
14
  options.SetQuote('\'');
196
14
  options.SetSourceSize(1);
197
14
  options.SetBinaryZeroIsTerminator(false);
198
199
14
  switch (wchar_size) {
200
0
  case 8:
201
0
    return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF8>(
202
0
        options);
203
0
  case 16:
204
0
    return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF16>(
205
0
        options);
206
14
  case 32:
207
14
    return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF32>(
208
14
        options);
209
0
  default:
210
0
    stream.Printf("size for wchar_t is not valid");
211
0
    return true;
212
14
  }
213
0
  return true;
214
14
}