1 //===-- CxxStringTypes.cpp --------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "CxxStringTypes.h"
11
12 #include "llvm/Support/ConvertUTF.h"
13
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/Symbol/ClangASTContext.h"
21 #include "lldb/Target/ProcessStructReader.h"
22 #include "lldb/Target/SectionLoadList.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25 #include "lldb/Utility/DataBufferHeap.h"
26 #include "lldb/Utility/Endian.h"
27 #include "lldb/Utility/Status.h"
28 #include "lldb/Utility/Stream.h"
29
30 #include <algorithm>
31
32 using namespace lldb;
33 using namespace lldb_private;
34 using namespace lldb_private::formatters;
35
Char16StringSummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)36 bool lldb_private::formatters::Char16StringSummaryProvider(
37 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
38 ProcessSP process_sp = valobj.GetProcessSP();
39 if (!process_sp)
40 return false;
41
42 lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
43 if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
44 return false;
45
46 StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
47 options.SetLocation(valobj_addr);
48 options.SetProcessSP(process_sp);
49 options.SetStream(&stream);
50 options.SetPrefixToken("u");
51
52 if (!StringPrinter::ReadStringAndDumpToStream<
53 StringPrinter::StringElementType::UTF16>(options)) {
54 stream.Printf("Summary Unavailable");
55 return true;
56 }
57
58 return true;
59 }
60
Char32StringSummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)61 bool lldb_private::formatters::Char32StringSummaryProvider(
62 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
63 ProcessSP process_sp = valobj.GetProcessSP();
64 if (!process_sp)
65 return false;
66
67 lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
68 if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
69 return false;
70
71 StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
72 options.SetLocation(valobj_addr);
73 options.SetProcessSP(process_sp);
74 options.SetStream(&stream);
75 options.SetPrefixToken("U");
76
77 if (!StringPrinter::ReadStringAndDumpToStream<
78 StringPrinter::StringElementType::UTF32>(options)) {
79 stream.Printf("Summary Unavailable");
80 return true;
81 }
82
83 return true;
84 }
85
WCharStringSummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)86 bool lldb_private::formatters::WCharStringSummaryProvider(
87 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
88 ProcessSP process_sp = valobj.GetProcessSP();
89 if (!process_sp)
90 return false;
91
92 lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
93 if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
94 return false;
95
96 // Get a wchar_t basic type from the current type system
97 CompilerType wchar_compiler_type =
98 valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
99
100 if (!wchar_compiler_type)
101 return false;
102
103 // Safe to pass nullptr for exe_scope here.
104 llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
105 if (!size)
106 return false;
107 const uint32_t wchar_size = *size;
108
109 StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
110 options.SetLocation(valobj_addr);
111 options.SetProcessSP(process_sp);
112 options.SetStream(&stream);
113 options.SetPrefixToken("L");
114
115 switch (wchar_size) {
116 case 8:
117 return StringPrinter::ReadStringAndDumpToStream<
118 StringPrinter::StringElementType::UTF8>(options);
119 case 16:
120 return StringPrinter::ReadStringAndDumpToStream<
121 StringPrinter::StringElementType::UTF16>(options);
122 case 32:
123 return StringPrinter::ReadStringAndDumpToStream<
124 StringPrinter::StringElementType::UTF32>(options);
125 default:
126 stream.Printf("size for wchar_t is not valid");
127 return true;
128 }
129 return true;
130 }
131
Char16SummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)132 bool lldb_private::formatters::Char16SummaryProvider(
133 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
134 DataExtractor data;
135 Status error;
136 valobj.GetData(data, error);
137
138 if (error.Fail())
139 return false;
140
141 std::string value;
142 valobj.GetValueAsCString(lldb::eFormatUnicode16, value);
143 if (!value.empty())
144 stream.Printf("%s ", value.c_str());
145
146 StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
147 options.SetData(data);
148 options.SetStream(&stream);
149 options.SetPrefixToken("u");
150 options.SetQuote('\'');
151 options.SetSourceSize(1);
152 options.SetBinaryZeroIsTerminator(false);
153
154 return StringPrinter::ReadBufferAndDumpToStream<
155 StringPrinter::StringElementType::UTF16>(options);
156 }
157
Char32SummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)158 bool lldb_private::formatters::Char32SummaryProvider(
159 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
160 DataExtractor data;
161 Status error;
162 valobj.GetData(data, error);
163
164 if (error.Fail())
165 return false;
166
167 std::string value;
168 valobj.GetValueAsCString(lldb::eFormatUnicode32, value);
169 if (!value.empty())
170 stream.Printf("%s ", value.c_str());
171
172 StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
173 options.SetData(data);
174 options.SetStream(&stream);
175 options.SetPrefixToken("U");
176 options.SetQuote('\'');
177 options.SetSourceSize(1);
178 options.SetBinaryZeroIsTerminator(false);
179
180 return StringPrinter::ReadBufferAndDumpToStream<
181 StringPrinter::StringElementType::UTF32>(options);
182 }
183
WCharSummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)184 bool lldb_private::formatters::WCharSummaryProvider(
185 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
186 DataExtractor data;
187 Status error;
188 valobj.GetData(data, error);
189
190 if (error.Fail())
191 return false;
192
193 // Get a wchar_t basic type from the current type system
194 CompilerType wchar_compiler_type =
195 valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
196
197 if (!wchar_compiler_type)
198 return false;
199
200 // Safe to pass nullptr for exe_scope here.
201 llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
202 if (!size)
203 return false;
204 const uint32_t wchar_size = *size;
205
206 StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
207 options.SetData(data);
208 options.SetStream(&stream);
209 options.SetPrefixToken("L");
210 options.SetQuote('\'');
211 options.SetSourceSize(1);
212 options.SetBinaryZeroIsTerminator(false);
213
214 switch (wchar_size) {
215 case 8:
216 return StringPrinter::ReadBufferAndDumpToStream<
217 StringPrinter::StringElementType::UTF8>(options);
218 case 16:
219 return StringPrinter::ReadBufferAndDumpToStream<
220 StringPrinter::StringElementType::UTF16>(options);
221 case 32:
222 return StringPrinter::ReadBufferAndDumpToStream<
223 StringPrinter::StringElementType::UTF32>(options);
224 default:
225 stream.Printf("size for wchar_t is not valid");
226 return true;
227 }
228 return true;
229 }
230