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