1 //===-- MICmnLLDBUtilSBValue.cpp --------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Third party headers:
14 #include "MICmnLLDBUtilSBValue.h"
15 #include "MICmnLLDBDebugSessionInfo.h"
16 #include "MICmnMIValueConst.h"
17 #include "MICmnMIValueTuple.h"
18 #include "MIUtilString.h"
20 //++ ------------------------------------------------------------------------------------
21 // Details: CMICmnLLDBUtilSBValue constructor.
23 // Args: vrValue - (R) The LLDB value object.
24 // vbHandleCharType - (R) True = Yes return text molding to char type,
25 // False = just return data.
29 CMICmnLLDBUtilSBValue::CMICmnLLDBUtilSBValue(const lldb::SBValue &vrValue, const bool vbHandleCharType /* = false */,
30 const bool vbHandleArrayType /* = true */)
31 : m_rValue(const_cast<lldb::SBValue &>(vrValue))
33 , m_pComposite("{...}")
34 , m_bHandleCharType(vbHandleCharType)
35 , m_bHandleArrayType(vbHandleArrayType)
37 m_bValidSBValue = m_rValue.IsValid();
40 //++ ------------------------------------------------------------------------------------
41 // Details: CMICmnLLDBUtilSBValue destructor.
47 CMICmnLLDBUtilSBValue::~CMICmnLLDBUtilSBValue(void)
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.
56 // Return: CMIUtilString - Name of the variable or "??" for unknown.
60 CMICmnLLDBUtilSBValue::GetName(void) const
62 const char *pName = m_bValidSBValue ? m_rValue.GetName() : nullptr;
63 const CMIUtilString text((pName != nullptr) ? pName : m_pUnkwn);
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
74 // Return: CMIUtilString - Text description of the variable's value or "??".
78 CMICmnLLDBUtilSBValue::GetValue(const bool vbExpandAggregates /* = false */) const
83 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
84 bool bPrintExpandAggregates = false;
85 bPrintExpandAggregates = rSessionInfo.SharedDataRetrieve<bool>(rSessionInfo.m_constStrPrintExpandAggregates,
86 bPrintExpandAggregates) && bPrintExpandAggregates;
88 const bool bHandleArrayTypeAsSimple = m_bHandleArrayType && !vbExpandAggregates && !bPrintExpandAggregates;
90 const bool bIsSimpleValue = GetSimpleValue(bHandleArrayTypeAsSimple, value);
94 if (!vbExpandAggregates && !bPrintExpandAggregates)
97 bool bPrintAggregateFieldNames = false;
98 bPrintAggregateFieldNames = !rSessionInfo.SharedDataRetrieve<bool>(rSessionInfo.m_constStrPrintAggregateFieldNames,
99 bPrintAggregateFieldNames) || bPrintAggregateFieldNames;
101 CMICmnMIValueTuple miValueTuple;
102 const bool bOk = GetCompositeValue(bPrintAggregateFieldNames, miValueTuple);
106 value = miValueTuple.GetString();
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).
114 // Args: vwrValue - (W) The SBValue in a string format.
115 // Return: MIstatus::success - Function succeeded.
116 // MIstatus::failure - Function failed.
120 CMICmnLLDBUtilSBValue::GetSimpleValue(const bool vbHandleArrayType, CMIUtilString &vwrValue) const
122 const MIuint nChildren = m_rValue.GetNumChildren();
125 if (m_bHandleCharType && IsCharType())
127 vwrValue = GetSimpleValueChar();
128 return MIstatus::success;
132 const char *pValue = m_rValue.GetValue();
133 vwrValue = pValue != nullptr ? pValue : m_pUnkwn;
134 return MIstatus::success;
137 else if (IsPointerType())
139 if (m_bHandleCharType && IsFirstChildCharType())
141 vwrValue = GetSimpleValueCStringPointer();
142 return MIstatus::success;
146 const char *pValue = m_rValue.GetValue();
147 vwrValue = pValue != nullptr ? pValue : m_pUnkwn;
148 return MIstatus::success;
151 else if (IsArrayType())
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())
159 vwrValue = GetSimpleValueCStringArray();
160 return MIstatus::success;
162 else if (vbHandleArrayType)
164 vwrValue = CMIUtilString::Format("[%u]", nChildren);
165 return MIstatus::success;
169 // Composite variable type i.e. struct
170 return MIstatus::failure;
173 //++ ------------------------------------------------------------------------------------
174 // Details: Retrieve from the LLDB SB Value object the char value of the variable.
177 // Return: CMIUtilString - The char value of the variable.
181 CMICmnLLDBUtilSBValue::GetSimpleValueChar(void) const
183 const uint64_t value = m_rValue.GetValueAsUnsigned();
186 const uint64_t nFailValue = 1;
187 if (nFailValue == m_rValue.GetValueAsUnsigned(nFailValue))
191 const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
195 assert(0 && "value must be a char type");
196 case lldb::eBasicTypeChar:
197 case lldb::eBasicTypeSignedChar:
198 case lldb::eBasicTypeUnsignedChar:
200 const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char)value));
201 return CMIUtilString::Format("%" PRIu8 " '%s'", (uint8_t)value, prefix.c_str());
203 case lldb::eBasicTypeChar16:
205 const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char16_t)value));
206 return CMIUtilString::Format("U+%04" PRIx16 " u'%s'", (uint16_t)value, prefix.c_str());
208 case lldb::eBasicTypeChar32:
210 const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char32_t)value));
211 return CMIUtilString::Format("U+%08" PRIx32 " U'%s'", (uint32_t)value, prefix.c_str());
216 //++ ------------------------------------------------------------------------------------
217 // Details: Retrieve from the LLDB SB Value object of type char* the c-string value.
220 // Return: CMIUtilString - The c-string value of the variable.
224 CMICmnLLDBUtilSBValue::GetSimpleValueCStringPointer(void) const
226 const char *value = m_rValue.GetValue();
227 if (value == nullptr)
230 lldb::SBValue child = m_rValue.GetChildAtIndex(0);
231 const lldb::BasicType eType = child.GetType().GetBasicType();
235 assert(0 && "child must be a char type");
236 case lldb::eBasicTypeChar:
237 case lldb::eBasicTypeSignedChar:
238 case lldb::eBasicTypeUnsignedChar:
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());
247 case lldb::eBasicTypeChar16:
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());
253 case lldb::eBasicTypeChar32:
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());
262 //++ ------------------------------------------------------------------------------------
263 // Details: Retrieve from the LLDB SB Value object of type char[] the c-string value.
266 // Return: CMIUtilString - The c-string value of the variable.
270 CMICmnLLDBUtilSBValue::GetSimpleValueCStringArray(void) const
272 const MIuint nChildren = m_rValue.GetNumChildren();
273 lldb::SBValue child = m_rValue.GetChildAtIndex(0);
274 const lldb::BasicType eType = child.GetType().GetBasicType();
278 assert(0 && "value must be a char[] type");
279 case lldb::eBasicTypeChar:
280 case lldb::eBasicTypeSignedChar:
281 case lldb::eBasicTypeUnsignedChar:
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());
289 case lldb::eBasicTypeChar16:
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());
295 case lldb::eBasicTypeChar32:
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());
305 CMICmnLLDBUtilSBValue::GetCompositeValue(const bool vbPrintFieldNames, CMICmnMIValueTuple &vwrMiValueTuple,
306 const MIuint vnDepth /* = 1 */) const
308 const MIuint nMaxDepth = 10;
309 const MIuint nChildren = m_rValue.GetNumChildren();
310 for (MIuint i = 0; i < nChildren; ++i)
312 const lldb::SBValue member = m_rValue.GetChildAtIndex(i);
313 const CMICmnLLDBUtilSBValue utilMember(member, m_bHandleCharType, m_bHandleArrayType);
314 const bool bHandleArrayTypeAsSimple = false;
316 const bool bIsSimpleValue = utilMember.GetSimpleValue(bHandleArrayTypeAsSimple, value);
319 // OK. Value is simple (not composite) and was successfully got
321 else if (vnDepth < nMaxDepth)
323 // Need to get value from composite type
324 CMICmnMIValueTuple miValueTuple;
325 const bool bOk = utilMember.GetCompositeValue(vbPrintFieldNames, miValueTuple, vnDepth + 1);
327 // Can't obtain composite type
330 // OK. Value is composite and was successfully got
331 value = miValueTuple.GetString();
335 // Need to get value from composite type, but vnMaxDepth is reached
336 value = m_pComposite;
338 const bool bNoQuotes = true;
339 const CMICmnMIValueConst miValueConst(value, bNoQuotes);
340 if (vbPrintFieldNames)
342 const bool bUseSpacing = true;
343 const CMICmnMIValueResult miValueResult(utilMember.GetName(), miValueConst, bUseSpacing);
344 const bool bOk = vwrMiValueTuple.Add(miValueResult, bUseSpacing);
346 return MIstatus::failure;
350 const bool bUseSpacing = false;
351 const bool bOk = vwrMiValueTuple.Add(miValueConst, bUseSpacing);
353 return MIstatus::failure;
357 return MIstatus::success;
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.
365 // Return: bool - True = Yes is a char type, false = some other type.
369 CMICmnLLDBUtilSBValue::IsCharType(void) const
371 const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
374 case lldb::eBasicTypeChar:
375 case lldb::eBasicTypeSignedChar:
376 case lldb::eBasicTypeUnsignedChar:
377 case lldb::eBasicTypeChar16:
378 case lldb::eBasicTypeChar32:
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.
391 // Return: bool - True = Yes is a char type, false = some other type.
395 CMICmnLLDBUtilSBValue::IsFirstChildCharType(void) const
397 const MIuint nChildren = m_rValue.GetNumChildren();
399 // Is it a basic type
403 const lldb::SBValue member = m_rValue.GetChildAtIndex(0);
404 const CMICmnLLDBUtilSBValue utilValue(member);
405 return utilValue.IsCharType();
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.
413 // Return: bool - True = Yes is a integer type, false = some other type.
417 CMICmnLLDBUtilSBValue::IsIntegerType(void) const
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));
427 //++ ------------------------------------------------------------------------------------
428 // Details: Retrieve the flag stating whether this value object is a pointer type or some
432 // Return: bool - True = Yes is a pointer type, false = some other type.
436 CMICmnLLDBUtilSBValue::IsPointerType(void) const
438 return m_rValue.GetType().IsPointerType();
441 //++ ------------------------------------------------------------------------------------
442 // Details: Retrieve the flag stating whether this value object is an array type or some
446 // Return: bool - True = Yes is an array type, false = some other type.
450 CMICmnLLDBUtilSBValue::IsArrayType(void) const
452 return m_rValue.GetType().IsArrayType();
455 //++ ------------------------------------------------------------------------------------
456 // Details: Retrieve the C string data of value object by read the memory where the
459 // Args: vrValue - (R) LLDB SBValue variable object.
460 // Return: CMIUtilString - Text description of the variable's value.
463 template <typename charT>
465 CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(lldb::SBValue &vrValue, const MIuint vnMaxLen) const
468 lldb::addr_t addr = vrValue.GetLoadAddress(), end_addr = addr + vnMaxLen * sizeof(charT);
469 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
471 while (addr < end_addr)
474 const MIuint64 nReadBytes = process.ReadMemory(addr, &ch, sizeof(ch), error);
475 if (error.Fail() || nReadBytes != sizeof(ch))
479 result.append(CMIUtilString::ConvertToPrintableASCII(ch));
483 return result.c_str();
486 //++ ------------------------------------------------------------------------------------
487 // Details: Retrieve the state of the value object's name.
490 // Return: bool - True = yes name is indeterminate, false = name is valid.
494 CMICmnLLDBUtilSBValue::IsNameUnknown(void) const
496 const CMIUtilString name(GetName());
497 return (name == m_pUnkwn);
500 //++ ------------------------------------------------------------------------------------
501 // Details: Retrieve the state of the value object's value data.
504 // Return: bool - True = yes value is indeterminate, false = value valid.
508 CMICmnLLDBUtilSBValue::IsValueUnknown(void) const
510 const CMIUtilString value(GetValue());
511 return (value == m_pUnkwn);
514 //++ ------------------------------------------------------------------------------------
515 // Details: Retrieve the value object's type name if valid.
518 // Return: CMIUtilString - The type name or "??".
522 CMICmnLLDBUtilSBValue::GetTypeName(void) const
524 const char *pName = m_bValidSBValue ? m_rValue.GetTypeName() : nullptr;
525 const CMIUtilString text((pName != nullptr) ? pName : m_pUnkwn);
530 //++ ------------------------------------------------------------------------------------
531 // Details: Retrieve the value object's display type name if valid.
534 // Return: CMIUtilString - The type name or "??".
538 CMICmnLLDBUtilSBValue::GetTypeNameDisplay(void) const
540 const char *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
541 const CMIUtilString text((pName != nullptr) ? pName : m_pUnkwn);
546 //++ ------------------------------------------------------------------------------------
547 // Details: Retrieve whether the value object's is valid or not.
550 // Return: bool - True = valid, false = not valid.
554 CMICmnLLDBUtilSBValue::IsValid(void) const
556 return m_bValidSBValue;
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.
564 // Return: bool - True = valid, false = not valid.
568 CMICmnLLDBUtilSBValue::HasName(void) const
570 bool bHasAName = false;
572 const char *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
573 if (pName != nullptr)
575 bHasAName = (CMIUtilString(pName).length() > 0);
581 //++ ------------------------------------------------------------------------------------
582 // Details: Determine if the value object' represents a LLDB variable i.e. "$0".
585 // Return: bool - True = Yes LLDB variable, false = no.
589 CMICmnLLDBUtilSBValue::IsLLDBVariable(void) const
591 return (GetName().at(0) == '$');