1 //===-- CxxStringTypes.cpp --------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "CxxStringTypes.h"
11 #include "llvm/Support/ConvertUTF.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/Host/Time.h"
19 #include "lldb/Symbol/ClangASTContext.h"
20 #include "lldb/Target/ProcessStructReader.h"
21 #include "lldb/Target/SectionLoadList.h"
22 #include "lldb/Target/Target.h"
23 #include "lldb/Target/Thread.h"
24 #include "lldb/Utility/DataBufferHeap.h"
25 #include "lldb/Utility/Endian.h"
26 #include "lldb/Utility/Status.h"
27 #include "lldb/Utility/Stream.h"
32 using namespace lldb_private;
33 using namespace lldb_private::formatters;
35 bool lldb_private::formatters::Char8StringSummaryProvider(
36 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
37 ProcessSP process_sp = valobj.GetProcessSP();
41 lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
42 if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
45 StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
46 options.SetLocation(valobj_addr);
47 options.SetProcessSP(process_sp);
48 options.SetStream(&stream);
49 options.SetPrefixToken("u8");
51 if (!StringPrinter::ReadStringAndDumpToStream<
52 StringPrinter::StringElementType::UTF8>(options)) {
53 stream.Printf("Summary Unavailable");
60 bool lldb_private::formatters::Char16StringSummaryProvider(
61 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
62 ProcessSP process_sp = valobj.GetProcessSP();
66 lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
67 if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
70 StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
71 options.SetLocation(valobj_addr);
72 options.SetProcessSP(process_sp);
73 options.SetStream(&stream);
74 options.SetPrefixToken("u");
76 if (!StringPrinter::ReadStringAndDumpToStream<
77 StringPrinter::StringElementType::UTF16>(options)) {
78 stream.Printf("Summary Unavailable");
85 bool lldb_private::formatters::Char32StringSummaryProvider(
86 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
87 ProcessSP process_sp = valobj.GetProcessSP();
91 lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
92 if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
95 StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
96 options.SetLocation(valobj_addr);
97 options.SetProcessSP(process_sp);
98 options.SetStream(&stream);
99 options.SetPrefixToken("U");
101 if (!StringPrinter::ReadStringAndDumpToStream<
102 StringPrinter::StringElementType::UTF32>(options)) {
103 stream.Printf("Summary Unavailable");
110 bool lldb_private::formatters::WCharStringSummaryProvider(
111 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
112 ProcessSP process_sp = valobj.GetProcessSP();
116 lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
117 if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
120 // Get a wchar_t basic type from the current type system
121 CompilerType wchar_compiler_type =
122 valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
124 if (!wchar_compiler_type)
127 // Safe to pass nullptr for exe_scope here.
128 llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
131 const uint32_t wchar_size = *size;
133 StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
134 options.SetLocation(valobj_addr);
135 options.SetProcessSP(process_sp);
136 options.SetStream(&stream);
137 options.SetPrefixToken("L");
139 switch (wchar_size) {
141 return StringPrinter::ReadStringAndDumpToStream<
142 StringPrinter::StringElementType::UTF8>(options);
144 return StringPrinter::ReadStringAndDumpToStream<
145 StringPrinter::StringElementType::UTF16>(options);
147 return StringPrinter::ReadStringAndDumpToStream<
148 StringPrinter::StringElementType::UTF32>(options);
150 stream.Printf("size for wchar_t is not valid");
156 bool lldb_private::formatters::Char8SummaryProvider(
157 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
160 valobj.GetData(data, error);
166 valobj.GetValueAsCString(lldb::eFormatUnicode8, value);
168 stream.Printf("%s ", value.c_str());
170 StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
171 options.SetData(data);
172 options.SetStream(&stream);
173 options.SetPrefixToken("u8");
174 options.SetQuote('\'');
175 options.SetSourceSize(1);
176 options.SetBinaryZeroIsTerminator(false);
178 return StringPrinter::ReadBufferAndDumpToStream<
179 StringPrinter::StringElementType::UTF8>(options);
182 bool lldb_private::formatters::Char16SummaryProvider(
183 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
186 valobj.GetData(data, error);
192 valobj.GetValueAsCString(lldb::eFormatUnicode16, value);
194 stream.Printf("%s ", value.c_str());
196 StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
197 options.SetData(data);
198 options.SetStream(&stream);
199 options.SetPrefixToken("u");
200 options.SetQuote('\'');
201 options.SetSourceSize(1);
202 options.SetBinaryZeroIsTerminator(false);
204 return StringPrinter::ReadBufferAndDumpToStream<
205 StringPrinter::StringElementType::UTF16>(options);
208 bool lldb_private::formatters::Char32SummaryProvider(
209 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
212 valobj.GetData(data, error);
218 valobj.GetValueAsCString(lldb::eFormatUnicode32, value);
220 stream.Printf("%s ", value.c_str());
222 StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
223 options.SetData(data);
224 options.SetStream(&stream);
225 options.SetPrefixToken("U");
226 options.SetQuote('\'');
227 options.SetSourceSize(1);
228 options.SetBinaryZeroIsTerminator(false);
230 return StringPrinter::ReadBufferAndDumpToStream<
231 StringPrinter::StringElementType::UTF32>(options);
234 bool lldb_private::formatters::WCharSummaryProvider(
235 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
238 valobj.GetData(data, error);
243 // Get a wchar_t basic type from the current type system
244 CompilerType wchar_compiler_type =
245 valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
247 if (!wchar_compiler_type)
250 // Safe to pass nullptr for exe_scope here.
251 llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
254 const uint32_t wchar_size = *size;
256 StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
257 options.SetData(data);
258 options.SetStream(&stream);
259 options.SetPrefixToken("L");
260 options.SetQuote('\'');
261 options.SetSourceSize(1);
262 options.SetBinaryZeroIsTerminator(false);
264 switch (wchar_size) {
266 return StringPrinter::ReadBufferAndDumpToStream<
267 StringPrinter::StringElementType::UTF8>(options);
269 return StringPrinter::ReadBufferAndDumpToStream<
270 StringPrinter::StringElementType::UTF16>(options);
272 return StringPrinter::ReadBufferAndDumpToStream<
273 StringPrinter::StringElementType::UTF32>(options);
275 stream.Printf("size for wchar_t is not valid");