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:
11 #include "lldb/API/SBTypeSummary.h"
15 #include "MICmnLLDBDebugSessionInfo.h"
16 #include "MICmnLLDBUtilSBValue.h"
17 #include "MICmnMIValueConst.h"
18 #include "MICmnMIValueTuple.h"
19 #include "MIUtilString.h"
21 static const char *kUnknownValue = "??";
22 static const char *kUnresolvedCompositeValue = "{...}";
25 //------------------------------------------------------------------------------------
26 // Details: CMICmnLLDBUtilSBValue constructor.
28 // Args: vrValue - (R) The LLDB value object.
29 // vbHandleCharType - (R) True = Yes return text molding to char
31 // False = just return data.
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();
45 //------------------------------------------------------------------------------------
46 // Details: CMICmnLLDBUtilSBValue destructor.
52 CMICmnLLDBUtilSBValue::~CMICmnLLDBUtilSBValue() {}
55 //------------------------------------------------------------------------------------
56 // Details: Retrieve from the LLDB SB Value object the name of the variable. If
58 // is invalid (or the SBValue object invalid) then "??" is returned.
61 // Return: CMIUtilString - Name of the variable or "??" for unknown.
64 CMIUtilString CMICmnLLDBUtilSBValue::GetName() const {
65 const char *pName = m_bValidSBValue ? m_rValue.GetName() : nullptr;
66 const CMIUtilString text((pName != nullptr) ? pName : CMIUtilString());
72 //------------------------------------------------------------------------------------
73 // Details: Retrieve from the LLDB SB Value object the value of the variable
75 // text. If the value is invalid (or the SBValue object invalid) then
80 // Return: CMIUtilString - Text description of the variable's value or "??".
83 CMIUtilString CMICmnLLDBUtilSBValue::GetValue(
84 const bool vbExpandAggregates /* = false */) const {
88 CMICmnLLDBDebugSessionInfo &rSessionInfo(
89 CMICmnLLDBDebugSessionInfo::Instance());
90 bool bPrintExpandAggregates = false;
91 bPrintExpandAggregates = rSessionInfo.SharedDataRetrieve<bool>(
92 rSessionInfo.m_constStrPrintExpandAggregates,
93 bPrintExpandAggregates) &&
94 bPrintExpandAggregates;
96 const bool bHandleArrayTypeAsSimple =
97 m_bHandleArrayType && !vbExpandAggregates && !bPrintExpandAggregates;
99 const bool bIsSimpleValue = GetSimpleValue(bHandleArrayTypeAsSimple, value);
103 if (!vbExpandAggregates && !bPrintExpandAggregates)
104 return kUnresolvedCompositeValue;
106 bool bPrintAggregateFieldNames = false;
107 bPrintAggregateFieldNames =
108 !rSessionInfo.SharedDataRetrieve<bool>(
109 rSessionInfo.m_constStrPrintAggregateFieldNames,
110 bPrintAggregateFieldNames) ||
111 bPrintAggregateFieldNames;
113 CMICmnMIValueTuple miValueTuple;
114 const bool bOk = GetCompositeValue(bPrintAggregateFieldNames, miValueTuple);
116 return kUnknownValue;
118 value = miValueTuple.GetString();
123 //------------------------------------------------------------------------------------
124 // Details: Retrieve from the LLDB SB Value object the value of the variable
126 // text if it has a simple format (not composite).
128 // Args: vwrValue - (W) The SBValue in a string format.
129 // Return: MIstatus::success - Function succeeded.
130 // MIstatus::failure - Function failed.
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()) {
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;
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;
167 // Composite variable type i.e. struct
168 return MIstatus::failure;
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,
180 const bool bHandleArrayTypeAsSimple = false;
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);
192 // Can't obtain composite type
193 value = kUnknownValue;
195 // OK. Value is composite and was successfully got
196 value = miValueTuple.GetString();
198 // Need to get value from composite type, but vnMaxDepth is reached
199 value = kUnresolvedCompositeValue;
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);
209 const bool bUseSpacing = false;
210 vwrMiValueTuple.Add(miValueConst, bUseSpacing);
214 return MIstatus::success;
217 // Returns value or value + summary, depending on valueOnly parameter value.
218 // If result is an empty string returns failVal.
220 CMICmnLLDBUtilSBValue::GetValueSummary(bool valueOnly,
221 const CMIUtilString &failVal) const {
222 if (!m_rValue.IsValid())
225 CMIUtilString value, valSummary;
226 const char *c_value = m_rValue.GetValue();
228 return c_value == nullptr ? failVal : c_value;
230 const char *c_summary = m_rValue.GetSummary();
233 else if (c_summary == nullptr)
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) &&
241 valSummary.insert(0, value + " ");
245 // no summary - return just value
250 //------------------------------------------------------------------------------------
251 // Details: Check that basic type is a char type. Char type can be signed or
254 // Args: eType - type to check
255 // Return: bool - True = Yes is a char type, false = some other type.
258 bool CMICmnLLDBUtilSBValue::IsCharBasicType(lldb::BasicType eType) {
260 case lldb::eBasicTypeChar:
261 case lldb::eBasicTypeSignedChar:
262 case lldb::eBasicTypeUnsignedChar:
263 case lldb::eBasicTypeChar16:
264 case lldb::eBasicTypeChar32:
272 //------------------------------------------------------------------------------------
273 // Details: Retrieve the flag stating whether this value object is a char type
275 // other type. Char type can be signed or unsigned.
278 // Return: bool - True = Yes is a char type, false = some other type.
281 bool CMICmnLLDBUtilSBValue::IsCharType() const {
282 const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
283 return IsCharBasicType(eType);
287 //------------------------------------------------------------------------------------
288 // Details: Retrieve the flag stating whether first child value object of *this
290 // a char type or some other type. Returns false if there are not
292 // type can be signed or unsigned.
295 // Return: bool - True = Yes is a char type, false = some other type.
298 bool CMICmnLLDBUtilSBValue::IsFirstChildCharType() const {
299 const MIuint nChildren = m_rValue.GetNumChildren();
301 // Is it a basic type
305 const lldb::SBValue member = m_rValue.GetChildAtIndex(0);
306 const CMICmnLLDBUtilSBValue utilValue(member);
307 return utilValue.IsCharType();
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
315 // type can be signed or unsigned.
318 // Return: bool - True = Yes is a char type, false = some other type.
321 bool CMICmnLLDBUtilSBValue::IsPointeeCharType() const {
322 const MIuint nChildren = m_rValue.GetNumChildren();
324 // Is it a basic type
328 const lldb::BasicType eType =
329 m_rValue.GetType().GetPointeeType().GetBasicType();
330 return IsCharBasicType(eType);
334 //------------------------------------------------------------------------------------
335 // Details: Retrieve the flag stating whether this value object is a integer
337 // other type. Char type can be signed or unsigned and short or
341 // Return: bool - True = Yes is a integer type, false = some other type.
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));
359 //------------------------------------------------------------------------------------
360 // Details: Retrieve the flag stating whether this value object is a pointer
365 // Return: bool - True = Yes is a pointer type, false = some other type.
368 bool CMICmnLLDBUtilSBValue::IsPointerType() const {
369 return m_rValue.GetType().IsPointerType();
373 //------------------------------------------------------------------------------------
374 // Details: Retrieve the flag stating whether this value object is an array type
379 // Return: bool - True = Yes is an array type, false = some other type.
382 bool CMICmnLLDBUtilSBValue::IsArrayType() const {
383 return m_rValue.GetType().IsArrayType();
387 //------------------------------------------------------------------------------------
388 // Details: Retrieve the C string data of value object by read the memory where
392 // Args: vrValue - (R) LLDB SBValue variable object.
393 // Return: CMIUtilString - Text description of the variable's value.
396 template <typename charT>
398 CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(lldb::SBValue &vrValue,
399 const MIuint vnMaxLen) const {
401 lldb::addr_t addr = vrValue.GetLoadAddress(),
402 end_addr = addr + vnMaxLen * sizeof(charT);
403 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
405 while (addr < end_addr) {
407 const MIuint64 nReadBytes =
408 process.ReadMemory(addr, &ch, sizeof(ch), error);
409 if (error.Fail() || nReadBytes != sizeof(ch))
410 return kUnknownValue;
414 CMIUtilString::ConvertToPrintableASCII(ch, true /* bEscapeQuotes */));
422 //------------------------------------------------------------------------------------
423 // Details: Retrieve the state of the value object's name.
426 // Return: bool - True = yes name is indeterminate, false = name is valid.
429 bool CMICmnLLDBUtilSBValue::IsNameUnknown() const {
430 const CMIUtilString name(GetName());
431 return (name == kUnknownValue);
435 //------------------------------------------------------------------------------------
436 // Details: Retrieve the state of the value object's value data.
439 // Return: bool - True = yes value is indeterminate, false = value valid.
442 bool CMICmnLLDBUtilSBValue::IsValueUnknown() const {
443 const CMIUtilString value(GetValue());
444 return (value == kUnknownValue);
448 //------------------------------------------------------------------------------------
449 // Details: Retrieve the value object's type name if valid.
452 // Return: CMIUtilString - The type name or "??".
455 CMIUtilString CMICmnLLDBUtilSBValue::GetTypeName() const {
456 const char *pName = m_bValidSBValue ? m_rValue.GetTypeName() : nullptr;
457 const CMIUtilString text((pName != nullptr) ? pName : kUnknownValue);
463 //------------------------------------------------------------------------------------
464 // Details: Retrieve the value object's display type name if valid.
467 // Return: CMIUtilString - The type name or "??".
470 CMIUtilString CMICmnLLDBUtilSBValue::GetTypeNameDisplay() const {
471 const char *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
472 const CMIUtilString text((pName != nullptr) ? pName : kUnknownValue);
478 //------------------------------------------------------------------------------------
479 // Details: Retrieve whether the value object's is valid or not.
482 // Return: bool - True = valid, false = not valid.
485 bool CMICmnLLDBUtilSBValue::IsValid() const { return m_bValidSBValue; }
488 //------------------------------------------------------------------------------------
489 // Details: Retrieve the value object' has a name. A value object can be valid
491 // have no name which suggest it is not a variable.
494 // Return: bool - True = valid, false = not valid.
497 bool CMICmnLLDBUtilSBValue::HasName() const {
498 bool bHasAName = false;
500 const char *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
501 if (pName != nullptr) {
502 bHasAName = (CMIUtilString(pName).length() > 0);
509 //------------------------------------------------------------------------------------
510 // Details: Determine if the value object' represents a LLDB variable i.e. "$0".
513 // Return: bool - True = Yes LLDB variable, false = no.
516 bool CMICmnLLDBUtilSBValue::IsLLDBVariable() const {
517 return (GetName().at(0) == '$');