1 //===-- MICmnLLDBDebugSessionInfoVarObj.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 // In-house headers:
11 #include "MICmnLLDBDebugSessionInfoVarObj.h"
12 #include "MICmnLLDBProxySBValue.h"
13 #include "MICmnLLDBUtilSBValue.h"
14 
15 // Instantiations:
16 const char *CMICmnLLDBDebugSessionInfoVarObj::ms_aVarFormatStrings[] = {
17     // CODETAG_SESSIONINFO_VARFORMAT_ENUM
18     // *** Order is import here.
19     "<Invalid var format>", "binary", "octal", "decimal", "hexadecimal", "natural"};
20 const char *CMICmnLLDBDebugSessionInfoVarObj::ms_aVarFormatChars[] = {
21     // CODETAG_SESSIONINFO_VARFORMAT_ENUM
22     // *** Order is import here.
23     "<Invalid var format>", "t", "o", "d", "x", "N"};
24 CMICmnLLDBDebugSessionInfoVarObj::MapKeyToVarObj_t CMICmnLLDBDebugSessionInfoVarObj::ms_mapVarIdToVarObj;
25 MIuint CMICmnLLDBDebugSessionInfoVarObj::ms_nVarUniqueId = 0; // Index from 0
26 CMICmnLLDBDebugSessionInfoVarObj::varFormat_e CMICmnLLDBDebugSessionInfoVarObj::ms_eDefaultFormat = eVarFormat_Natural;
27 
28 //++ ------------------------------------------------------------------------------------
29 // Details: CMICmnLLDBDebugSessionInfoVarObj constructor.
30 // Type:    Method.
31 // Args:    None.
32 // Return:  None.
33 // Throws:  None.
34 //--
35 CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj()
36     : m_eVarFormat(eVarFormat_Natural)
37     , m_eVarType(eVarType_Internal)
38 {
39     // Do not call UpdateValue() in here as not necessary
40 }
41 
42 //++ ------------------------------------------------------------------------------------
43 // Details: CMICmnLLDBDebugSessionInfoVarObj constructor.
44 // Type:    Method.
45 // Args:    vrStrNameReal   - (R) The actual name of the variable, the expression.
46 //          vrStrName       - (R) The name given for *this var object.
47 //          vrValue         - (R) The LLDB SBValue object represented by *this object.
48 // Return:  None.
49 // Throws:  None.
50 //--
51 CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj(const CMIUtilString &vrStrNameReal, const CMIUtilString &vrStrName,
52                                                                    const lldb::SBValue &vrValue)
53     : m_eVarFormat(eVarFormat_Natural)
54     , m_eVarType(eVarType_Internal)
55     , m_strName(vrStrName)
56     , m_SBValue(vrValue)
57     , m_strNameReal(vrStrNameReal)
58 {
59     UpdateValue();
60 }
61 
62 //++ ------------------------------------------------------------------------------------
63 // Details: CMICmnLLDBDebugSessionInfoVarObj constructor.
64 // Type:    Method.
65 // Args:    vrStrNameReal           - (R) The actual name of the variable, the expression.
66 //          vrStrName               - (R) The name given for *this var object.
67 //          vrValue                 - (R) The LLDB SBValue object represented by *this object.
68 //          vrStrVarObjParentName   - (R) The var object parent to *this var object (LLDB SBValue equivalent).
69 // Return:  None.
70 // Throws:  None.
71 //--
72 CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj(const CMIUtilString &vrStrNameReal, const CMIUtilString &vrStrName,
73                                                                    const lldb::SBValue &vrValue, const CMIUtilString &vrStrVarObjParentName)
74     : m_eVarFormat(eVarFormat_Natural)
75     , m_eVarType(eVarType_Internal)
76     , m_strName(vrStrName)
77     , m_SBValue(vrValue)
78     , m_strNameReal(vrStrNameReal)
79     , m_strVarObjParentName(vrStrVarObjParentName)
80 {
81     UpdateValue();
82 }
83 
84 //++ ------------------------------------------------------------------------------------
85 // Details: CMICmnLLDBDebugSessionInfoVarObj copy constructor.
86 // Type:    Method.
87 // Args:    vrOther - (R) The object to copy from.
88 // Return:  None.
89 // Throws:  None.
90 //--
91 CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj(const CMICmnLLDBDebugSessionInfoVarObj &vrOther)
92 {
93     CopyOther(vrOther);
94 }
95 
96 //++ ------------------------------------------------------------------------------------
97 // Details: CMICmnLLDBDebugSessionInfoVarObj copy constructor.
98 // Type:    Method.
99 // Args:    vrOther - (R) The object to copy from.
100 // Return:  None.
101 // Throws:  None.
102 //--
103 CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj(CMICmnLLDBDebugSessionInfoVarObj &vrOther)
104 {
105     CopyOther(vrOther);
106 }
107 
108 //++ ------------------------------------------------------------------------------------
109 // Details: CMICmnLLDBDebugSessionInfoVarObj move constructor.
110 // Type:    Method.
111 // Args:    vrwOther    - (R) The object to copy from.
112 // Return:  None.
113 // Throws:  None.
114 //--
115 CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj(CMICmnLLDBDebugSessionInfoVarObj &&vrwOther)
116 {
117     MoveOther(vrwOther);
118 }
119 
120 //++ ------------------------------------------------------------------------------------
121 // Details: CMICmnLLDBDebugSessionInfoVarObj assignment operator.
122 // Type:    Method.
123 // Args:    vrOther - (R) The object to copy from.
124 // Return:  CMICmnLLDBDebugSessionInfoVarObj & - Updated *this object.
125 // Throws:  None.
126 //--
127 CMICmnLLDBDebugSessionInfoVarObj &CMICmnLLDBDebugSessionInfoVarObj::operator=(const CMICmnLLDBDebugSessionInfoVarObj &vrOther)
128 {
129     CopyOther(vrOther);
130 
131     return *this;
132 }
133 
134 //++ ------------------------------------------------------------------------------------
135 // Details: CMICmnLLDBDebugSessionInfoVarObj assignment operator.
136 // Type:    Method.
137 // Args:    vrwOther    - (R) The object to copy from.
138 // Return:  CMICmnLLDBDebugSessionInfoVarObj & - Updated *this object.
139 // Throws:  None.
140 //--
141 CMICmnLLDBDebugSessionInfoVarObj &CMICmnLLDBDebugSessionInfoVarObj::operator=(CMICmnLLDBDebugSessionInfoVarObj &&vrwOther)
142 {
143     MoveOther(vrwOther);
144 
145     return *this;
146 }
147 
148 //++ ------------------------------------------------------------------------------------
149 // Details: Copy the other instance of that object to *this object.
150 // Type:    Method.
151 // Args:    vrOther - (R) The object to copy from.
152 // Return:  MIstatus::success - Functional succeeded.
153 //          MIstatus::failure - Functional failed.
154 // Throws:  None.
155 //--
156 bool
157 CMICmnLLDBDebugSessionInfoVarObj::CopyOther(const CMICmnLLDBDebugSessionInfoVarObj &vrOther)
158 {
159     // Check for self-assignment
160     if (this == &vrOther)
161         return MIstatus::success;
162 
163     m_eVarFormat = vrOther.m_eVarFormat;
164     m_eVarType = vrOther.m_eVarType;
165     m_strName = vrOther.m_strName;
166     m_SBValue = vrOther.m_SBValue;
167     m_strNameReal = vrOther.m_strNameReal;
168     m_strFormattedValue = vrOther.m_strFormattedValue;
169     m_strVarObjParentName = vrOther.m_strVarObjParentName;
170 
171     return MIstatus::success;
172 }
173 
174 //++ ------------------------------------------------------------------------------------
175 // Details: Move that object to *this object.
176 // Type:    Method.
177 // Args:    vrwOther    - (RW) The object to copy from.
178 // Return:  MIstatus::success - Functional succeeded.
179 //          MIstatus::failure - Functional failed.
180 // Throws:  None.
181 //--
182 bool
183 CMICmnLLDBDebugSessionInfoVarObj::MoveOther(CMICmnLLDBDebugSessionInfoVarObj &vrwOther)
184 {
185     // Check for self-assignment
186     if (this == &vrwOther)
187         return MIstatus::success;
188 
189     CopyOther(vrwOther);
190     vrwOther.m_eVarFormat = eVarFormat_Natural;
191     vrwOther.m_eVarType = eVarType_Internal;
192     vrwOther.m_strName.clear();
193     vrwOther.m_SBValue.Clear();
194     vrwOther.m_strNameReal.clear();
195     vrwOther.m_strFormattedValue.clear();
196     vrwOther.m_strVarObjParentName.clear();
197 
198     return MIstatus::success;
199 }
200 
201 //++ ------------------------------------------------------------------------------------
202 // Details: CMICmnLLDBDebugSessionInfoVarObj destructor.
203 // Type:    Overridden.
204 // Args:    None.
205 // Return:  None.
206 // Throws:  None.
207 //--
208 CMICmnLLDBDebugSessionInfoVarObj::~CMICmnLLDBDebugSessionInfoVarObj()
209 {
210 }
211 
212 //++ ------------------------------------------------------------------------------------
213 // Details: Retrieve the var format enumeration for the specified string.
214 // Type:    Static method.
215 // Args:    vrStrFormat - (R) Text description of the var format.
216 // Return:  varFormat_e - Var format enumeration.
217 //                      - No match found return eVarFormat_Invalid.
218 // Throws:  None.
219 //--
220 CMICmnLLDBDebugSessionInfoVarObj::varFormat_e
221 CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString(const CMIUtilString &vrStrFormat)
222 {
223     // CODETAG_SESSIONINFO_VARFORMAT_ENUM
224     for (MIuint i = 0; i < eVarFormat_count; i++)
225     {
226         const char *pVarFormatString = ms_aVarFormatStrings[i];
227         if (vrStrFormat == pVarFormatString)
228             return static_cast<varFormat_e>(i);
229     }
230 
231     return eVarFormat_Invalid;
232 }
233 
234 //++ ------------------------------------------------------------------------------------
235 // Details: Retrieve the var format enumeration for the specified character.
236 // Type:    Static method.
237 // Args:    vcFormat    - Character representing the var format.
238 // Return:  varFormat_e - Var format enumeration.
239 //                      - No match found return eVarFormat_Invalid.
240 // Throws:  None.
241 //--
242 CMICmnLLDBDebugSessionInfoVarObj::varFormat_e
243 CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar(char vcFormat)
244 {
245     if ('r' == vcFormat)
246         return eVarFormat_Hex;
247 
248     // CODETAG_SESSIONINFO_VARFORMAT_ENUM
249     for (MIuint i = 0; i < eVarFormat_count; i++)
250     {
251         const char *pVarFormatChar = ms_aVarFormatChars[i];
252         if (*pVarFormatChar == vcFormat)
253             return static_cast<varFormat_e>(i);
254     }
255 
256     return eVarFormat_Invalid;
257 }
258 
259 //++ ------------------------------------------------------------------------------------
260 // Details: Return the equivalent var value formatted string for the given value type,
261 //          which was prepared for printing (i.e. value was escaped and now it's ready
262 //          for wrapping into quotes).
263 //          The SBValue vrValue parameter is checked by LLDB private code for valid
264 //          scalar type via MI Driver proxy function as the valued returned can also be
265 //          an error condition. The proxy function determines if the check was valid
266 //          otherwise return an error condition state by other means saying so.
267 // Type:    Static method.
268 // Args:    vrValue     - (R) The var value object.
269 //          veVarFormat - (R) Var format enumeration.
270 // Returns: CMIUtilString   - Value formatted string.
271 // Throws:  None.
272 //--
273 CMIUtilString
274 CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(const lldb::SBValue &vrValue,
275                                                           const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat)
276 {
277     const CMICmnLLDBUtilSBValue utilValue(vrValue, true);
278     if (utilValue.IsIntegerType())
279     {
280         MIuint64 nValue = 0;
281         if (CMICmnLLDBProxySBValue::GetValueAsUnsigned(vrValue, nValue))
282         {
283             lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
284             return GetStringFormatted(nValue, rValue.GetValue(), veVarFormat);
285         }
286     }
287 
288     return utilValue.GetValue().AddSlashes();
289 }
290 
291 //++ ------------------------------------------------------------------------------------
292 // Details: Return number formatted string according to the given value type.
293 // Type:    Static method.
294 // Args:    vnValue             - (R) The number value to get formatted.
295 //          vpStrValueNatural   - (R) The natural representation of the number value.
296 //          veVarFormat         - (R) Var format enumeration.
297 // Returns: CMIUtilString       - Numerical formatted string.
298 // Throws:  None.
299 //--
300 CMIUtilString
301 CMICmnLLDBDebugSessionInfoVarObj::GetStringFormatted(const MIuint64 vnValue, const char *vpStrValueNatural,
302                                                      const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat)
303 {
304     CMIUtilString strFormattedValue;
305     CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veFormat = veVarFormat;
306     if (ms_eDefaultFormat != eVarFormat_Invalid && veVarFormat == eVarFormat_Natural)
307     {
308         veFormat = ms_eDefaultFormat;
309     }
310 
311     switch (veFormat)
312     {
313         case eVarFormat_Binary:
314             strFormattedValue = CMIUtilString::FormatBinary(vnValue);
315             break;
316         case eVarFormat_Octal:
317             strFormattedValue = CMIUtilString::Format("0%llo", vnValue);
318             break;
319         case eVarFormat_Decimal:
320             strFormattedValue = CMIUtilString::Format("%lld", vnValue);
321             break;
322         case eVarFormat_Hex:
323             strFormattedValue = CMIUtilString::Format("0x%llx", vnValue);
324             break;
325         case eVarFormat_Natural:
326         default:
327         {
328             strFormattedValue = (vpStrValueNatural != nullptr) ? vpStrValueNatural : "";
329         }
330     }
331 
332     return strFormattedValue;
333 }
334 
335 //++ ------------------------------------------------------------------------------------
336 // Details: Delete internal container contents.
337 // Type:    Static method.
338 // Args:    None.
339 // Returns: None.
340 // Throws:  None.
341 //--
342 void
343 CMICmnLLDBDebugSessionInfoVarObj::VarObjClear()
344 {
345     ms_mapVarIdToVarObj.clear();
346 }
347 
348 //++ ------------------------------------------------------------------------------------
349 // Details: Add a var object to the internal container.
350 // Type:    Static method.
351 // Args:    vrVarObj    - (R) The var value object.
352 // Returns: None.
353 // Throws:  None.
354 //--
355 void
356 CMICmnLLDBDebugSessionInfoVarObj::VarObjAdd(const CMICmnLLDBDebugSessionInfoVarObj &vrVarObj)
357 {
358     VarObjDelete(vrVarObj.GetName());
359     MapPairKeyToVarObj_t pr(vrVarObj.GetName(), vrVarObj);
360     ms_mapVarIdToVarObj.insert(pr);
361 }
362 
363 //++ ------------------------------------------------------------------------------------
364 // Details: Delete the var object from the internal container matching the specified name.
365 // Type:    Static method.
366 // Args:    vrVarName   - (R) The var value name.
367 // Returns: None.
368 // Throws:  None.
369 //--
370 void
371 CMICmnLLDBDebugSessionInfoVarObj::VarObjDelete(const CMIUtilString &vrVarName)
372 {
373     const MapKeyToVarObj_t::const_iterator it = ms_mapVarIdToVarObj.find(vrVarName);
374     if (it != ms_mapVarIdToVarObj.end())
375     {
376         ms_mapVarIdToVarObj.erase(it);
377     }
378 }
379 
380 //++ ------------------------------------------------------------------------------------
381 // Details: Update an existing var object in the internal container.
382 // Type:    Static method.
383 // Args:    vrVarObj    - (R) The var value object.
384 // Returns: None.
385 // Throws:  None.
386 //--
387 void
388 CMICmnLLDBDebugSessionInfoVarObj::VarObjUpdate(const CMICmnLLDBDebugSessionInfoVarObj &vrVarObj)
389 {
390     VarObjAdd(vrVarObj);
391 }
392 
393 //++ ------------------------------------------------------------------------------------
394 // Details: Retrieve the var object matching the specified name.
395 // Type:    Static method.
396 // Args:    vrVarName   - (R) The var value name.
397 //          vrwVarObj   - (W) A var object.
398 // Returns: bool    - True = object found, false = object not found.
399 // Throws:  None.
400 //--
401 bool
402 CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(const CMIUtilString &vrVarName, CMICmnLLDBDebugSessionInfoVarObj &vrwVarObj)
403 {
404     const MapKeyToVarObj_t::const_iterator it = ms_mapVarIdToVarObj.find(vrVarName);
405     if (it != ms_mapVarIdToVarObj.end())
406     {
407         const CMICmnLLDBDebugSessionInfoVarObj &rVarObj = (*it).second;
408         vrwVarObj = rVarObj;
409         return true;
410     }
411 
412     return false;
413 }
414 
415 //++ ------------------------------------------------------------------------------------
416 // Details: A count is kept of the number of var value objects created. This is count is
417 //          used to ID the var value object. Reset the count to 0.
418 // Type:    Static method.
419 // Args:    None.
420 // Returns: None.
421 // Throws:  None.
422 //--
423 void
424 CMICmnLLDBDebugSessionInfoVarObj::VarObjIdResetToZero()
425 {
426     ms_nVarUniqueId = 0;
427 }
428 
429 //++ ------------------------------------------------------------------------------------
430 // Details: Default format is globally used as the data format when "natural" is in effect, that is, this overrides the default
431 // Type:    Static method.
432 // Args:    None.
433 // Returns: None.
434 // Throws:  None.
435 //--
436 void
437 CMICmnLLDBDebugSessionInfoVarObj::VarObjSetFormat(varFormat_e eDefaultFormat)
438 {
439     ms_eDefaultFormat = eDefaultFormat;
440 }
441 
442 
443 //++ ------------------------------------------------------------------------------------
444 // Details: A count is kept of the number of var value objects created. This is count is
445 //          used to ID the var value object. Increment the count by 1.
446 // Type:    Static method.
447 // Args:    None.
448 // Returns: None.
449 // Throws:  None.
450 //--
451 void
452 CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc()
453 {
454     ms_nVarUniqueId++;
455 }
456 
457 //++ ------------------------------------------------------------------------------------
458 // Details: A count is kept of the number of var value objects created. This is count is
459 //          used to ID the var value object. Retrieve ID.
460 // Type:    Static method.
461 // Args:    None.
462 // Returns: None.
463 // Throws:  None.
464 //--
465 MIuint
466 CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet()
467 {
468     return ms_nVarUniqueId;
469 }
470 
471 //++ ------------------------------------------------------------------------------------
472 // Details: Retrieve the value formatted object's name.
473 // Type:    Method.
474 // Args:    None.
475 // Returns: CMIUtilString & - Value's var%u name text.
476 // Throws:  None.
477 //--
478 const CMIUtilString &
479 CMICmnLLDBDebugSessionInfoVarObj::GetName() const
480 {
481     return m_strName;
482 }
483 
484 //++ ------------------------------------------------------------------------------------
485 // Details: Retrieve the value formatted object's variable name as given in the MI command
486 //          to create the var object.
487 // Type:    Method.
488 // Args:    None.
489 // Returns: CMIUtilString & - Value's real name text.
490 // Throws:  None.
491 //--
492 const CMIUtilString &
493 CMICmnLLDBDebugSessionInfoVarObj::GetNameReal() const
494 {
495     return m_strNameReal;
496 }
497 
498 //++ ------------------------------------------------------------------------------------
499 // Details: Retrieve the value formatted string.
500 // Type:    Method.
501 // Args:    None.
502 // Returns: CMIUtilString & - Value formatted string.
503 // Throws:  None.
504 //--
505 const CMIUtilString &
506 CMICmnLLDBDebugSessionInfoVarObj::GetValueFormatted() const
507 {
508     return m_strFormattedValue;
509 }
510 
511 //++ ------------------------------------------------------------------------------------
512 // Details: Retrieve the LLDB Value object.
513 // Type:    Method.
514 // Args:    None.
515 // Returns: lldb::SBValue & - LLDB Value object.
516 // Throws:  None.
517 //--
518 lldb::SBValue &
519 CMICmnLLDBDebugSessionInfoVarObj::GetValue()
520 {
521     return m_SBValue;
522 }
523 
524 //++ ------------------------------------------------------------------------------------
525 // Details: Retrieve the LLDB Value object.
526 // Type:    Method.
527 // Args:    None.
528 // Returns: lldb::SBValue & - Constant LLDB Value object.
529 // Throws:  None.
530 //--
531 const lldb::SBValue &
532 CMICmnLLDBDebugSessionInfoVarObj::GetValue() const
533 {
534     return m_SBValue;
535 }
536 
537 //++ ------------------------------------------------------------------------------------
538 // Details: Set the var format type for *this object and update the formatting.
539 // Type:    Method.
540 // Args:    None.
541 // Return:  MIstatus::success - Functional succeeded.
542 //          MIstatus::failure - Functional failed.
543 // Throws:  None.
544 //--
545 bool
546 CMICmnLLDBDebugSessionInfoVarObj::SetVarFormat(const varFormat_e veVarFormat)
547 {
548     if (veVarFormat >= eVarFormat_count)
549         return MIstatus::failure;
550 
551     m_eVarFormat = veVarFormat;
552     UpdateValue();
553     return MIstatus::success;
554 }
555 
556 //++ ------------------------------------------------------------------------------------
557 // Details: Update *this var obj. Update it's value and type.
558 // Type:    Method.
559 // Args:    None.
560 // Returns: None.
561 // Throws:  None.
562 //--
563 void
564 CMICmnLLDBDebugSessionInfoVarObj::UpdateValue()
565 {
566     m_strFormattedValue = GetValueStringFormatted(m_SBValue, m_eVarFormat);
567 
568     MIuint64 nValue = 0;
569     if (CMICmnLLDBProxySBValue::GetValueAsUnsigned(m_SBValue, nValue) == MIstatus::failure)
570         m_eVarType = eVarType_Composite;
571 
572     CMICmnLLDBDebugSessionInfoVarObj::VarObjUpdate(*this);
573 }
574 
575 //++ ------------------------------------------------------------------------------------
576 // Details: Retrieve the enumeration type of the var object.
577 // Type:    Method.
578 // Args:    None.
579 // Returns: varType_e   - Enumeration value.
580 // Throws:  None.
581 //--
582 CMICmnLLDBDebugSessionInfoVarObj::varType_e
583 CMICmnLLDBDebugSessionInfoVarObj::GetType() const
584 {
585     return m_eVarType;
586 }
587 
588 //++ ------------------------------------------------------------------------------------
589 // Details: Retrieve the parent var object's name, the parent var object  to *this var
590 //          object (if assigned). The parent is equivalent to LLDB SBValue variable's
591 //          parent.
592 // Type:    Method.
593 // Args:    None.
594 // Returns: CMIUtilString & - Pointer to var object, NULL = no parent.
595 // Throws:  None.
596 //--
597 const CMIUtilString &
598 CMICmnLLDBDebugSessionInfoVarObj::GetVarParentName() const
599 {
600     return m_strVarObjParentName;
601 }
602