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::Char16StringSummaryProvider(
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("u");
51 if (!StringPrinter::ReadStringAndDumpToStream<
52 StringPrinter::StringElementType::UTF16>(options)) {
53 stream.Printf("Summary Unavailable");
60 bool lldb_private::formatters::Char32StringSummaryProvider(
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::UTF32>(options)) {
78 stream.Printf("Summary Unavailable");
85 bool lldb_private::formatters::WCharStringSummaryProvider(
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 // Get a wchar_t basic type from the current type system
96 CompilerType wchar_compiler_type =
97 valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
99 if (!wchar_compiler_type)
102 // Safe to pass nullptr for exe_scope here.
103 llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
106 const uint32_t wchar_size = *size;
108 StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
109 options.SetLocation(valobj_addr);
110 options.SetProcessSP(process_sp);
111 options.SetStream(&stream);
112 options.SetPrefixToken("L");
114 switch (wchar_size) {
116 return StringPrinter::ReadStringAndDumpToStream<
117 StringPrinter::StringElementType::UTF8>(options);
119 return StringPrinter::ReadStringAndDumpToStream<
120 StringPrinter::StringElementType::UTF16>(options);
122 return StringPrinter::ReadStringAndDumpToStream<
123 StringPrinter::StringElementType::UTF32>(options);
125 stream.Printf("size for wchar_t is not valid");
131 bool lldb_private::formatters::Char16SummaryProvider(
132 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
135 valobj.GetData(data, error);
141 valobj.GetValueAsCString(lldb::eFormatUnicode16, value);
143 stream.Printf("%s ", value.c_str());
145 StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
146 options.SetData(data);
147 options.SetStream(&stream);
148 options.SetPrefixToken("u");
149 options.SetQuote('\'');
150 options.SetSourceSize(1);
151 options.SetBinaryZeroIsTerminator(false);
153 return StringPrinter::ReadBufferAndDumpToStream<
154 StringPrinter::StringElementType::UTF16>(options);
157 bool lldb_private::formatters::Char32SummaryProvider(
158 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
161 valobj.GetData(data, error);
167 valobj.GetValueAsCString(lldb::eFormatUnicode32, value);
169 stream.Printf("%s ", value.c_str());
171 StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
172 options.SetData(data);
173 options.SetStream(&stream);
174 options.SetPrefixToken("U");
175 options.SetQuote('\'');
176 options.SetSourceSize(1);
177 options.SetBinaryZeroIsTerminator(false);
179 return StringPrinter::ReadBufferAndDumpToStream<
180 StringPrinter::StringElementType::UTF32>(options);
183 bool lldb_private::formatters::WCharSummaryProvider(
184 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
187 valobj.GetData(data, error);
192 // Get a wchar_t basic type from the current type system
193 CompilerType wchar_compiler_type =
194 valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
196 if (!wchar_compiler_type)
199 // Safe to pass nullptr for exe_scope here.
200 llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
203 const uint32_t wchar_size = *size;
205 StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
206 options.SetData(data);
207 options.SetStream(&stream);
208 options.SetPrefixToken("L");
209 options.SetQuote('\'');
210 options.SetSourceSize(1);
211 options.SetBinaryZeroIsTerminator(false);
213 switch (wchar_size) {
215 return StringPrinter::ReadBufferAndDumpToStream<
216 StringPrinter::StringElementType::UTF8>(options);
218 return StringPrinter::ReadBufferAndDumpToStream<
219 StringPrinter::StringElementType::UTF16>(options);
221 return StringPrinter::ReadBufferAndDumpToStream<
222 StringPrinter::StringElementType::UTF32>(options);
224 stream.Printf("size for wchar_t is not valid");