LLDB mainline
MsvcStl.cpp
Go to the documentation of this file.
1//===-- MsvcStl.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 "MsvcStl.h"
10
11#include "lldb/Core/Debugger.h"
16#include "lldb/Utility/Status.h"
17#include "lldb/Utility/Stream.h"
19#include "llvm/ADT/StringRef.h"
20
22
23#include "lldb/lldb-forward.h"
24#include <optional>
25#include <tuple>
26
27using namespace lldb;
28using namespace lldb_private;
29using namespace lldb_private::formatters;
30
32
33template <StringElementType element_type>
34static constexpr uint64_t StringElementByteSize() {
35 switch (element_type) {
36 case StringElementType::ASCII:
37 case StringElementType::UTF8:
38 return 1;
39 case StringElementType::UTF16:
40 return 2;
41 case StringElementType::UTF32:
42 return 3;
43 }
44 return 0;
45}
46
48 return valobj.GetChildAtNamePath({"_Mypair", "_Myval2"});
49}
50
51/// Determine the size in bytes of \p valobj (a MSVC STL std::string object) and
52/// extract its data payload. Return the size + payload pair.
53static std::optional<std::pair<uint64_t, ValueObjectSP>>
54ExtractMsvcStlStringInfo(ValueObject &valobj, uint64_t element_size) {
55 ValueObjectSP valobj_pair_sp = ExtractMsvcStlStringData(valobj);
56 if (!valobj_pair_sp || !valobj_pair_sp->GetError().Success())
57 return {};
58
59 ValueObjectSP size_sp = valobj_pair_sp->GetChildMemberWithName("_Mysize");
60 ValueObjectSP capacity_sp = valobj_pair_sp->GetChildMemberWithName("_Myres");
61 ValueObjectSP bx_sp = valobj_pair_sp->GetChildMemberWithName("_Bx");
62 if (!size_sp || !capacity_sp || !bx_sp)
63 return {};
64
65 bool success = false;
66 uint64_t size = size_sp->GetValueAsUnsigned(0, &success);
67 if (!success)
68 return {};
69 uint64_t capacity = capacity_sp->GetValueAsUnsigned(0, &success);
70 if (!success)
71 return {};
72
73 size_t bufSize = std::max<size_t>(16 / element_size, 1);
74 bool isShortString = capacity < bufSize;
75
76 if (isShortString) {
77 ValueObjectSP buf_sp = bx_sp->GetChildMemberWithName("_Buf");
78 if (buf_sp)
79 return std::make_pair(size, buf_sp);
80 return {};
81 }
82 ValueObjectSP ptr_sp = bx_sp->GetChildMemberWithName("_Ptr");
83 if (ptr_sp)
84 return std::make_pair(size, ptr_sp);
85 return {};
86}
87
88template <StringPrinter::StringElementType element_type>
89static bool
91 const TypeSummaryOptions &summary_options,
92 std::string prefix_token) {
93 auto string_info =
95 if (!string_info)
96 return false;
97 auto [size, location_sp] = *string_info;
98
100 stream, summary_options, location_sp, size, prefix_token);
101}
102template <StringPrinter::StringElementType element_type>
103static bool formatStringImpl(ValueObject &valobj, Stream &stream,
104 const TypeSummaryOptions &summary_options,
105 std::string prefix_token) {
106 StreamString scratch_stream;
108 valobj, scratch_stream, summary_options, prefix_token);
109 if (success)
110 stream << scratch_stream.GetData();
111 else
112 stream << "Summary Unavailable";
113 return true;
114}
115
116template <StringPrinter::StringElementType element_type>
117static bool formatStringViewImpl(ValueObject &valobj, Stream &stream,
118 const TypeSummaryOptions &summary_options,
119 std::string prefix_token) {
120 auto data_sp = valobj.GetChildMemberWithName("_Mydata");
121 auto size_sp = valobj.GetChildMemberWithName("_Mysize");
122 if (!data_sp || !size_sp)
123 return false;
124
125 bool success = false;
126 uint64_t size = size_sp->GetValueAsUnsigned(0, &success);
127 if (!success) {
128 stream << "Summary Unavailable";
129 return true;
130 }
131
132 StreamString scratch_stream;
134 scratch_stream, summary_options, data_sp, size, prefix_token);
135
136 if (success)
137 stream << scratch_stream.GetData();
138 else
139 stream << "Summary Unavailable";
140 return true;
141}
142
144 std::vector<uint32_t> indexes;
145 return valobj.GetCompilerType().GetIndexOfChildMemberWithName("_Mypair", true,
146 indexes) > 0;
147}
148
150 std::vector<uint32_t> indexes;
151 return valobj.GetCompilerType().GetIndexOfChildMemberWithName("_Mydata", true,
152 indexes) > 0;
153}
154
156 ValueObject &valobj, Stream &stream,
157 const TypeSummaryOptions &summary_options) {
158 return formatStringImpl<StringElementType::UTF16>(valobj, stream,
159 summary_options, "L");
160}
161
162template <>
164 StringElementType::ASCII>(ValueObject &valobj, Stream &stream,
165 const TypeSummaryOptions &summary_options) {
167 valobj, stream, summary_options, "");
168}
169template <>
171 StringElementType::UTF8>(ValueObject &valobj, Stream &stream,
172 const TypeSummaryOptions &summary_options) {
174 valobj, stream, summary_options, "u8");
175}
176template <>
178 StringElementType::UTF16>(ValueObject &valobj, Stream &stream,
179 const TypeSummaryOptions &summary_options) {
181 valobj, stream, summary_options, "u");
182}
183template <>
185 StringElementType::UTF32>(ValueObject &valobj, Stream &stream,
186 const TypeSummaryOptions &summary_options) {
188 valobj, stream, summary_options, "U");
189}
190
192 ValueObject &valobj, Stream &stream,
193 const TypeSummaryOptions &summary_options) {
195 summary_options, "L");
196}
197
198template <>
200 StringElementType::ASCII>(ValueObject &valobj, Stream &stream,
201 const TypeSummaryOptions &summary_options) {
203 summary_options, "");
204}
205template <>
207 StringElementType::UTF8>(ValueObject &valobj, Stream &stream,
208 const TypeSummaryOptions &summary_options) {
210 summary_options, "u8");
211}
212template <>
214 StringElementType::UTF16>(ValueObject &valobj, Stream &stream,
215 const TypeSummaryOptions &summary_options) {
217 summary_options, "u");
218}
219template <>
221 StringElementType::UTF32>(ValueObject &valobj, Stream &stream,
222 const TypeSummaryOptions &summary_options) {
224 summary_options, "U");
225}
226
228 std::vector<uint32_t> indexes;
229 return valobj.GetCompilerType().GetIndexOfChildMemberWithName("_Value", true,
230 indexes) > 0;
231}
232
233static std::optional<int64_t> MsvcStlExtractOrderingValue(ValueObject &valobj) {
234 lldb::ValueObjectSP value_sp = valobj.GetChildMemberWithName("_Value");
235 if (!value_sp)
236 return std::nullopt;
237 bool success;
238 int64_t value = value_sp->GetValueAsSigned(0, &success);
239 if (!success)
240 return std::nullopt;
241 return value;
242}
243
245 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
246 std::optional<int64_t> value = MsvcStlExtractOrderingValue(valobj);
247 if (!value)
248 return false;
249 switch (*value) {
250 case -1:
251 stream << "less";
252 break;
253 case 0:
254 stream << "equivalent";
255 break;
256 case 1:
257 stream << "greater";
258 break;
259 case -128:
260 stream << "unordered";
261 break;
262 default:
263 return false;
264 }
265 return true;
266}
267
269 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
270 std::optional<int64_t> value = MsvcStlExtractOrderingValue(valobj);
271 if (!value)
272 return false;
273 switch (*value) {
274 case -1:
275 stream << "less";
276 break;
277 case 0:
278 stream << "equivalent";
279 break;
280 case 1:
281 stream << "greater";
282 break;
283 default:
284 return false;
285 }
286 return true;
287}
288
290 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
291 std::optional<int64_t> value = MsvcStlExtractOrderingValue(valobj);
292 if (!value)
293 return false;
294 switch (*value) {
295 case -1:
296 stream << "less";
297 break;
298 case 0:
299 stream << "equal";
300 break;
301 case 1:
302 stream << "greater";
303 break;
304 default:
305 return false;
306 }
307 return true;
308}
309
311 if (auto valobj_sp = valobj.GetNonSyntheticValue())
312 return valobj_sp->GetChildMemberWithName("_File") != nullptr;
313 return false;
314}
315
317 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
318 ValueObjectSP file_sp = valobj.GetChildMemberWithName("_File");
319 ValueObjectSP function_sp = valobj.GetChildMemberWithName("_Function");
320 ValueObjectSP line_sp = valobj.GetChildMemberWithName("_Line");
321 ValueObjectSP column_sp = valobj.GetChildMemberWithName("_Column");
322
323 if (!file_sp || !function_sp || !line_sp || !column_sp)
324 return false;
325
326 bool success = false;
327 uint64_t line = line_sp->GetValueAsUnsigned(0, &success);
328 if (!success)
329 return false;
330
331 uint64_t column = column_sp->GetValueAsUnsigned(0, &success);
332 if (!success)
333 return false;
334
335 const char *file = file_sp->GetSummaryAsCString();
336 // Default-constructed source_location is empty; don't invent a summary.
337 if (line == 0 && column == 0 &&
338 (!file || file[0] == '\0' || llvm::StringRef(file) == "\"\""))
339 return false;
340
341 stream.Format("{0}:{1}:{2}", file ? file : "<unknown>", line, column);
342
343 if (const char *function = function_sp->GetSummaryAsCString())
344 stream.Printf(" (%s)", function);
345
346 return true;
347}
static std::optional< std::pair< uint64_t, ValueObjectSP > > ExtractMsvcStlStringInfo(ValueObject &valobj, uint64_t element_size)
Determine the size in bytes of valobj (a MSVC STL std::string object) and extract its data payload.
Definition MsvcStl.cpp:54
static bool formatStringImpl(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options, std::string prefix_token)
Definition MsvcStl.cpp:103
static constexpr uint64_t StringElementByteSize()
Definition MsvcStl.cpp:34
static bool MsvcStlStringSummaryProviderImpl(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options, std::string prefix_token)
Definition MsvcStl.cpp:90
static std::optional< int64_t > MsvcStlExtractOrderingValue(ValueObject &valobj)
Definition MsvcStl.cpp:233
static bool formatStringViewImpl(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options, std::string prefix_token)
Definition MsvcStl.cpp:117
static ValueObjectSP ExtractMsvcStlStringData(ValueObject &valobj)
Definition MsvcStl.cpp:47
StringPrinter::StringElementType StringElementType
size_t GetIndexOfChildMemberWithName(llvm::StringRef name, bool omit_empty_base_classes, std::vector< uint32_t > &child_indexes) const
Lookup a child member given a name.
const char * GetData() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:370
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
virtual lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name, bool can_create=true)
lldb::ValueObjectSP GetChildAtNamePath(llvm::ArrayRef< llvm::StringRef > names)
CompilerType GetCompilerType()
virtual lldb::ValueObjectSP GetNonSyntheticValue()
bool IsMsvcStlStringType(ValueObject &valobj)
Definition MsvcStl.cpp:143
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 MsvcStlPartialOrderingSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition MsvcStl.cpp:244
bool MsvcStlWeakOrderingSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition MsvcStl.cpp:268
bool IsMsvcStlSourceLocation(ValueObject &valobj)
Definition MsvcStl.cpp:310
bool MsvcStlStrongOrderingSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition MsvcStl.cpp:289
bool MsvcStlSourceLocationSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition MsvcStl.cpp:316
bool MsvcStlStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
bool IsMsvcStlOrdering(ValueObject &valobj)
Definition MsvcStl.cpp:227
bool MsvcStlStringViewSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
bool IsMsvcStlStringViewType(ValueObject &valobj)
Definition MsvcStl.cpp:149
bool MsvcStlWStringViewSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition MsvcStl.cpp:191
bool MsvcStlWStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition MsvcStl.cpp:155
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP