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