• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
13 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
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/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"
28 
29 #include <algorithm>
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 using namespace lldb_private::formatters;
34 
Char8StringSummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)35 bool lldb_private::formatters::Char8StringSummaryProvider(
36     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
37   ProcessSP process_sp = valobj.GetProcessSP();
38   if (!process_sp)
39     return false;
40 
41   lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
42   if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
43     return false;
44 
45   StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
46   options.SetLocation(valobj_addr);
47   options.SetProcessSP(process_sp);
48   options.SetStream(&stream);
49   options.SetPrefixToken("u8");
50 
51   if (!StringPrinter::ReadStringAndDumpToStream<
52           StringPrinter::StringElementType::UTF8>(options)) {
53     stream.Printf("Summary Unavailable");
54     return true;
55   }
56 
57   return true;
58 }
59 
Char16StringSummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)60 bool lldb_private::formatters::Char16StringSummaryProvider(
61     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
62   ProcessSP process_sp = valobj.GetProcessSP();
63   if (!process_sp)
64     return false;
65 
66   lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
67   if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
68     return false;
69 
70   StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
71   options.SetLocation(valobj_addr);
72   options.SetProcessSP(process_sp);
73   options.SetStream(&stream);
74   options.SetPrefixToken("u");
75 
76   if (!StringPrinter::ReadStringAndDumpToStream<
77           StringPrinter::StringElementType::UTF16>(options)) {
78     stream.Printf("Summary Unavailable");
79     return true;
80   }
81 
82   return true;
83 }
84 
Char32StringSummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)85 bool lldb_private::formatters::Char32StringSummaryProvider(
86     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
87   ProcessSP process_sp = valobj.GetProcessSP();
88   if (!process_sp)
89     return false;
90 
91   lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
92   if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
93     return false;
94 
95   StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
96   options.SetLocation(valobj_addr);
97   options.SetProcessSP(process_sp);
98   options.SetStream(&stream);
99   options.SetPrefixToken("U");
100 
101   if (!StringPrinter::ReadStringAndDumpToStream<
102           StringPrinter::StringElementType::UTF32>(options)) {
103     stream.Printf("Summary Unavailable");
104     return true;
105   }
106 
107   return true;
108 }
109 
WCharStringSummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)110 bool lldb_private::formatters::WCharStringSummaryProvider(
111     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
112   ProcessSP process_sp = valobj.GetProcessSP();
113   if (!process_sp)
114     return false;
115 
116   lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
117   if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
118     return false;
119 
120   // Get a wchar_t basic type from the current type system
121   CompilerType wchar_compiler_type =
122       valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
123 
124   if (!wchar_compiler_type)
125     return false;
126 
127   // Safe to pass nullptr for exe_scope here.
128   llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
129   if (!size)
130     return false;
131   const uint32_t wchar_size = *size;
132 
133   StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
134   options.SetLocation(valobj_addr);
135   options.SetProcessSP(process_sp);
136   options.SetStream(&stream);
137   options.SetPrefixToken("L");
138 
139   switch (wchar_size) {
140   case 8:
141     return StringPrinter::ReadStringAndDumpToStream<
142         StringPrinter::StringElementType::UTF8>(options);
143   case 16:
144     return StringPrinter::ReadStringAndDumpToStream<
145         StringPrinter::StringElementType::UTF16>(options);
146   case 32:
147     return StringPrinter::ReadStringAndDumpToStream<
148         StringPrinter::StringElementType::UTF32>(options);
149   default:
150     stream.Printf("size for wchar_t is not valid");
151     return true;
152   }
153   return true;
154 }
155 
Char8SummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)156 bool lldb_private::formatters::Char8SummaryProvider(
157     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
158   DataExtractor data;
159   Status error;
160   valobj.GetData(data, error);
161 
162   if (error.Fail())
163     return false;
164 
165   std::string value;
166   valobj.GetValueAsCString(lldb::eFormatUnicode8, value);
167   if (!value.empty())
168     stream.Printf("%s ", value.c_str());
169 
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);
177 
178   return StringPrinter::ReadBufferAndDumpToStream<
179       StringPrinter::StringElementType::UTF8>(options);
180 }
181 
Char16SummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)182 bool lldb_private::formatters::Char16SummaryProvider(
183     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
184   DataExtractor data;
185   Status error;
186   valobj.GetData(data, error);
187 
188   if (error.Fail())
189     return false;
190 
191   std::string value;
192   valobj.GetValueAsCString(lldb::eFormatUnicode16, value);
193   if (!value.empty())
194     stream.Printf("%s ", value.c_str());
195 
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);
203 
204   return StringPrinter::ReadBufferAndDumpToStream<
205       StringPrinter::StringElementType::UTF16>(options);
206 }
207 
Char32SummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)208 bool lldb_private::formatters::Char32SummaryProvider(
209     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
210   DataExtractor data;
211   Status error;
212   valobj.GetData(data, error);
213 
214   if (error.Fail())
215     return false;
216 
217   std::string value;
218   valobj.GetValueAsCString(lldb::eFormatUnicode32, value);
219   if (!value.empty())
220     stream.Printf("%s ", value.c_str());
221 
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);
229 
230   return StringPrinter::ReadBufferAndDumpToStream<
231       StringPrinter::StringElementType::UTF32>(options);
232 }
233 
WCharSummaryProvider(ValueObject & valobj,Stream & stream,const TypeSummaryOptions &)234 bool lldb_private::formatters::WCharSummaryProvider(
235     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
236   DataExtractor data;
237   Status error;
238   valobj.GetData(data, error);
239 
240   if (error.Fail())
241     return false;
242 
243   // Get a wchar_t basic type from the current type system
244   CompilerType wchar_compiler_type =
245       valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
246 
247   if (!wchar_compiler_type)
248     return false;
249 
250     // Safe to pass nullptr for exe_scope here.
251   llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
252   if (!size)
253     return false;
254   const uint32_t wchar_size = *size;
255 
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);
263 
264   switch (wchar_size) {
265   case 8:
266     return StringPrinter::ReadBufferAndDumpToStream<
267         StringPrinter::StringElementType::UTF8>(options);
268   case 16:
269     return StringPrinter::ReadBufferAndDumpToStream<
270         StringPrinter::StringElementType::UTF16>(options);
271   case 32:
272     return StringPrinter::ReadBufferAndDumpToStream<
273         StringPrinter::StringElementType::UTF32>(options);
274   default:
275     stream.Printf("size for wchar_t is not valid");
276     return true;
277   }
278   return true;
279 }
280