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
16#include "lldb/Host/Time.h"
18#include "lldb/Target/Target.h"
19#include "lldb/Target/Thread.h"
21#include "lldb/Utility/Endian.h"
22#include "lldb/Utility/Status.h"
23#include "lldb/Utility/Stream.h"
26
27#include <algorithm>
28#include <optional>
29
30using namespace lldb;
31using namespace lldb_private;
32using namespace lldb_private::formatters;
33
35
36static constexpr std::pair<const char *, Format>
38 switch (ElemType) {
39 case StringElementType::UTF8:
40 return std::make_pair("u8", lldb::eFormatUnicode8);
41 case StringElementType::UTF16:
42 return std::make_pair("u", lldb::eFormatUnicode16);
43 case StringElementType::UTF32:
44 return std::make_pair("U", lldb::eFormatUnicode32);
45 default:
46 return std::make_pair(nullptr, lldb::eFormatInvalid);
47 }
48}
49
50template <StringElementType ElemType>
51static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
52 Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
53 if (!valobj_addr.IsValid())
54 return false;
55
57 options.SetLocation(valobj_addr);
58 options.SetTargetSP(valobj.GetTargetSP());
59 options.SetStream(&stream);
60 options.SetPrefixToken(getElementTraits(ElemType).first);
61
62 CompilerType ty = valobj.GetCompilerType();
63 uint64_t size = 0;
64 if (ty.IsArrayType(nullptr, &size) && size > 0) {
65 options.SetSourceSize(size);
66 options.SetHasSourceSize(true);
67 options.SetZeroTermination(
69 }
70
72 stream.Printf("Summary Unavailable");
73
74 return true;
75}
76
77template <StringElementType ElemType>
78static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) {
79 DataExtractor data;
81 valobj.GetData(data, error);
82
83 if (error.Fail())
84 return false;
85
86 std::string value;
88
89 constexpr auto ElemTraits = getElementTraits(ElemType);
90 valobj.GetValueAsCString(ElemTraits.second, value);
91
92 if (!value.empty())
93 stream.Printf("%s ", value.c_str());
94
95 options.SetData(std::move(data));
96 options.SetStream(&stream);
97 options.SetPrefixToken(ElemTraits.first);
98 options.SetQuote('\'');
99 options.SetSourceSize(1);
101
103}
104
109
114
119
121 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
122 Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
123 if (!valobj_addr.IsValid())
124 return false;
125
126 // Get a wchar_t basic type from the current type system
127 std::optional<uint64_t> size = GetWCharByteSize(valobj);
128 if (!size)
129 return false;
130 const uint32_t wchar_size = *size;
131
133 options.SetLocation(valobj_addr);
134 options.SetTargetSP(valobj.GetTargetSP());
135 options.SetStream(&stream);
136 options.SetPrefixToken("L");
137
138 CompilerType ty = valobj.GetCompilerType();
139 uint64_t arr_size = 0;
140 if (ty.IsArrayType(nullptr, &arr_size) && arr_size > 0) {
141 options.SetSourceSize(arr_size);
142 options.SetHasSourceSize(true);
143 options.SetZeroTermination(
145 }
146
147 switch (wchar_size) {
148 case 1:
150 options);
151 case 2:
153 options);
154 case 4:
156 options);
157 default:
158 stream.Printf("size for wchar_t is not valid");
159 return true;
160 }
161 return true;
162}
163
168
173
178
180 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
181 DataExtractor data;
183 valobj.GetData(data, error);
184
185 if (error.Fail())
186 return false;
187
188 // Get a wchar_t basic type from the current type system
189 std::optional<uint64_t> size = GetWCharByteSize(valobj);
190 if (!size)
191 return false;
192 const uint32_t wchar_size = *size;
193
195 options.SetData(std::move(data));
196 options.SetStream(&stream);
197 options.SetPrefixToken("L");
198 options.SetQuote('\'');
199 options.SetSourceSize(1);
201
202 switch (wchar_size) {
203 case 1:
205 options);
206 case 2:
208 options);
209 case 4:
211 options);
212 default:
213 stream.Printf("size for wchar_t is not valid");
214 return true;
215 }
216 return true;
217}
218
219std::optional<uint64_t>
221 return llvm::expectedToOptional(
222 valobj.GetCompilerType()
224 .GetByteSize(nullptr));
225}
226
227template <StringPrinter::StringElementType element_type>
229 Stream &stream, const TypeSummaryOptions &summary_options,
230 lldb::ValueObjectSP location_sp, uint64_t size, std::string prefix_token) {
231
232 if (size == 0) {
233 stream.PutCString(prefix_token);
234 stream.PutCString("\"\"");
235 return true;
236 }
237
238 if (!location_sp)
239 return false;
240
242
243 if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
244 const auto max_size =
245 location_sp->GetTargetSP()->GetMaximumSizeOfStringSummary();
246 if (size > max_size) {
247 size = max_size;
248 options.SetIsTruncated(true);
249 }
250 }
251
252 {
253 DataExtractor extractor;
254 const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
255 if (bytes_read < size)
256 return false;
257
258 options.SetData(std::move(extractor));
259 }
260 options.SetStream(&stream);
261 if (prefix_token.empty())
262 options.SetPrefixToken(nullptr);
263 else
264 options.SetPrefixToken(prefix_token);
265 options.SetQuote('"');
266 options.SetSourceSize(size);
267 options.SetZeroTermination(StringPrinter::ZeroTermination::Ignore);
269}
270
271// explicit instantiations for all string element types
272template bool
274 Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t,
275 std::string);
276template bool
278 Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t,
279 std::string);
280template bool
282 Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t,
283 std::string);
284template bool
286 Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t,
287 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