]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/tools/lldb-mi/MICmdCmdVar.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / tools / lldb-mi / MICmdCmdVar.cpp
1 //===-- MICmdCmdVar.cpp -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // Overview:    CMICmdCmdVarCreate                  implementation.
10 //              CMICmdCmdVarUpdate                  implementation.
11 //              CMICmdCmdVarDelete                  implementation.
12 //              CMICmdCmdVarAssign                  implementation.
13 //              CMICmdCmdVarSetFormat               implementation.
14 //              CMICmdCmdVarListChildren            implementation.
15 //              CMICmdCmdVarEvaluateExpression      implementation.
16 //              CMICmdCmdVarInfoPathExpression      implementation.
17 //              CMICmdCmdVarShowAttributes          implementation.
18
19 // Third Party Headers:
20 #include "lldb/API/SBStream.h"
21 #include "lldb/API/SBThread.h"
22 #include "lldb/API/SBType.h"
23
24 // In-house headers:
25 #include "MICmdArgValListOfN.h"
26 #include "MICmdArgValNumber.h"
27 #include "MICmdArgValOptionLong.h"
28 #include "MICmdArgValOptionShort.h"
29 #include "MICmdArgValPrintValues.h"
30 #include "MICmdArgValString.h"
31 #include "MICmdArgValThreadGrp.h"
32 #include "MICmdCmdVar.h"
33 #include "MICmnLLDBDebugSessionInfo.h"
34 #include "MICmnLLDBDebugger.h"
35 #include "MICmnLLDBProxySBValue.h"
36 #include "MICmnLLDBUtilSBValue.h"
37 #include "MICmnMIResultRecord.h"
38 #include "MICmnMIValueConst.h"
39
40 #include <algorithm>
41
42 //++
43 // Details: CMICmdCmdVarCreate constructor.
44 // Type:    Method.
45 // Args:    None.
46 // Return:  None.
47 // Throws:  None.
48 //--
49 CMICmdCmdVarCreate::CMICmdCmdVarCreate()
50     : m_nChildren(0), m_nThreadId(0), m_strType("??"), m_bValid(false),
51       m_strValue("??"), m_constStrArgName("name"),
52       m_constStrArgFrameAddr("frame-addr"),
53       m_constStrArgExpression("expression") {
54   // Command factory matches this name with that received from the stdin stream
55   m_strMiCmd = "var-create";
56
57   // Required by the CMICmdFactory when registering *this command
58   m_pSelfCreatorFn = &CMICmdCmdVarCreate::CreateSelf;
59 }
60
61 //++
62 // Details: CMICmdCmdVarCreate destructor.
63 // Type:    Overrideable.
64 // Args:    None.
65 // Return:  None.
66 // Throws:  None.
67 //--
68 CMICmdCmdVarCreate::~CMICmdCmdVarCreate() {}
69
70 //++
71 // Details: The invoker requires this function. The parses the command line
72 // options
73 //          arguments to extract values for each of those arguments.
74 // Type:    Overridden.
75 // Args:    None.
76 // Return:  MIstatus::success - Functional succeeded.
77 //          MIstatus::failure - Functional failed.
78 // Throws:  None.
79 //--
80 bool CMICmdCmdVarCreate::ParseArgs() {
81   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, false, true));
82   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFrameAddr, false, true));
83   m_setCmdArgs.Add(
84       new CMICmdArgValString(m_constStrArgExpression, true, true, true, true));
85   return ParseValidateCmdOptions();
86 }
87
88 //++
89 // Details: The invoker requires this function. The command does work in this
90 // function.
91 //          The command is likely to communicate with the LLDB SBDebugger in
92 //          here.
93 // Type:    Overridden.
94 // Args:    None.
95 // Return:  MIstatus::success - Functional succeeded.
96 //          MIstatus::failure - Functional failed.
97 // Throws:  None.
98 //--
99 bool CMICmdCmdVarCreate::Execute() {
100   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
101   CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
102   CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
103   CMICMDBASE_GETOPTION(pArgFrameAddr, String, m_constStrArgFrameAddr);
104   CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
105
106   // Retrieve the --thread option's thread ID (only 1)
107   MIuint64 nThreadId = UINT64_MAX;
108   if (pArgThread->GetFound() &&
109       !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
110     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
111                                    m_cmdData.strMiCmd.c_str(),
112                                    m_constStrArgThread.c_str()));
113     return MIstatus::failure;
114   }
115
116   // Retrieve the --frame option's number
117   MIuint64 nFrame = UINT64_MAX;
118   if (pArgThread->GetFound() &&
119       !pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) {
120     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
121                                    m_cmdData.strMiCmd.c_str(),
122                                    m_constStrArgFrame.c_str()));
123     return MIstatus::failure;
124   }
125
126   const CMICmdArgValOptionLong::VecArgObjPtr_t &rVecFrameId(
127       pArgFrame->GetExpectedOptions());
128   CMICmdArgValOptionLong::VecArgObjPtr_t::const_iterator it2 =
129       rVecFrameId.begin();
130   if (it2 != rVecFrameId.end()) {
131     const CMICmdArgValNumber *pOption = static_cast<CMICmdArgValNumber *>(*it2);
132     nFrame = pOption->GetValue();
133   }
134
135   m_strVarName = "<unnamedvariable>";
136   if (pArgName->GetFound()) {
137     const CMIUtilString &rArg = pArgName->GetValue();
138     const bool bAutoName = (rArg == "-");
139     if (bAutoName) {
140       m_strVarName = CMIUtilString::Format(
141           "var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet());
142       CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
143     } else
144       m_strVarName = rArg;
145   }
146
147   bool bCurrentFrame = false;
148   if (pArgFrameAddr->GetFound()) {
149     const CMIUtilString &rStrFrameAddr(pArgFrameAddr->GetValue());
150     bCurrentFrame = CMIUtilString::Compare(rStrFrameAddr, "*");
151     if (!bCurrentFrame && (nFrame == UINT64_MAX)) {
152       // FIXME: *addr isn't implemented. Exit with error if --thread isn't
153       // specified.
154       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
155                                      m_cmdData.strMiCmd.c_str(),
156                                      m_constStrArgFrame.c_str()));
157       return MIstatus::failure;
158     }
159   }
160
161   const CMIUtilString &rStrExpression(pArgExpression->GetValue());
162   m_strExpression = rStrExpression;
163
164   CMICmnLLDBDebugSessionInfo &rSessionInfo(
165       CMICmnLLDBDebugSessionInfo::Instance());
166   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
167   lldb::SBThread thread = (nThreadId != UINT64_MAX)
168                               ? sbProcess.GetThreadByIndexID(nThreadId)
169                               : sbProcess.GetSelectedThread();
170   m_nThreadId = thread.GetIndexID();
171   lldb::SBFrame frame = bCurrentFrame ? thread.GetSelectedFrame()
172                                       : thread.GetFrameAtIndex(nFrame);
173   lldb::SBValue value;
174
175   if (rStrExpression[0] == '$') {
176     const CMIUtilString rStrRegister(rStrExpression.substr(1));
177     value = frame.FindRegister(rStrRegister.c_str());
178   } else {
179     const bool bArgs = true;
180     const bool bLocals = true;
181     const bool bStatics = true;
182     const bool bInScopeOnly = true;
183     const lldb::SBValueList valueList =
184         frame.GetVariables(bArgs, bLocals, bStatics, bInScopeOnly);
185     value = valueList.GetFirstValueByName(rStrExpression.c_str());
186   }
187
188   if (!value.IsValid())
189     value = frame.EvaluateExpression(rStrExpression.c_str());
190
191   if (value.IsValid() && value.GetError().Success()) {
192     CompleteSBValue(value);
193     m_bValid = true;
194     m_nChildren = value.GetNumChildren();
195     m_strType = CMICmnLLDBUtilSBValue(value).GetTypeNameDisplay();
196
197     // This gets added to CMICmnLLDBDebugSessionInfoVarObj static container of
198     // varObjs
199     CMICmnLLDBDebugSessionInfoVarObj varObj(rStrExpression, m_strVarName,
200                                             value);
201     m_strValue = varObj.GetValueFormatted();
202   } else {
203     m_strValue = value.GetError().GetCString();
204   }
205
206   return MIstatus::success;
207 }
208
209 //++
210 // Details: The invoker requires this function. The command prepares a MI Record
211 // Result
212 //          for the work carried out in the Execute().
213 // Type:    Overridden.
214 // Args:    None.
215 // Return:  MIstatus::success - Functional succeeded.
216 //          MIstatus::failure - Functional failed.
217 // Throws:  None.
218 //--
219 bool CMICmdCmdVarCreate::Acknowledge() {
220   if (m_bValid) {
221     // MI print
222     // "%s^done,name=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%llu\",has_more=\"%u\""
223     const CMICmnMIValueConst miValueConst(m_strVarName);
224     CMICmnMIValueResult miValueResultAll("name", miValueConst);
225     const CMIUtilString strNumChild(CMIUtilString::Format("%d", m_nChildren));
226     const CMICmnMIValueConst miValueConst2(strNumChild);
227     miValueResultAll.Add("numchild", miValueConst2);
228     const CMICmnMIValueConst miValueConst3(m_strValue);
229     miValueResultAll.Add("value", miValueConst3);
230     const CMICmnMIValueConst miValueConst4(m_strType);
231     miValueResultAll.Add("type", miValueConst4);
232     const CMIUtilString strThreadId(CMIUtilString::Format("%llu", m_nThreadId));
233     const CMICmnMIValueConst miValueConst5(strThreadId);
234     miValueResultAll.Add("thread-id", miValueConst5);
235     const CMICmnMIValueConst miValueConst6("0");
236     miValueResultAll.Add("has_more", miValueConst6);
237
238     const CMICmnMIResultRecord miRecordResult(
239         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
240         miValueResultAll);
241     m_miResultRecord = miRecordResult;
242
243     return MIstatus::success;
244   }
245
246   CMIUtilString strErrMsg(m_strValue);
247   if (m_strValue.empty())
248     strErrMsg = CMIUtilString::Format(
249         MIRSRC(IDS_CMD_ERR_VARIABLE_CREATION_FAILED), m_strExpression.c_str());
250   const CMICmnMIValueConst miValueConst(
251       strErrMsg.Escape(true /* vbEscapeQuotes */));
252   CMICmnMIValueResult miValueResult("msg", miValueConst);
253   const CMICmnMIResultRecord miRecordResult(
254       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
255       miValueResult);
256   m_miResultRecord = miRecordResult;
257
258   return MIstatus::success;
259 }
260
261 //++
262 // Details: Required by the CMICmdFactory when registering *this command. The
263 // factory
264 //          calls this function to create an instance of *this command.
265 // Type:    Static method.
266 // Args:    None.
267 // Return:  CMICmdBase * - Pointer to a new command.
268 // Throws:  None.
269 //--
270 CMICmdBase *CMICmdCmdVarCreate::CreateSelf() {
271   return new CMICmdCmdVarCreate();
272 }
273
274 //++
275 // Details: Complete SBValue object and its children to get
276 // SBValue::GetValueDidChange
277 //          work.
278 // Type:    Method.
279 // Args:    vrwValue    - (R)   Value to update.
280 // Return:  MIstatus::success - Functional succeeded.
281 //          MIstatus::failure - Functional failed.
282 // Throws:  None.
283 //--
284 void CMICmdCmdVarCreate::CompleteSBValue(lldb::SBValue &vrwValue) {
285   // Force a value to update
286   vrwValue.GetValueDidChange();
287
288   // And update its children
289   lldb::SBType valueType = vrwValue.GetType();
290   if (!valueType.IsPointerType() && !valueType.IsReferenceType()) {
291     const MIuint nChildren = vrwValue.GetNumChildren();
292     for (MIuint i = 0; i < nChildren; ++i) {
293       lldb::SBValue member = vrwValue.GetChildAtIndex(i);
294       if (member.IsValid())
295         CompleteSBValue(member);
296     }
297   }
298 }
299
300
301 //++
302 // Details: CMICmdCmdVarUpdate constructor.
303 // Type:    Method.
304 // Args:    None.
305 // Return:  None.
306 // Throws:  None.
307 //--
308 CMICmdCmdVarUpdate::CMICmdCmdVarUpdate()
309     : m_constStrArgPrintValues("print-values"), m_constStrArgName("name"),
310       m_bValueChanged(false), m_miValueList(true) {
311   // Command factory matches this name with that received from the stdin stream
312   m_strMiCmd = "var-update";
313
314   // Required by the CMICmdFactory when registering *this command
315   m_pSelfCreatorFn = &CMICmdCmdVarUpdate::CreateSelf;
316 }
317
318 //++
319 // Details: CMICmdCmdVarUpdate destructor.
320 // Type:    Overrideable.
321 // Args:    None.
322 // Return:  None.
323 // Throws:  None.
324 //--
325 CMICmdCmdVarUpdate::~CMICmdCmdVarUpdate() {}
326
327 //++
328 // Details: The invoker requires this function. The parses the command line
329 // options
330 //          arguments to extract values for each of those arguments.
331 // Type:    Overridden.
332 // Args:    None.
333 // Return:  MIstatus::success - Functional succeeded.
334 //          MIstatus::failure - Functional failed.
335 // Throws:  None.
336 //--
337 bool CMICmdCmdVarUpdate::ParseArgs() {
338   m_setCmdArgs.Add(
339       new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
340   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
341   return ParseValidateCmdOptions();
342 }
343
344 //++
345 // Details: The invoker requires this function. The command does work in this
346 // function.
347 //          The command is likely to communicate with the LLDB SBDebugger in
348 //          here.
349 // Type:    Overridden.
350 // Args:    None.
351 // Return:  MIstatus::success - Functional succeeded.
352 //          MIstatus::failure - Functional failed.
353 // Throws:  None.
354 //--
355 bool CMICmdCmdVarUpdate::Execute() {
356   CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
357   CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
358
359   CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
360       CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
361   if (pArgPrintValues->GetFound())
362     eVarInfoFormat =
363         static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
364             pArgPrintValues->GetValue());
365
366   const CMIUtilString &rVarObjName(pArgName->GetValue());
367   CMICmnLLDBDebugSessionInfoVarObj varObj;
368   if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
369     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
370                                    m_cmdData.strMiCmd.c_str(),
371                                    rVarObjName.c_str()));
372     return MIstatus::failure;
373   }
374
375   lldb::SBValue &rValue = varObj.GetValue();
376   if (!ExamineSBValueForChange(rValue, m_bValueChanged))
377     return MIstatus::failure;
378
379   if (m_bValueChanged) {
380     varObj.UpdateValue();
381     const bool bPrintValue(
382         (eVarInfoFormat ==
383          CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues) ||
384         (eVarInfoFormat ==
385              CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues &&
386          rValue.GetNumChildren() == 0));
387     const CMIUtilString strValue(bPrintValue ? varObj.GetValueFormatted() : "");
388     const CMIUtilString strInScope(rValue.IsInScope() ? "true" : "false");
389     MIFormResponse(rVarObjName, bPrintValue ? strValue.c_str() : nullptr,
390                    strInScope);
391   }
392
393   return MIstatus::success;
394 }
395
396 //++
397 // Details: The invoker requires this function. The command prepares a MI Record
398 // Result
399 //          for the work carried out in the Execute().
400 // Type:    Overridden.
401 // Args:    None.
402 // Return:  MIstatus::success - Functional succeeded.
403 //          MIstatus::failure - Functional failed.
404 // Throws:  None.
405 //--
406 bool CMICmdCmdVarUpdate::Acknowledge() {
407   if (m_bValueChanged) {
408     // MI print
409     // "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
410     CMICmnMIValueResult miValueResult("changelist", m_miValueList);
411     const CMICmnMIResultRecord miRecordResult(
412         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
413         miValueResult);
414     m_miResultRecord = miRecordResult;
415   } else {
416     // MI print "%s^done,changelist=[]"
417     const CMICmnMIValueList miValueList(true);
418     CMICmnMIValueResult miValueResult6("changelist", miValueList);
419     const CMICmnMIResultRecord miRecordResult(
420         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
421         miValueResult6);
422     m_miResultRecord = miRecordResult;
423   }
424
425   return MIstatus::success;
426 }
427
428 //++
429 // Details: Required by the CMICmdFactory when registering *this command. The
430 // factory
431 //          calls this function to create an instance of *this command.
432 // Type:    Static method.
433 // Args:    None.
434 // Return:  CMICmdBase * - Pointer to a new command.
435 // Throws:  None.
436 //--
437 CMICmdBase *CMICmdCmdVarUpdate::CreateSelf() {
438   return new CMICmdCmdVarUpdate();
439 }
440
441 //++
442 // Details: Form the MI response for multiple variables.
443 // Type:    Method.
444 // Args:    vrStrVarName    - (R)   Session var object's name.
445 //          vpValue         - (R)   Text version of the value held in the
446 //          variable.
447 //          vrStrScope      - (R)   In scope "yes" or "no".
448 // Return:  None.
449 // Throws:  None.
450 //--
451 void CMICmdCmdVarUpdate::MIFormResponse(const CMIUtilString &vrStrVarName,
452                                         const char *const vpValue,
453                                         const CMIUtilString &vrStrScope) {
454   // MI print
455   // "[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
456   const CMICmnMIValueConst miValueConst(vrStrVarName);
457   const CMICmnMIValueResult miValueResult("name", miValueConst);
458   CMICmnMIValueTuple miValueTuple(miValueResult);
459   if (vpValue != nullptr) {
460     const CMICmnMIValueConst miValueConst2(vpValue);
461     const CMICmnMIValueResult miValueResult2("value", miValueConst2);
462     miValueTuple.Add(miValueResult2);
463   }
464   const CMICmnMIValueConst miValueConst3(vrStrScope);
465   const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
466   miValueTuple.Add(miValueResult3);
467   const CMICmnMIValueConst miValueConst4("false");
468   const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
469   miValueTuple.Add(miValueResult4);
470   const CMICmnMIValueConst miValueConst5("0");
471   const CMICmnMIValueResult miValueResult5("has_more", miValueConst5);
472   miValueTuple.Add(miValueResult5);
473   m_miValueList.Add(miValueTuple);
474 }
475
476 //++
477 // Details: Determine if the var object was changed.
478 // Type:    Method.
479 // Args:    vrVarObj    - (R)   Session var object to examine.
480 //          vrwbChanged - (W)   True = The var object was changed,
481 //                              False = It was not changed.
482 // Return:  MIstatus::success - Functional succeeded.
483 //          MIstatus::failure - Functional failed.
484 // Throws:  None.
485 //--
486 bool CMICmdCmdVarUpdate::ExamineSBValueForChange(lldb::SBValue &vrwValue,
487                                                  bool &vrwbChanged) {
488   if (vrwValue.GetValueDidChange()) {
489     vrwbChanged = true;
490     return MIstatus::success;
491   }
492
493   const MIuint nChildren = vrwValue.GetNumChildren();
494   for (MIuint i = 0; i < nChildren; ++i) {
495     lldb::SBValue member = vrwValue.GetChildAtIndex(i);
496     if (!member.IsValid())
497       continue;
498
499     // skip pointers and references to avoid infinite loop
500     if (member.GetType().GetTypeFlags() &
501         (lldb::eTypeIsPointer | lldb::eTypeIsReference))
502       continue;
503
504     // Handle composite types (i.e. struct or arrays)
505     if (ExamineSBValueForChange(member, vrwbChanged) && vrwbChanged)
506       return MIstatus::success;
507   }
508   vrwbChanged = false;
509   return MIstatus::success;
510 }
511
512
513 //++
514 // Details: CMICmdCmdVarDelete constructor.
515 // Type:    Method.
516 // Args:    None.
517 // Return:  None.
518 // Throws:  None.
519 //--
520 CMICmdCmdVarDelete::CMICmdCmdVarDelete() : m_constStrArgName("name") {
521   // Command factory matches this name with that received from the stdin stream
522   m_strMiCmd = "var-delete";
523
524   // Required by the CMICmdFactory when registering *this command
525   m_pSelfCreatorFn = &CMICmdCmdVarDelete::CreateSelf;
526 }
527
528 //++
529 // Details: The invoker requires this function. The parses the command line
530 // options
531 //          arguments to extract values for each of those arguments.
532 // Type:    Overridden.
533 // Args:    None.
534 // Return:  MIstatus::success - Functional succeeded.
535 //          MIstatus::failure - Functional failed.
536 // Throws:  None.
537 //--
538 bool CMICmdCmdVarDelete::ParseArgs() {
539   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
540   return ParseValidateCmdOptions();
541 }
542
543 //++
544 // Details: CMICmdCmdVarDelete destructor.
545 // Type:    Overrideable.
546 // Args:    None.
547 // Return:  None.
548 // Throws:  None.
549 //--
550 CMICmdCmdVarDelete::~CMICmdCmdVarDelete() {}
551
552 //++
553 // Details: The invoker requires this function. The command does work in this
554 // function.
555 //          The command is likely to communicate with the LLDB SBDebugger in
556 //          here.
557 // Type:    Overridden.
558 // Args:    None.
559 // Return:  MIstatus::success - Functional succeeded.
560 //          MIstatus::failure - Functional failed.
561 // Throws:  None.
562 //--
563 bool CMICmdCmdVarDelete::Execute() {
564   CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
565
566   const CMIUtilString &rVarObjName(pArgName->GetValue());
567   CMICmnLLDBDebugSessionInfoVarObj::VarObjDelete(rVarObjName);
568
569   return MIstatus::success;
570 }
571
572 //++
573 // Details: The invoker requires this function. The command prepares a MI Record
574 // Result
575 //          for the work carried out in the Execute().
576 // Type:    Overridden.
577 // Args:    None.
578 // Return:  MIstatus::success - Functional succeeded.
579 //          MIstatus::failure - Functional failed.
580 // Throws:  None.
581 //--
582 bool CMICmdCmdVarDelete::Acknowledge() {
583   const CMICmnMIResultRecord miRecordResult(
584       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
585   m_miResultRecord = miRecordResult;
586
587   return MIstatus::success;
588 }
589
590 //++
591 // Details: Required by the CMICmdFactory when registering *this command. The
592 // factory
593 //          calls this function to create an instance of *this command.
594 // Type:    Static method.
595 // Args:    None.
596 // Return:  CMICmdBase * - Pointer to a new command.
597 // Throws:  None.
598 //--
599 CMICmdBase *CMICmdCmdVarDelete::CreateSelf() {
600   return new CMICmdCmdVarDelete();
601 }
602
603
604 //++
605 // Details: CMICmdCmdVarAssign constructor.
606 // Type:    Method.
607 // Args:    None.
608 // Return:  None.
609 // Throws:  None.
610 //--
611 CMICmdCmdVarAssign::CMICmdCmdVarAssign()
612     : m_bOk(true), m_constStrArgName("name"),
613       m_constStrArgExpression("expression") {
614   // Command factory matches this name with that received from the stdin stream
615   m_strMiCmd = "var-assign";
616
617   // Required by the CMICmdFactory when registering *this command
618   m_pSelfCreatorFn = &CMICmdCmdVarAssign::CreateSelf;
619 }
620
621 //++
622 // Details: CMICmdCmdVarAssign destructor.
623 // Type:    Overrideable.
624 // Args:    None.
625 // Return:  None.
626 // Throws:  None.
627 //--
628 CMICmdCmdVarAssign::~CMICmdCmdVarAssign() {}
629
630 //++
631 // Details: The invoker requires this function. The parses the command line
632 // options
633 //          arguments to extract values for each of those arguments.
634 // Type:    Overridden.
635 // Args:    None.
636 // Return:  MIstatus::success - Functional succeeded.
637 //          MIstatus::failure - Functional failed.
638 // Throws:  None.
639 //--
640 bool CMICmdCmdVarAssign::ParseArgs() {
641   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
642   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgExpression, true, true));
643   return ParseValidateCmdOptions();
644 }
645
646 //++
647 // Details: The invoker requires this function. The command does work in this
648 // function.
649 //          The command is likely to communicate with the LLDB SBDebugger in
650 //          here.
651 // Type:    Overridden.
652 // Args:    None.
653 // Return:  MIstatus::success - Functional succeeded.
654 //          MIstatus::failure - Functional failed.
655 // Throws:  None.
656 //--
657 bool CMICmdCmdVarAssign::Execute() {
658   CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
659   CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
660
661   const CMIUtilString &rVarObjName(pArgName->GetValue());
662   const CMIUtilString &rExpression(pArgExpression->GetValue());
663
664   CMICmnLLDBDebugSessionInfoVarObj varObj;
665   if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
666     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
667                                    m_cmdData.strMiCmd.c_str(),
668                                    rVarObjName.c_str()));
669     return MIstatus::failure;
670   }
671   m_varObjName = rVarObjName;
672
673   CMIUtilString strExpression(rExpression.Trim());
674   strExpression = strExpression.Trim('"');
675   lldb::SBValue &rValue(const_cast<lldb::SBValue &>(varObj.GetValue()));
676   m_bOk = rValue.SetValueFromCString(strExpression.c_str());
677   if (m_bOk)
678     varObj.UpdateValue();
679
680   return MIstatus::success;
681 }
682
683 //++
684 // Details: The invoker requires this function. The command prepares a MI Record
685 // Result
686 //          for the work carried out in the Execute().
687 // Type:    Overridden.
688 // Args:    None.
689 // Return:  MIstatus::success - Functional succeeded.
690 //          MIstatus::failure - Functional failed.
691 // Throws:  None.
692 //--
693 bool CMICmdCmdVarAssign::Acknowledge() {
694   if (m_bOk) {
695     // MI print "%s^done,value=\"%s\""
696     CMICmnLLDBDebugSessionInfoVarObj varObj;
697     CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
698     const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
699     const CMICmnMIValueResult miValueResult("value", miValueConst);
700     const CMICmnMIResultRecord miRecordResult(
701         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
702         miValueResult);
703     m_miResultRecord = miRecordResult;
704
705     return MIstatus::success;
706   }
707
708   const CMICmnMIValueConst miValueConst("expression could not be evaluated");
709   const CMICmnMIValueResult miValueResult("msg", miValueConst);
710   const CMICmnMIResultRecord miRecordResult(
711       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
712       miValueResult);
713   m_miResultRecord = miRecordResult;
714
715   return MIstatus::success;
716 }
717
718 //++
719 // Details: Required by the CMICmdFactory when registering *this command. The
720 // factory
721 //          calls this function to create an instance of *this command.
722 // Type:    Static method.
723 // Args:    None.
724 // Return:  CMICmdBase * - Pointer to a new command.
725 // Throws:  None.
726 //--
727 CMICmdBase *CMICmdCmdVarAssign::CreateSelf() {
728   return new CMICmdCmdVarAssign();
729 }
730
731
732 //++
733 // Details: CMICmdCmdVarSetFormat constructor.
734 // Type:    Method.
735 // Args:    None.
736 // Return:  None.
737 // Throws:  None.
738 //--
739 CMICmdCmdVarSetFormat::CMICmdCmdVarSetFormat()
740     : m_constStrArgName("name"), m_constStrArgFormatSpec("format-spec") {
741   // Command factory matches this name with that received from the stdin stream
742   m_strMiCmd = "var-set-format";
743
744   // Required by the CMICmdFactory when registering *this command
745   m_pSelfCreatorFn = &CMICmdCmdVarSetFormat::CreateSelf;
746 }
747
748 //++
749 // Details: CMICmdCmdVarSetFormat destructor.
750 // Type:    Overrideable.
751 // Args:    None.
752 // Return:  None.
753 // Throws:  None.
754 //--
755 CMICmdCmdVarSetFormat::~CMICmdCmdVarSetFormat() {}
756
757 //++
758 // Details: The invoker requires this function. The parses the command line
759 // options
760 //          arguments to extract values for each of those arguments.
761 // Type:    Overridden.
762 // Args:    None.
763 // Return:  MIstatus::success - Functional succeeded.
764 //          MIstatus::failure - Functional failed.
765 // Throws:  None.
766 //--
767 bool CMICmdCmdVarSetFormat::ParseArgs() {
768   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
769   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFormatSpec, true, true));
770   return ParseValidateCmdOptions();
771 }
772
773 //++
774 // Details: The invoker requires this function. The command does work in this
775 // function.
776 //          The command is likely to communicate with the LLDB SBDebugger in
777 //          here.
778 // Type:    Overridden.
779 // Args:    None.
780 // Return:  MIstatus::success - Functional succeeded.
781 //          MIstatus::failure - Functional failed.
782 // Throws:  None.
783 //--
784 bool CMICmdCmdVarSetFormat::Execute() {
785   CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
786   CMICMDBASE_GETOPTION(pArgFormatSpec, String, m_constStrArgFormatSpec);
787
788   const CMIUtilString &rVarObjName(pArgName->GetValue());
789   const CMIUtilString &rExpression(pArgFormatSpec->GetValue());
790
791   CMICmnLLDBDebugSessionInfoVarObj varObj;
792   if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
793     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
794                                    m_cmdData.strMiCmd.c_str(),
795                                    rVarObjName.c_str()));
796     return MIstatus::failure;
797   }
798   if (!varObj.SetVarFormat(
799           CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString(
800               rExpression))) {
801     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_ENUM_INVALID),
802                                    m_cmdData.strMiCmd.c_str(),
803                                    rVarObjName.c_str(), rExpression.c_str()));
804     return MIstatus::failure;
805   }
806   varObj.UpdateValue();
807
808   m_varObjName = rVarObjName;
809
810   return MIstatus::success;
811 }
812
813 //++
814 // Details: The invoker requires this function. The command prepares a MI Record
815 // Result
816 //          for the work carried out in the Execute().
817 // Type:    Overridden.
818 // Args:    None.
819 // Return:  MIstatus::success - Functional succeeded.
820 //          MIstatus::failure - Functional failed.
821 // Throws:  None.
822 //--
823 bool CMICmdCmdVarSetFormat::Acknowledge() {
824   // MI print
825   // "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
826   CMICmnLLDBDebugSessionInfoVarObj varObj;
827   CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
828   const CMICmnMIValueConst miValueConst(m_varObjName);
829   const CMICmnMIValueResult miValueResult("name", miValueConst);
830   CMICmnMIValueTuple miValueTuple(miValueResult);
831   const CMICmnMIValueConst miValueConst2(varObj.GetValueFormatted());
832   const CMICmnMIValueResult miValueResult2("value", miValueConst2);
833   miValueTuple.Add(miValueResult2);
834   lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
835   const CMICmnMIValueConst miValueConst3(rValue.IsInScope() ? "true" : "false");
836   const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
837   miValueTuple.Add(miValueResult3);
838   const CMICmnMIValueConst miValueConst4("false");
839   const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
840   miValueTuple.Add(miValueResult4);
841   const CMICmnMIValueConst miValueConst5("0");
842   const CMICmnMIValueResult miValueResult5("type_changed", miValueConst5);
843   miValueTuple.Add(miValueResult5);
844   const CMICmnMIValueList miValueList(miValueTuple);
845   const CMICmnMIValueResult miValueResult6("changelist", miValueList);
846
847   const CMICmnMIResultRecord miRecordResult(
848       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
849       miValueResult6);
850   m_miResultRecord = miRecordResult;
851
852   return MIstatus::success;
853 }
854
855 //++
856 // Details: Required by the CMICmdFactory when registering *this command. The
857 // factory
858 //          calls this function to create an instance of *this command.
859 // Type:    Static method.
860 // Args:    None.
861 // Return:  CMICmdBase * - Pointer to a new command.
862 // Throws:  None.
863 //--
864 CMICmdBase *CMICmdCmdVarSetFormat::CreateSelf() {
865   return new CMICmdCmdVarSetFormat();
866 }
867
868
869 //++
870 // Details: CMICmdCmdVarListChildren constructor.
871 // Type:    Method.
872 // Args:    None.
873 // Return:  None.
874 // Throws:  None.
875 //--
876 CMICmdCmdVarListChildren::CMICmdCmdVarListChildren()
877     : m_constStrArgPrintValues("print-values"), m_constStrArgName("name"),
878       m_constStrArgFrom("from"), m_constStrArgTo("to"), m_bValueValid(false),
879       m_nChildren(0), m_miValueList(true), m_bHasMore(false) {
880   // Command factory matches this name with that received from the stdin stream
881   m_strMiCmd = "var-list-children";
882
883   // Required by the CMICmdFactory when registering *this command
884   m_pSelfCreatorFn = &CMICmdCmdVarListChildren::CreateSelf;
885 }
886
887 //++
888 // Details: CMICmdCmdVarListChildren destructor.
889 // Type:    Overrideable.
890 // Args:    None.
891 // Return:  None.
892 // Throws:  None.
893 //--
894 CMICmdCmdVarListChildren::~CMICmdCmdVarListChildren() {}
895
896 //++
897 // Details: The invoker requires this function. The parses the command line
898 // options
899 //          arguments to extract values for each of those arguments.
900 // Type:    Overridden.
901 // Args:    None.
902 // Return:  MIstatus::success - Functional succeeded.
903 //          MIstatus::failure - Functional failed.
904 // Throws:  None.
905 //--
906 bool CMICmdCmdVarListChildren::ParseArgs() {
907   m_setCmdArgs.Add(
908       new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
909   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true, true));
910   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrom, false, true));
911   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgTo, false, true));
912   return ParseValidateCmdOptions();
913 }
914
915 //++
916 // Details: The invoker requires this function. The command does work in this
917 // function.
918 //          The command is likely to communicate with the LLDB SBDebugger in
919 //          here.
920 // Type:    Overridden.
921 // Args:    None.
922 // Return:  MIstatus::success - Functional succeeded.
923 //          MIstatus::failure - Functional failed.
924 // Throws:  None.
925 //--
926 bool CMICmdCmdVarListChildren::Execute() {
927   CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
928   CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
929   CMICMDBASE_GETOPTION(pArgFrom, Number, m_constStrArgFrom);
930   CMICMDBASE_GETOPTION(pArgTo, Number, m_constStrArgTo);
931
932   CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
933       CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
934   if (pArgPrintValues->GetFound())
935     eVarInfoFormat =
936         static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
937             pArgPrintValues->GetValue());
938
939   const CMIUtilString &rVarObjName(pArgName->GetValue());
940   CMICmnLLDBDebugSessionInfoVarObj varObj;
941   if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
942     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
943                                    m_cmdData.strMiCmd.c_str(),
944                                    rVarObjName.c_str()));
945     return MIstatus::failure;
946   }
947
948   MIuint nFrom = 0;
949   MIuint nTo = UINT32_MAX;
950   if (pArgFrom->GetFound() && pArgTo->GetFound()) {
951     nFrom = pArgFrom->GetValue();
952     nTo = pArgTo->GetValue();
953   } else if (pArgFrom->GetFound() || pArgTo->GetFound()) {
954     // Only from or to was specified but both are required
955     SetError(
956         CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID),
957                               m_cmdData.strMiCmd.c_str()));
958     return MIstatus::failure;
959   }
960
961   lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
962   m_bValueValid = rValue.IsValid();
963   if (!m_bValueValid)
964     return MIstatus::success;
965
966   const MIuint nChildren = rValue.GetNumChildren();
967   m_bHasMore = nTo < nChildren;
968   nTo = std::min(nTo, nChildren);
969   m_nChildren = nFrom < nTo ? nTo - nFrom : 0;
970   for (MIuint i = nFrom; i < nTo; i++) {
971     lldb::SBValue member = rValue.GetChildAtIndex(i);
972     const CMICmnLLDBUtilSBValue utilValue(member);
973     const CMIUtilString strExp = utilValue.GetName();
974     const CMIUtilString name(
975         strExp.empty() ? CMIUtilString::Format("%s.$%u", rVarObjName.c_str(), i)
976                        : CMIUtilString::Format("%s.%s", rVarObjName.c_str(),
977                                                strExp.c_str()));
978     const MIuint nChildren = member.GetNumChildren();
979     const CMIUtilString strThreadId(
980         CMIUtilString::Format("%u", member.GetThread().GetIndexID()));
981
982     // Varobj gets added to CMICmnLLDBDebugSessionInfoVarObj static container of
983     // varObjs
984     CMICmnLLDBDebugSessionInfoVarObj var(strExp, name, member, rVarObjName);
985
986     // MI print
987     // "child={name=\"%s\",exp=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%u\",has_more=\"%u\"}"
988     const CMICmnMIValueConst miValueConst(name);
989     const CMICmnMIValueResult miValueResult("name", miValueConst);
990     CMICmnMIValueTuple miValueTuple(miValueResult);
991     const CMICmnMIValueConst miValueConst2(strExp);
992     const CMICmnMIValueResult miValueResult2("exp", miValueConst2);
993     miValueTuple.Add(miValueResult2);
994     const CMIUtilString strNumChild(CMIUtilString::Format("%u", nChildren));
995     const CMICmnMIValueConst miValueConst3(strNumChild);
996     const CMICmnMIValueResult miValueResult3("numchild", miValueConst3);
997     miValueTuple.Add(miValueResult3);
998     const CMICmnMIValueConst miValueConst5(utilValue.GetTypeNameDisplay());
999     const CMICmnMIValueResult miValueResult5("type", miValueConst5);
1000     miValueTuple.Add(miValueResult5);
1001     const CMICmnMIValueConst miValueConst6(strThreadId);
1002     const CMICmnMIValueResult miValueResult6("thread-id", miValueConst6);
1003     miValueTuple.Add(miValueResult6);
1004     // nChildren == 0 is used to check for simple values
1005     if (eVarInfoFormat ==
1006             CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues ||
1007         (eVarInfoFormat ==
1008              CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues &&
1009          nChildren == 0)) {
1010       const CMIUtilString strValue(
1011           CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(
1012               member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural));
1013       const CMICmnMIValueConst miValueConst7(strValue);
1014       const CMICmnMIValueResult miValueResult7("value", miValueConst7);
1015       miValueTuple.Add(miValueResult7);
1016     }
1017     const CMICmnMIValueConst miValueConst8("0");
1018     const CMICmnMIValueResult miValueResult8("has_more", miValueConst8);
1019     miValueTuple.Add(miValueResult8);
1020     const CMICmnMIValueResult miValueResult9("child", miValueTuple);
1021     m_miValueList.Add(miValueResult9);
1022   }
1023
1024   return MIstatus::success;
1025 }
1026
1027 //++
1028 // Details: The invoker requires this function. The command prepares a MI Record
1029 // Result
1030 //          for the work carried out in the Execute().
1031 // Type:    Overridden.
1032 // Args:    None.
1033 // Return:  MIstatus::success - Functional succeeded.
1034 //          MIstatus::failure - Functional failed.
1035 // Throws:  None.
1036 //--
1037 bool CMICmdCmdVarListChildren::Acknowledge() {
1038   if (m_bValueValid) {
1039     // MI print "%s^done,numchild=\"%u\",children=[%s],has_more=\"%d\""
1040     const CMIUtilString strNumChild(CMIUtilString::Format("%u", m_nChildren));
1041     const CMICmnMIValueConst miValueConst(strNumChild);
1042     CMICmnMIValueResult miValueResult("numchild", miValueConst);
1043     if (m_nChildren != 0)
1044       miValueResult.Add("children", m_miValueList);
1045     const CMIUtilString strHasMore(m_bHasMore ? "1" : "0");
1046     const CMICmnMIValueConst miValueConst2(strHasMore);
1047     miValueResult.Add("has_more", miValueConst2);
1048
1049     const CMICmnMIResultRecord miRecordResult(
1050         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1051         miValueResult);
1052     m_miResultRecord = miRecordResult;
1053
1054     return MIstatus::success;
1055   }
1056
1057   // MI print "%s^error,msg=\"variable invalid\""
1058   const CMICmnMIValueConst miValueConst("variable invalid");
1059   const CMICmnMIValueResult miValueResult("msg", miValueConst);
1060   const CMICmnMIResultRecord miRecordResult(
1061       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1062       miValueResult);
1063   m_miResultRecord = miRecordResult;
1064
1065   return MIstatus::success;
1066 }
1067
1068 //++
1069 // Details: Required by the CMICmdFactory when registering *this command. The
1070 // factory
1071 //          calls this function to create an instance of *this command.
1072 // Type:    Static method.
1073 // Args:    None.
1074 // Return:  CMICmdBase * - Pointer to a new command.
1075 // Throws:  None.
1076 //--
1077 CMICmdBase *CMICmdCmdVarListChildren::CreateSelf() {
1078   return new CMICmdCmdVarListChildren();
1079 }
1080
1081
1082 //++
1083 // Details: CMICmdCmdVarEvaluateExpression constructor.
1084 // Type:    Method.
1085 // Args:    None.
1086 // Return:  None.
1087 // Throws:  None.
1088 //--
1089 CMICmdCmdVarEvaluateExpression::CMICmdCmdVarEvaluateExpression()
1090     : m_bValueValid(true), m_constStrArgFormatSpec("-f"),
1091       m_constStrArgName("name") {
1092   // Command factory matches this name with that received from the stdin stream
1093   m_strMiCmd = "var-evaluate-expression";
1094
1095   // Required by the CMICmdFactory when registering *this command
1096   m_pSelfCreatorFn = &CMICmdCmdVarEvaluateExpression::CreateSelf;
1097 }
1098
1099 //++
1100 // Details: CMICmdCmdVarEvaluateExpression destructor.
1101 // Type:    Overrideable.
1102 // Args:    None.
1103 // Return:  None.
1104 // Throws:  None.
1105 //--
1106 CMICmdCmdVarEvaluateExpression::~CMICmdCmdVarEvaluateExpression() {}
1107
1108 //++
1109 // Details: The invoker requires this function. The parses the command line
1110 // options
1111 //          arguments to extract values for each of those arguments.
1112 // Type:    Overridden.
1113 // Args:    None.
1114 // Return:  MIstatus::success - Functional succeeded.
1115 //          MIstatus::failure - Functional failed.
1116 // Throws:  None.
1117 //--
1118 bool CMICmdCmdVarEvaluateExpression::ParseArgs() {
1119   m_setCmdArgs.Add(
1120       new CMICmdArgValOptionShort(m_constStrArgFormatSpec, false, false,
1121                                   CMICmdArgValListBase::eArgValType_String, 1));
1122   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1123   return ParseValidateCmdOptions();
1124 }
1125
1126 //++
1127 // Details: The invoker requires this function. The command does work in this
1128 // function.
1129 //          The command is likely to communicate with the LLDB SBDebugger in
1130 //          here.
1131 // Type:    Overridden.
1132 // Args:    None.
1133 // Return:  MIstatus::success - Functional succeeded.
1134 //          MIstatus::failure - Functional failed.
1135 // Throws:  None.
1136 //--
1137 bool CMICmdCmdVarEvaluateExpression::Execute() {
1138   CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1139
1140   const CMIUtilString &rVarObjName(pArgName->GetValue());
1141   CMICmnLLDBDebugSessionInfoVarObj varObj;
1142   if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1143     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1144                                    m_cmdData.strMiCmd.c_str(),
1145                                    rVarObjName.c_str()));
1146     return MIstatus::failure;
1147   }
1148
1149   lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1150   m_bValueValid = rValue.IsValid();
1151   if (!m_bValueValid)
1152     return MIstatus::success;
1153
1154   m_varObjName = rVarObjName;
1155   varObj.UpdateValue();
1156
1157   return MIstatus::success;
1158 }
1159
1160 //++
1161 // Details: The invoker requires this function. The command prepares a MI Record
1162 // Result
1163 //          for the work carried out in the Execute().
1164 // Type:    Overridden.
1165 // Args:    None.
1166 // Return:  MIstatus::success - Functional succeeded.
1167 //          MIstatus::failure - Functional failed.
1168 // Throws:  None.
1169 //--
1170 bool CMICmdCmdVarEvaluateExpression::Acknowledge() {
1171   if (m_bValueValid) {
1172     CMICmnLLDBDebugSessionInfoVarObj varObj;
1173     CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
1174     const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
1175     const CMICmnMIValueResult miValueResult("value", miValueConst);
1176     const CMICmnMIResultRecord miRecordResult(
1177         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1178         miValueResult);
1179     m_miResultRecord = miRecordResult;
1180     return MIstatus::success;
1181   }
1182
1183   const CMICmnMIValueConst miValueConst("variable invalid");
1184   const CMICmnMIValueResult miValueResult("msg", miValueConst);
1185   const CMICmnMIResultRecord miRecordResult(
1186       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1187       miValueResult);
1188   m_miResultRecord = miRecordResult;
1189   return MIstatus::success;
1190 }
1191
1192 //++
1193 // Details: Required by the CMICmdFactory when registering *this command. The
1194 // factory
1195 //          calls this function to create an instance of *this command.
1196 // Type:    Static method.
1197 // Args:    None.
1198 // Return:  CMICmdBase * - Pointer to a new command.
1199 // Throws:  None.
1200 //--
1201 CMICmdBase *CMICmdCmdVarEvaluateExpression::CreateSelf() {
1202   return new CMICmdCmdVarEvaluateExpression();
1203 }
1204
1205
1206 //++
1207 // Details: CMICmdCmdVarInfoPathExpression constructor.
1208 // Type:    Method.
1209 // Args:    None.
1210 // Return:  None.
1211 // Throws:  None.
1212 //--
1213 CMICmdCmdVarInfoPathExpression::CMICmdCmdVarInfoPathExpression()
1214     : m_bValueValid(true), m_constStrArgName("name") {
1215   // Command factory matches this name with that received from the stdin stream
1216   m_strMiCmd = "var-info-path-expression";
1217
1218   // Required by the CMICmdFactory when registering *this command
1219   m_pSelfCreatorFn = &CMICmdCmdVarInfoPathExpression::CreateSelf;
1220 }
1221
1222 //++
1223 // Details: CMICmdCmdVarInfoPathExpression destructor.
1224 // Type:    Overrideable.
1225 // Args:    None.
1226 // Return:  None.
1227 // Throws:  None.
1228 //--
1229 CMICmdCmdVarInfoPathExpression::~CMICmdCmdVarInfoPathExpression() {}
1230
1231 //++
1232 // Details: The invoker requires this function. The parses the command line
1233 // options
1234 //          arguments to extract values for each of those arguments.
1235 // Type:    Overridden.
1236 // Args:    None.
1237 // Return:  MIstatus::success - Functional succeeded.
1238 //          MIstatus::failure - Functional failed.
1239 // Throws:  None.
1240 //--
1241 bool CMICmdCmdVarInfoPathExpression::ParseArgs() {
1242   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1243   return ParseValidateCmdOptions();
1244 }
1245
1246 //++
1247 // Details: The invoker requires this function. The command does work in this
1248 // function.
1249 //          The command is likely to communicate with the LLDB SBDebugger in
1250 //          here.
1251 // Type:    Overridden.
1252 // Args:    None.
1253 // Return:  MIstatus::success - Functional succeeded.
1254 //          MIstatus::failure - Functional failed.
1255 // Throws:  None.
1256 //--
1257 bool CMICmdCmdVarInfoPathExpression::Execute() {
1258   CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1259
1260   const CMIUtilString &rVarObjName(pArgName->GetValue());
1261   CMICmnLLDBDebugSessionInfoVarObj varObj;
1262   if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1263     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1264                                    m_cmdData.strMiCmd.c_str(),
1265                                    rVarObjName.c_str()));
1266     return MIstatus::failure;
1267   }
1268
1269   lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1270   m_bValueValid = rValue.IsValid();
1271   if (!m_bValueValid)
1272     return MIstatus::success;
1273
1274   lldb::SBStream stream;
1275   if (!rValue.GetExpressionPath(stream, true)) {
1276     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH),
1277                                    m_cmdData.strMiCmd.c_str(),
1278                                    rVarObjName.c_str()));
1279     return MIstatus::failure;
1280   }
1281
1282   const char *pPathExpression = stream.GetData();
1283   if (pPathExpression == nullptr) {
1284     // Build expression from what we do know
1285     m_strPathExpression = varObj.GetNameReal();
1286     return MIstatus::success;
1287   }
1288
1289   // Has LLDB returned a var signature of it's own
1290   if (pPathExpression[0] != '$') {
1291     m_strPathExpression = pPathExpression;
1292     return MIstatus::success;
1293   }
1294
1295   // Build expression from what we do know
1296   const CMIUtilString &rVarParentName(varObj.GetVarParentName());
1297   if (rVarParentName.empty()) {
1298     m_strPathExpression = varObj.GetNameReal();
1299   } else {
1300     CMICmnLLDBDebugSessionInfoVarObj varObjParent;
1301     if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarParentName,
1302                                                      varObjParent)) {
1303       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1304                                      m_cmdData.strMiCmd.c_str(),
1305                                      rVarParentName.c_str()));
1306       return MIstatus::failure;
1307     }
1308     m_strPathExpression =
1309         CMIUtilString::Format("%s.%s", varObjParent.GetNameReal().c_str(),
1310                               varObj.GetNameReal().c_str());
1311   }
1312
1313   return MIstatus::success;
1314 }
1315
1316 //++
1317 // Details: The invoker requires this function. The command prepares a MI Record
1318 // Result
1319 //          for the work carried out in the Execute().
1320 // Type:    Overridden.
1321 // Args:    None.
1322 // Return:  MIstatus::success - Functional succeeded.
1323 //          MIstatus::failure - Functional failed.
1324 // Throws:  None.
1325 //--
1326 bool CMICmdCmdVarInfoPathExpression::Acknowledge() {
1327   if (m_bValueValid) {
1328     const CMICmnMIValueConst miValueConst(m_strPathExpression);
1329     const CMICmnMIValueResult miValueResult("path_expr", miValueConst);
1330     const CMICmnMIResultRecord miRecordResult(
1331         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1332         miValueResult);
1333     m_miResultRecord = miRecordResult;
1334     return MIstatus::success;
1335   }
1336
1337   const CMICmnMIValueConst miValueConst("variable invalid");
1338   const CMICmnMIValueResult miValueResult("msg", miValueConst);
1339   const CMICmnMIResultRecord miRecordResult(
1340       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1341       miValueResult);
1342   m_miResultRecord = miRecordResult;
1343
1344   return MIstatus::success;
1345 }
1346
1347 //++
1348 // Details: Required by the CMICmdFactory when registering *this command. The
1349 // factory
1350 //          calls this function to create an instance of *this command.
1351 // Type:    Static method.
1352 // Args:    None.
1353 // Return:  CMICmdBase * - Pointer to a new command.
1354 // Throws:  None.
1355 //--
1356 CMICmdBase *CMICmdCmdVarInfoPathExpression::CreateSelf() {
1357   return new CMICmdCmdVarInfoPathExpression();
1358 }
1359
1360
1361 //++
1362 // Details: CMICmdCmdVarShowAttributes constructor.
1363 // Type:    Method.
1364 // Args:    None.
1365 // Return:  None.
1366 // Throws:  None.
1367 //--
1368 CMICmdCmdVarShowAttributes::CMICmdCmdVarShowAttributes()
1369     : m_constStrArgName("name") {
1370   // Command factory matches this name with that received from the stdin stream
1371   m_strMiCmd = "var-show-attributes";
1372
1373   // Required by the CMICmdFactory when registering *this command
1374   m_pSelfCreatorFn = &CMICmdCmdVarShowAttributes::CreateSelf;
1375 }
1376
1377 //++
1378 // Details: CMICmdCmdVarShowAttributes destructor.
1379 // Type:    Overrideable.
1380 // Args:    None.
1381 // Return:  None.
1382 // Throws:  None.
1383 //--
1384 CMICmdCmdVarShowAttributes::~CMICmdCmdVarShowAttributes() {}
1385
1386 //++
1387 // Details: The invoker requires this function. The parses the command line
1388 // options
1389 //          arguments to extract values for each of those arguments.
1390 // Type:    Overridden.
1391 // Args:    None.
1392 // Return:  MIstatus::success - Functional succeeded.
1393 //          MIstatus::failure - Functional failed.
1394 // Throws:  None.
1395 //--
1396 bool CMICmdCmdVarShowAttributes::ParseArgs() {
1397   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1398   return ParseValidateCmdOptions();
1399 }
1400
1401 //++
1402 // Details: The invoker requires this function. The command does work in this
1403 // function.
1404 //          The command is likely to communicate with the LLDB SBDebugger in
1405 //          here.
1406 // Type:    Overridden.
1407 // Args:    None.
1408 // Return:  MIstatus::success - Functional succeeded.
1409 //          MIstatus::failure - Functional failed.
1410 // Throws:  None.
1411 //--
1412 bool CMICmdCmdVarShowAttributes::Execute() {
1413   CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1414
1415   const CMIUtilString &rVarObjName(pArgName->GetValue());
1416   CMICmnLLDBDebugSessionInfoVarObj varObj;
1417   if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1418     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1419                                    m_cmdData.strMiCmd.c_str(),
1420                                    rVarObjName.c_str()));
1421     return MIstatus::failure;
1422   }
1423
1424   return MIstatus::success;
1425 }
1426
1427 //++
1428 // Details: The invoker requires this function. The command prepares a MI Record
1429 // Result
1430 //          for the work carried out in the Execute().
1431 // Type:    Overridden.
1432 // Args:    None.
1433 // Return:  MIstatus::success - Functional succeeded.
1434 //          MIstatus::failure - Functional failed.
1435 // Throws:  None.
1436 //--
1437 bool CMICmdCmdVarShowAttributes::Acknowledge() {
1438   // MI output: "%s^done,status=\"editable\"]"
1439   const CMICmnMIValueConst miValueConst("editable");
1440   const CMICmnMIValueResult miValueResult("status", miValueConst);
1441   const CMICmnMIResultRecord miRecordResult(
1442       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1443       miValueResult);
1444   m_miResultRecord = miRecordResult;
1445
1446   return MIstatus::success;
1447 }
1448
1449 //++
1450 // Details: Required by the CMICmdFactory when registering *this command. The
1451 // factory
1452 //          calls this function to create an instance of *this command.
1453 // Type:    Static method.
1454 // Args:    None.
1455 // Return:  CMICmdBase * - Pointer to a new command.
1456 // Throws:  None.
1457 //--
1458 CMICmdBase *CMICmdCmdVarShowAttributes::CreateSelf() {
1459   return new CMICmdCmdVarShowAttributes();
1460 }