LLDB mainline
CxxStringTypes.cpp
Go to the documentation of this file.
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
17#include "lldb/Host/Time.h"
19#include "lldb/Target/Target.h"
20#include "lldb/Target/Thread.h"
22#include "lldb/Utility/Endian.h"
23#include "lldb/Utility/Status.h"
24#include "lldb/Utility/Stream.h"
27
28#include <algorithm>
29#include <optional>
30
31using namespace lldb;
32using namespace lldb_private;
33using namespace lldb_private::formatters;
34
36
37static constexpr std::pair<const char *, Format>
39 switch (ElemType) {
40 case StringElementType::UTF8:
41 return std::make_pair("u8", lldb::eFormatUnicode8);
42 case StringElementType::UTF16:
43 return std::make_pair("u", lldb::eFormatUnicode16);
44 case StringElementType::UTF32:
45 return std::make_pair("U", lldb::eFormatUnicode32);
46 default:
47 return std::make_pair(nullptr, lldb::eFormatInvalid);
48 }
49}
50
51template <StringElementType ElemType>
52static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
53 Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
54 if (!valobj_addr.IsValid())
55 return false;
56
58 options.SetLocation(valobj_addr);
59 options.SetTargetSP(valobj.GetTargetSP());
60 options.SetStream(&stream);
61 options.SetPrefixToken(getElementTraits(ElemType).first);
62
63 CompilerType ty = valobj.GetCompilerType();
64 uint64_t size = 0;
65 if (ty.IsArrayType(nullptr, &size) && size > 0) {
66 options.SetSourceSize(size);
67 options.SetHasSourceSize(true);
68 options.SetZeroTermination(
70 }
71
73 stream.Printf("Summary Unavailable");
74
75 return true;
76}
77
78template <StringElementType ElemType>
79static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) {
80 DataExtractor data;
82 valobj.GetData(data, error);
83
84 if (error.Fail())
85 return false;
86
87 std::string value;
89
90 constexpr auto ElemTraits = getElementTraits(ElemType);
91 valobj.GetValueAsCString(ElemTraits.second, value);
92
93 if (!value.empty())
94 stream.Printf("%s ", value.c_str());
95
96 options.SetData(std::move(data));
97 options.SetStream(&stream);
98 options.SetPrefixToken(ElemTraits.first);
99 options.SetQuote('\'');
100 options.SetSourceSize(1);
102
104}
105
110
115
120
122 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
123 Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
124 if (!valobj_addr.IsValid())
125 return false;
126
127 // Get a wchar_t basic type from the current type system
128 std::optional<uint64_t> size = GetWCharByteSize(valobj);
129 if (!size)
130 return false;
131 const uint32_t wchar_size = *size;
132
134 options.SetLocation(valobj_addr);
135 options.SetTargetSP(valobj.GetTargetSP());
136 options.SetStream(&stream);
137 options.SetPrefixToken("L");
138
139 CompilerType ty = valobj.GetCompilerType();
140 uint64_t arr_size = 0;
141 if (ty.IsArrayType(nullptr, &arr_size) && arr_size > 0) {
142 options.SetSourceSize(arr_size);
143 options.SetHasSourceSize(true);
144 options.SetZeroTermination(
146 }
147
148 switch (wchar_size) {
149 case 1:
151 options);
152 case 2:
154 options);
155 case 4:
157 options);
158 default:
159 stream.Printf("size for wchar_t is not valid");
160 return true;
161 }
162 return true;
163}
164
169
174
179
181 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
182 DataExtractor data;
184 valobj.GetData(data, error);
185
186 if (error.Fail())
187 return false;
188
189 // Get a wchar_t basic type from the current type system
190 std::optional<uint64_t> size = GetWCharByteSize(valobj);
191 if (!size)
192 return false;
193 const uint32_t wchar_size = *size;
194
196 options.SetData(std::move(data));
197 options.SetStream(&stream);
198 options.SetPrefixToken("L");
199 options.SetQuote('\'');
200 options.SetSourceSize(1);
202
203 switch (wchar_size) {
204 case 1:
206 options);
207 case 2:
209 options);
210 case 4:
212 options);
213 default:
214 stream.Printf("size for wchar_t is not valid");
215 return true;
216 }
217 return true;
218}
219
220std::optional<uint64_t>
222 return llvm::expectedToOptional(
223 valobj.GetCompilerType()
225 .GetByteSize(nullptr));
226}
227
228template <StringPrinter::StringElementType element_type>
230 Stream &stream, const TypeSummaryOptions &summary_options,
231 lldb::ValueObjectSP location_sp, uint64_t size, std::string prefix_token) {
232
233 if (size == 0) {
234 stream.PutCString(prefix_token);
235 stream.PutCString("\"\"");
236 return true;
237 }
238
239 if (!location_sp)
240 return false;
241
243
244 if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
245 const auto max_size =
246 location_sp->GetTargetSP()->GetMaximumSizeOfStringSummary();
247 if (size > max_size) {
248 size = max_size;
249 options.SetIsTruncated(true);
250 }
251 }
252
253 {
254 DataExtractor extractor;
255 const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
256 if (bytes_read < size)
257 return false;
258
259 options.SetData(std::move(extractor));
260 }
261 options.SetStream(&stream);
262 if (prefix_token.empty())
263 options.SetPrefixToken(nullptr);
264 else
265 options.SetPrefixToken(prefix_token);
266 options.SetQuote('"');
267 options.SetSourceSize(size);
268 options.SetZeroTermination(StringPrinter::ZeroTermination::Ignore);
270}
271
272// explicit instantiations for all string element types
273template bool
275 Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t,
276 std::string);
277template bool
279 Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t,
280 std::string);
281template bool
283 Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t,
284 std::string);
285template bool
287 Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t,
288 std::string);
static llvm::raw_ostream & error(Stream &strm)
static constexpr std::pair< const char *, Format > getElementTraits(StringElementType ElemType)
static bool CharSummaryProvider(ValueObject &valobj, Stream &stream)
static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream)
StringPrinter::StringElementType StringElementType
A section + offset based address class.
Definition Address.h:62
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
Generic representation of a type in a programming language.
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const
Create related types using the current type's AST.
bool IsArrayType(CompilerType *element_type=nullptr, uint64_t *size=nullptr, bool *is_incomplete=nullptr) const
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
An data extractor class.
An error handling class.
Definition Status.h:118
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
lldb::TypeSummaryCapping GetCapping() const
virtual uint64_t GetData(DataExtractor &data, Status &error)
lldb::TargetSP GetTargetSP() const
CompilerType GetCompilerType()
virtual const char * GetValueAsCString()
static bool ReadBufferAndDumpToStream(const ReadBufferAndDumpToStreamOptions &options)
@ TrimTrailingZeros
Print embedded zeros, but ignore zeros at the end of the buffer.
@ Ignore
Don't look for a terminator - print the whole buffer.
static bool ReadStringAndDumpToStream(const ReadStringAndDumpToStreamOptions &options)
bool Char32StringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
bool WCharSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
std::optional< uint64_t > GetWCharByteSize(ValueObject &valobj)
bool StringBufferSummaryProvider(Stream &stream, const TypeSummaryOptions &summary_options, lldb::ValueObjectSP location_sp, uint64_t size, std::string prefix_token)
Print a summary for a string buffer to stream.
bool Char8SummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
bool Char16SummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
bool Char8StringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
bool Char16StringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Address GetArrayAddressOrPointerValue(ValueObject &valobj)
bool WCharStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
bool Char32SummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP