]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / tools / lldb-mi / MICmnLLDBUtilSBValue.cpp
1 //===-- MICmnLLDBUtilSBValue.cpp --------------------------------*- C++ -*-===//
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 // Third party headers:
10 #include "lldb/API/SBTypeSummary.h"
11 #include <cinttypes>
12
13 // In-house headers:
14 #include "MICmnLLDBDebugSessionInfo.h"
15 #include "MICmnLLDBUtilSBValue.h"
16 #include "MICmnMIValueConst.h"
17 #include "MICmnMIValueTuple.h"
18 #include "MIUtilString.h"
19
20 static const char *kUnknownValue = "??";
21 static const char *kUnresolvedCompositeValue = "{...}";
22
23 //++
24 // Details: CMICmnLLDBUtilSBValue constructor.
25 // Type:    Method.
26 // Args:    vrValue             - (R) The LLDB value object.
27 //          vbHandleCharType    - (R) True = Yes return text molding to char
28 //          type,
29 //                                    False = just return data.
30 // Return:  None.
31 // Throws:  None.
32 //--
33 CMICmnLLDBUtilSBValue::CMICmnLLDBUtilSBValue(
34     const lldb::SBValue &vrValue, const bool vbHandleCharType /* = false */,
35     const bool vbHandleArrayType /* = true */)
36     : m_rValue(const_cast<lldb::SBValue &>(vrValue)),
37       m_bHandleCharType(vbHandleCharType),
38       m_bHandleArrayType(vbHandleArrayType) {
39   m_bValidSBValue = m_rValue.IsValid();
40 }
41
42 //++
43 // Details: CMICmnLLDBUtilSBValue destructor.
44 // Type:    Method.
45 // Args:    None.
46 // Return:  None.
47 // Throws:  None.
48 //--
49 CMICmnLLDBUtilSBValue::~CMICmnLLDBUtilSBValue() {}
50
51 //++
52 // Details: Retrieve from the LLDB SB Value object the name of the variable. If
53 // the name
54 //          is invalid (or the SBValue object invalid) then "??" is returned.
55 // Type:    Method.
56 // Args:    None.
57 // Return:  CMIUtilString   - Name of the variable or "??" for unknown.
58 // Throws:  None.
59 //--
60 CMIUtilString CMICmnLLDBUtilSBValue::GetName() const {
61   const char *pName = m_bValidSBValue ? m_rValue.GetName() : nullptr;
62   const CMIUtilString text((pName != nullptr) ? pName : CMIUtilString());
63
64   return text;
65 }
66
67 //++
68 // Details: Retrieve from the LLDB SB Value object the value of the variable
69 // described in
70 //          text. If the value is invalid (or the SBValue object invalid) then
71 //          "??" is
72 //          returned.
73 // Type:    Method.
74 // Args:    None.
75 // Return:  CMIUtilString   - Text description of the variable's value or "??".
76 // Throws:  None.
77 //--
78 CMIUtilString CMICmnLLDBUtilSBValue::GetValue(
79     const bool vbExpandAggregates /* = false */) const {
80   if (!m_bValidSBValue)
81     return kUnknownValue;
82
83   CMICmnLLDBDebugSessionInfo &rSessionInfo(
84       CMICmnLLDBDebugSessionInfo::Instance());
85   bool bPrintExpandAggregates = false;
86   bPrintExpandAggregates = rSessionInfo.SharedDataRetrieve<bool>(
87                                rSessionInfo.m_constStrPrintExpandAggregates,
88                                bPrintExpandAggregates) &&
89                            bPrintExpandAggregates;
90
91   const bool bHandleArrayTypeAsSimple =
92       m_bHandleArrayType && !vbExpandAggregates && !bPrintExpandAggregates;
93   CMIUtilString value;
94   const bool bIsSimpleValue = GetSimpleValue(bHandleArrayTypeAsSimple, value);
95   if (bIsSimpleValue)
96     return value;
97
98   if (!vbExpandAggregates && !bPrintExpandAggregates)
99     return kUnresolvedCompositeValue;
100
101   bool bPrintAggregateFieldNames = false;
102   bPrintAggregateFieldNames =
103       !rSessionInfo.SharedDataRetrieve<bool>(
104           rSessionInfo.m_constStrPrintAggregateFieldNames,
105           bPrintAggregateFieldNames) ||
106       bPrintAggregateFieldNames;
107
108   CMICmnMIValueTuple miValueTuple;
109   const bool bOk = GetCompositeValue(bPrintAggregateFieldNames, miValueTuple);
110   if (!bOk)
111     return kUnknownValue;
112
113   value = miValueTuple.GetString();
114   return value;
115 }
116
117 //++
118 // Details: Retrieve from the LLDB SB Value object the value of the variable
119 // described in
120 //          text if it has a simple format (not composite).
121 // Type:    Method.
122 // Args:    vwrValue          - (W) The SBValue in a string format.
123 // Return:  MIstatus::success - Function succeeded.
124 //          MIstatus::failure - Function failed.
125 // Throws:  None.
126 //--
127 bool CMICmnLLDBUtilSBValue::GetSimpleValue(const bool vbHandleArrayType,
128                                            CMIUtilString &vwrValue) const {
129   const MIuint nChildren = m_rValue.GetNumChildren();
130   if (nChildren == 0) {
131     vwrValue = GetValueSummary(!m_bHandleCharType && IsCharType(), kUnknownValue);
132     return MIstatus::success;
133   } else if (IsPointerType()) {
134     vwrValue =
135         GetValueSummary(!m_bHandleCharType && IsPointeeCharType(), kUnknownValue);
136     return MIstatus::success;
137   } else if (IsArrayType()) {
138     CMICmnLLDBDebugSessionInfo &rSessionInfo(
139         CMICmnLLDBDebugSessionInfo::Instance());
140     bool bPrintCharArrayAsString = false;
141     bPrintCharArrayAsString = rSessionInfo.SharedDataRetrieve<bool>(
142                                   rSessionInfo.m_constStrPrintCharArrayAsString,
143                                   bPrintCharArrayAsString) &&
144                               bPrintCharArrayAsString;
145     if (bPrintCharArrayAsString && m_bHandleCharType &&
146         IsFirstChildCharType()) {
147       vwrValue = GetValueSummary(false);
148       return MIstatus::success;
149     } else if (vbHandleArrayType) {
150       vwrValue = CMIUtilString::Format("[%u]", nChildren);
151       return MIstatus::success;
152     }
153   } else {
154     // Treat composite value which has registered summary
155     // (for example with AddCXXSummary) as simple value
156     vwrValue = GetValueSummary(false);
157     if (!vwrValue.empty())
158       return MIstatus::success;
159   }
160
161   // Composite variable type i.e. struct
162   return MIstatus::failure;
163 }
164
165 bool CMICmnLLDBUtilSBValue::GetCompositeValue(
166     const bool vbPrintFieldNames, CMICmnMIValueTuple &vwrMiValueTuple,
167     const MIuint vnDepth /* = 1 */) const {
168   const MIuint nMaxDepth = 10;
169   const MIuint nChildren = m_rValue.GetNumChildren();
170   for (MIuint i = 0; i < nChildren; ++i) {
171     const lldb::SBValue member = m_rValue.GetChildAtIndex(i);
172     const CMICmnLLDBUtilSBValue utilMember(member, m_bHandleCharType,
173                                            m_bHandleArrayType);
174     const bool bHandleArrayTypeAsSimple = false;
175     CMIUtilString value;
176     const bool bIsSimpleValue =
177         utilMember.GetSimpleValue(bHandleArrayTypeAsSimple, value);
178     if (bIsSimpleValue) {
179       // OK. Value is simple (not composite) and was successfully got
180     } else if (vnDepth < nMaxDepth) {
181       // Need to get value from composite type
182       CMICmnMIValueTuple miValueTuple;
183       const bool bOk = utilMember.GetCompositeValue(vbPrintFieldNames,
184                                                     miValueTuple, vnDepth + 1);
185       if (!bOk)
186         // Can't obtain composite type
187         value = kUnknownValue;
188       else
189         // OK. Value is composite and was successfully got
190         value = miValueTuple.GetString();
191     } else {
192       // Need to get value from composite type, but vnMaxDepth is reached
193       value = kUnresolvedCompositeValue;
194     }
195     const bool bNoQuotes = true;
196     const CMICmnMIValueConst miValueConst(value, bNoQuotes);
197     if (vbPrintFieldNames) {
198       const bool bUseSpacing = true;
199       const CMICmnMIValueResult miValueResult(utilMember.GetName(),
200                                               miValueConst, bUseSpacing);
201       vwrMiValueTuple.Add(miValueResult, bUseSpacing);
202     } else {
203       const bool bUseSpacing = false;
204       vwrMiValueTuple.Add(miValueConst, bUseSpacing);
205     }
206   }
207
208   return MIstatus::success;
209 }
210
211 // Returns value or value + summary, depending on valueOnly parameter value.
212 // If result is an empty string returns failVal.
213 CMIUtilString
214 CMICmnLLDBUtilSBValue::GetValueSummary(bool valueOnly,
215                                        const CMIUtilString &failVal) const {
216   if (!m_rValue.IsValid())
217     return failVal;
218
219   CMIUtilString value, valSummary;
220   const char *c_value = m_rValue.GetValue();
221   if (valueOnly)
222     return c_value == nullptr ? failVal : c_value;
223
224   const char *c_summary = m_rValue.GetSummary();
225   if (c_value)
226     value = c_value;
227   else if (c_summary == nullptr)
228     return failVal;
229
230   if (c_summary && c_summary[0]) {
231     valSummary = c_summary;
232     lldb::SBTypeSummary summary = m_rValue.GetTypeSummary();
233     if (summary.IsValid() && summary.DoesPrintValue(m_rValue) &&
234         !value.empty()) {
235       valSummary.insert(0, value + " ");
236     }
237     return valSummary;
238   }
239   // no summary - return just value
240   return value;
241 }
242
243 //++
244 // Details: Check that basic type is a char type. Char type can be signed or
245 // unsigned.
246 // Type:    Static.
247 // Args:    eType   - type to check
248 // Return:  bool    - True = Yes is a char type, false = some other type.
249 // Throws:  None.
250 //--
251 bool CMICmnLLDBUtilSBValue::IsCharBasicType(lldb::BasicType eType) {
252   switch (eType) {
253   case lldb::eBasicTypeChar:
254   case lldb::eBasicTypeSignedChar:
255   case lldb::eBasicTypeUnsignedChar:
256   case lldb::eBasicTypeChar16:
257   case lldb::eBasicTypeChar32:
258     return true;
259   default:
260     return false;
261   }
262 }
263
264 //++
265 // Details: Retrieve the flag stating whether this value object is a char type
266 // or some
267 //          other type. Char type can be signed or unsigned.
268 // Type:    Method.
269 // Args:    None.
270 // Return:  bool    - True = Yes is a char type, false = some other type.
271 // Throws:  None.
272 //--
273 bool CMICmnLLDBUtilSBValue::IsCharType() const {
274   const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
275   return IsCharBasicType(eType);
276 }
277
278 //++
279 // Details: Retrieve the flag stating whether first child value object of *this
280 // object is
281 //          a char type or some other type. Returns false if there are not
282 //          children. Char
283 //          type can be signed or unsigned.
284 // Type:    Method.
285 // Args:    None.
286 // Return:  bool    - True = Yes is a char type, false = some other type.
287 // Throws:  None.
288 //--
289 bool CMICmnLLDBUtilSBValue::IsFirstChildCharType() const {
290   const MIuint nChildren = m_rValue.GetNumChildren();
291
292   // Is it a basic type
293   if (nChildren == 0)
294     return false;
295
296   const lldb::SBValue member = m_rValue.GetChildAtIndex(0);
297   const CMICmnLLDBUtilSBValue utilValue(member);
298   return utilValue.IsCharType();
299 }
300
301 //++
302 // Details: Retrieve the flag stating whether pointee object of *this object is
303 //          a char type or some other type. Returns false if there are not
304 //          children. Char
305 //          type can be signed or unsigned.
306 // Type:    Method.
307 // Args:    None.
308 // Return:  bool    - True = Yes is a char type, false = some other type.
309 // Throws:  None.
310 //--
311 bool CMICmnLLDBUtilSBValue::IsPointeeCharType() const {
312   const MIuint nChildren = m_rValue.GetNumChildren();
313
314   // Is it a basic type
315   if (nChildren == 0)
316     return false;
317
318   const lldb::BasicType eType =
319       m_rValue.GetType().GetPointeeType().GetBasicType();
320   return IsCharBasicType(eType);
321 }
322
323 //++
324 // Details: Retrieve the flag stating whether this value object is a integer
325 // type or some
326 //          other type. Char type can be signed or unsigned and short or
327 //          long/very long.
328 // Type:    Method.
329 // Args:    None.
330 // Return:  bool    - True = Yes is a integer type, false = some other type.
331 // Throws:  None.
332 //--
333 bool CMICmnLLDBUtilSBValue::IsIntegerType() const {
334   const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
335   return ((eType == lldb::eBasicTypeShort) ||
336           (eType == lldb::eBasicTypeUnsignedShort) ||
337           (eType == lldb::eBasicTypeInt) ||
338           (eType == lldb::eBasicTypeUnsignedInt) ||
339           (eType == lldb::eBasicTypeLong) ||
340           (eType == lldb::eBasicTypeUnsignedLong) ||
341           (eType == lldb::eBasicTypeLongLong) ||
342           (eType == lldb::eBasicTypeUnsignedLongLong) ||
343           (eType == lldb::eBasicTypeInt128) ||
344           (eType == lldb::eBasicTypeUnsignedInt128));
345 }
346
347 //++
348 // Details: Retrieve the flag stating whether this value object is a pointer
349 // type or some
350 //          other type.
351 // Type:    Method.
352 // Args:    None.
353 // Return:  bool    - True = Yes is a pointer type, false = some other type.
354 // Throws:  None.
355 //--
356 bool CMICmnLLDBUtilSBValue::IsPointerType() const {
357   return m_rValue.GetType().IsPointerType();
358 }
359
360 //++
361 // Details: Retrieve the flag stating whether this value object is an array type
362 // or some
363 //          other type.
364 // Type:    Method.
365 // Args:    None.
366 // Return:  bool    - True = Yes is an array type, false = some other type.
367 // Throws:  None.
368 //--
369 bool CMICmnLLDBUtilSBValue::IsArrayType() const {
370   return m_rValue.GetType().IsArrayType();
371 }
372
373 //++
374 // Details: Retrieve the C string data of value object by read the memory where
375 // the
376 //          variable is held.
377 // Type:    Method.
378 // Args:    vrValue         - (R) LLDB SBValue variable object.
379 // Return:  CMIUtilString   - Text description of the variable's value.
380 // Throws:  None.
381 //--
382 template <typename charT>
383 CMIUtilString
384 CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(lldb::SBValue &vrValue,
385                                                  const MIuint vnMaxLen) const {
386   std::string result;
387   lldb::addr_t addr = vrValue.GetLoadAddress(),
388                end_addr = addr + vnMaxLen * sizeof(charT);
389   lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
390   lldb::SBError error;
391   while (addr < end_addr) {
392     charT ch;
393     const MIuint64 nReadBytes =
394         process.ReadMemory(addr, &ch, sizeof(ch), error);
395     if (error.Fail() || nReadBytes != sizeof(ch))
396       return kUnknownValue;
397     else if (ch == 0)
398       break;
399     result.append(
400         CMIUtilString::ConvertToPrintableASCII(ch, true /* bEscapeQuotes */));
401     addr += sizeof(ch);
402   }
403
404   return result;
405 }
406
407 //++
408 // Details: Retrieve the state of the value object's name.
409 // Type:    Method.
410 // Args:    None.
411 // Return:  bool    - True = yes name is indeterminate, false = name is valid.
412 // Throws:  None.
413 //--
414 bool CMICmnLLDBUtilSBValue::IsNameUnknown() const {
415   const CMIUtilString name(GetName());
416   return (name == kUnknownValue);
417 }
418
419 //++
420 // Details: Retrieve the state of the value object's value data.
421 // Type:    Method.
422 // Args:    None.
423 // Return:  bool    - True = yes value is indeterminate, false = value valid.
424 // Throws:  None.
425 //--
426 bool CMICmnLLDBUtilSBValue::IsValueUnknown() const {
427   const CMIUtilString value(GetValue());
428   return (value == kUnknownValue);
429 }
430
431 //++
432 // Details: Retrieve the value object's type name if valid.
433 // Type:    Method.
434 // Args:    None.
435 // Return:  CMIUtilString   - The type name or "??".
436 // Throws:  None.
437 //--
438 CMIUtilString CMICmnLLDBUtilSBValue::GetTypeName() const {
439   const char *pName = m_bValidSBValue ? m_rValue.GetTypeName() : nullptr;
440   const CMIUtilString text((pName != nullptr) ? pName : kUnknownValue);
441
442   return text;
443 }
444
445 //++
446 // Details: Retrieve the value object's display type name if valid.
447 // Type:    Method.
448 // Args:    None.
449 // Return:  CMIUtilString   - The type name or "??".
450 // Throws:  None.
451 //--
452 CMIUtilString CMICmnLLDBUtilSBValue::GetTypeNameDisplay() const {
453   const char *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
454   const CMIUtilString text((pName != nullptr) ? pName : kUnknownValue);
455
456   return text;
457 }
458
459 //++
460 // Details: Retrieve whether the value object's is valid or not.
461 // Type:    Method.
462 // Args:    None.
463 // Return:  bool    - True = valid, false = not valid.
464 // Throws:  None.
465 //--
466 bool CMICmnLLDBUtilSBValue::IsValid() const { return m_bValidSBValue; }
467
468 //++
469 // Details: Retrieve the value object' has a name. A value object can be valid
470 // but still
471 //          have no name which suggest it is not a variable.
472 // Type:    Method.
473 // Args:    None.
474 // Return:  bool    - True = valid, false = not valid.
475 // Throws:  None.
476 //--
477 bool CMICmnLLDBUtilSBValue::HasName() const {
478   bool bHasAName = false;
479
480   const char *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
481   if (pName != nullptr) {
482     bHasAName = (CMIUtilString(pName).length() > 0);
483   }
484
485   return bHasAName;
486 }
487
488 //++
489 // Details: Determine if the value object' represents a LLDB variable i.e. "$0".
490 // Type:    Method.
491 // Args:    None.
492 // Return:  bool    - True = Yes LLDB variable, false = no.
493 // Throws:  None.
494 //--
495 bool CMICmnLLDBUtilSBValue::IsLLDBVariable() const {
496   return (GetName().at(0) == '$');
497 }