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