1 //===-- MICmdCmdVar.cpp -----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // 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.
20 // Third Party Headers:
21 #include "lldb/API/SBStream.h"
22 #include "lldb/API/SBThread.h"
23 #include "lldb/API/SBType.h"
26 #include "MICmdArgValListOfN.h"
27 #include "MICmdArgValNumber.h"
28 #include "MICmdArgValOptionLong.h"
29 #include "MICmdArgValOptionShort.h"
30 #include "MICmdArgValPrintValues.h"
31 #include "MICmdArgValString.h"
32 #include "MICmdArgValThreadGrp.h"
33 #include "MICmdCmdVar.h"
34 #include "MICmnLLDBDebugSessionInfo.h"
35 #include "MICmnLLDBDebugger.h"
36 #include "MICmnLLDBProxySBValue.h"
37 #include "MICmnLLDBUtilSBValue.h"
38 #include "MICmnMIResultRecord.h"
39 #include "MICmnMIValueConst.h"
44 //------------------------------------------------------------------------------------
45 // Details: CMICmdCmdVarCreate constructor.
51 CMICmdCmdVarCreate::CMICmdCmdVarCreate()
52 : m_nChildren(0), m_nThreadId(0), m_strType("??"), m_bValid(false),
53 m_strValue("??"), m_constStrArgName("name"),
54 m_constStrArgFrameAddr("frame-addr"),
55 m_constStrArgExpression("expression") {
56 // Command factory matches this name with that received from the stdin stream
57 m_strMiCmd = "var-create";
59 // Required by the CMICmdFactory when registering *this command
60 m_pSelfCreatorFn = &CMICmdCmdVarCreate::CreateSelf;
64 //------------------------------------------------------------------------------------
65 // Details: CMICmdCmdVarCreate destructor.
66 // Type: Overrideable.
71 CMICmdCmdVarCreate::~CMICmdCmdVarCreate() {}
74 //------------------------------------------------------------------------------------
75 // Details: The invoker requires this function. The parses the command line
77 // arguments to extract values for each of those arguments.
80 // Return: MIstatus::success - Functional succeeded.
81 // MIstatus::failure - Functional failed.
84 bool CMICmdCmdVarCreate::ParseArgs() {
85 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, false, true));
86 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFrameAddr, false, true));
88 new CMICmdArgValString(m_constStrArgExpression, true, true, true, true));
89 return ParseValidateCmdOptions();
93 //------------------------------------------------------------------------------------
94 // Details: The invoker requires this function. The command does work in this
96 // The command is likely to communicate with the LLDB SBDebugger in
100 // Return: MIstatus::success - Functional succeeded.
101 // MIstatus::failure - Functional failed.
104 bool CMICmdCmdVarCreate::Execute() {
105 CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
106 CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
107 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
108 CMICMDBASE_GETOPTION(pArgFrameAddr, String, m_constStrArgFrameAddr);
109 CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
111 // Retrieve the --thread option's thread ID (only 1)
112 MIuint64 nThreadId = UINT64_MAX;
113 if (pArgThread->GetFound() &&
114 !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
115 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
116 m_cmdData.strMiCmd.c_str(),
117 m_constStrArgThread.c_str()));
118 return MIstatus::failure;
121 // Retrieve the --frame option's number
122 MIuint64 nFrame = UINT64_MAX;
123 if (pArgThread->GetFound() &&
124 !pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) {
125 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
126 m_cmdData.strMiCmd.c_str(),
127 m_constStrArgFrame.c_str()));
128 return MIstatus::failure;
131 const CMICmdArgValOptionLong::VecArgObjPtr_t &rVecFrameId(
132 pArgFrame->GetExpectedOptions());
133 CMICmdArgValOptionLong::VecArgObjPtr_t::const_iterator it2 =
135 if (it2 != rVecFrameId.end()) {
136 const CMICmdArgValNumber *pOption = static_cast<CMICmdArgValNumber *>(*it2);
137 nFrame = pOption->GetValue();
140 m_strVarName = "<unnamedvariable>";
141 if (pArgName->GetFound()) {
142 const CMIUtilString &rArg = pArgName->GetValue();
143 const bool bAutoName = (rArg == "-");
145 m_strVarName = CMIUtilString::Format(
146 "var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet());
147 CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
152 bool bCurrentFrame = false;
153 if (pArgFrameAddr->GetFound()) {
154 const CMIUtilString &rStrFrameAddr(pArgFrameAddr->GetValue());
155 bCurrentFrame = CMIUtilString::Compare(rStrFrameAddr, "*");
156 if (!bCurrentFrame && (nFrame == UINT64_MAX)) {
157 // FIXME: *addr isn't implemented. Exit with error if --thread isn't
159 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
160 m_cmdData.strMiCmd.c_str(),
161 m_constStrArgFrame.c_str()));
162 return MIstatus::failure;
166 const CMIUtilString &rStrExpression(pArgExpression->GetValue());
167 m_strExpression = rStrExpression;
169 CMICmnLLDBDebugSessionInfo &rSessionInfo(
170 CMICmnLLDBDebugSessionInfo::Instance());
171 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
172 lldb::SBThread thread = (nThreadId != UINT64_MAX)
173 ? sbProcess.GetThreadByIndexID(nThreadId)
174 : sbProcess.GetSelectedThread();
175 m_nThreadId = thread.GetIndexID();
176 lldb::SBFrame frame = bCurrentFrame ? thread.GetSelectedFrame()
177 : thread.GetFrameAtIndex(nFrame);
180 if (rStrExpression[0] == '$') {
181 const CMIUtilString rStrRegister(rStrExpression.substr(1));
182 value = frame.FindRegister(rStrRegister.c_str());
184 const bool bArgs = true;
185 const bool bLocals = true;
186 const bool bStatics = true;
187 const bool bInScopeOnly = true;
188 const lldb::SBValueList valueList =
189 frame.GetVariables(bArgs, bLocals, bStatics, bInScopeOnly);
190 value = valueList.GetFirstValueByName(rStrExpression.c_str());
193 if (!value.IsValid())
194 value = frame.EvaluateExpression(rStrExpression.c_str());
196 if (value.IsValid() && value.GetError().Success()) {
197 CompleteSBValue(value);
199 m_nChildren = value.GetNumChildren();
200 m_strType = CMICmnLLDBUtilSBValue(value).GetTypeNameDisplay();
202 // This gets added to CMICmnLLDBDebugSessionInfoVarObj static container of
204 CMICmnLLDBDebugSessionInfoVarObj varObj(rStrExpression, m_strVarName,
206 m_strValue = varObj.GetValueFormatted();
208 m_strValue = value.GetError().GetCString();
211 return MIstatus::success;
215 //------------------------------------------------------------------------------------
216 // Details: The invoker requires this function. The command prepares a MI Record
218 // for the work carried out in the Execute().
221 // Return: MIstatus::success - Functional succeeded.
222 // MIstatus::failure - Functional failed.
225 bool CMICmdCmdVarCreate::Acknowledge() {
228 // "%s^done,name=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%llu\",has_more=\"%u\""
229 const CMICmnMIValueConst miValueConst(m_strVarName);
230 CMICmnMIValueResult miValueResultAll("name", miValueConst);
231 const CMIUtilString strNumChild(CMIUtilString::Format("%d", m_nChildren));
232 const CMICmnMIValueConst miValueConst2(strNumChild);
233 miValueResultAll.Add("numchild", miValueConst2);
234 const CMICmnMIValueConst miValueConst3(m_strValue);
235 miValueResultAll.Add("value", miValueConst3);
236 const CMICmnMIValueConst miValueConst4(m_strType);
237 miValueResultAll.Add("type", miValueConst4);
238 const CMIUtilString strThreadId(CMIUtilString::Format("%llu", m_nThreadId));
239 const CMICmnMIValueConst miValueConst5(strThreadId);
240 miValueResultAll.Add("thread-id", miValueConst5);
241 const CMICmnMIValueConst miValueConst6("0");
242 miValueResultAll.Add("has_more", miValueConst6);
244 const CMICmnMIResultRecord miRecordResult(
245 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
247 m_miResultRecord = miRecordResult;
249 return MIstatus::success;
252 CMIUtilString strErrMsg(m_strValue);
253 if (m_strValue.empty())
254 strErrMsg = CMIUtilString::Format(
255 MIRSRC(IDS_CMD_ERR_VARIABLE_CREATION_FAILED), m_strExpression.c_str());
256 const CMICmnMIValueConst miValueConst(
257 strErrMsg.Escape(true /* vbEscapeQuotes */));
258 CMICmnMIValueResult miValueResult("msg", miValueConst);
259 const CMICmnMIResultRecord miRecordResult(
260 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
262 m_miResultRecord = miRecordResult;
264 return MIstatus::success;
268 //------------------------------------------------------------------------------------
269 // Details: Required by the CMICmdFactory when registering *this command. The
271 // calls this function to create an instance of *this command.
272 // Type: Static method.
274 // Return: CMICmdBase * - Pointer to a new command.
277 CMICmdBase *CMICmdCmdVarCreate::CreateSelf() {
278 return new CMICmdCmdVarCreate();
282 //------------------------------------------------------------------------------------
283 // Details: Complete SBValue object and its children to get
284 // SBValue::GetValueDidChange
287 // Args: vrwValue - (R) Value to update.
288 // Return: MIstatus::success - Functional succeeded.
289 // MIstatus::failure - Functional failed.
292 void CMICmdCmdVarCreate::CompleteSBValue(lldb::SBValue &vrwValue) {
293 // Force a value to update
294 vrwValue.GetValueDidChange();
296 // And update its children
297 lldb::SBType valueType = vrwValue.GetType();
298 if (!valueType.IsPointerType() && !valueType.IsReferenceType()) {
299 const MIuint nChildren = vrwValue.GetNumChildren();
300 for (MIuint i = 0; i < nChildren; ++i) {
301 lldb::SBValue member = vrwValue.GetChildAtIndex(i);
302 if (member.IsValid())
303 CompleteSBValue(member);
308 //---------------------------------------------------------------------------------------
309 //---------------------------------------------------------------------------------------
310 //---------------------------------------------------------------------------------------
313 //------------------------------------------------------------------------------------
314 // Details: CMICmdCmdVarUpdate constructor.
320 CMICmdCmdVarUpdate::CMICmdCmdVarUpdate()
321 : m_constStrArgPrintValues("print-values"), m_constStrArgName("name"),
322 m_bValueChanged(false), m_miValueList(true) {
323 // Command factory matches this name with that received from the stdin stream
324 m_strMiCmd = "var-update";
326 // Required by the CMICmdFactory when registering *this command
327 m_pSelfCreatorFn = &CMICmdCmdVarUpdate::CreateSelf;
331 //------------------------------------------------------------------------------------
332 // Details: CMICmdCmdVarUpdate destructor.
333 // Type: Overrideable.
338 CMICmdCmdVarUpdate::~CMICmdCmdVarUpdate() {}
341 //------------------------------------------------------------------------------------
342 // Details: The invoker requires this function. The parses the command line
344 // arguments to extract values for each of those arguments.
347 // Return: MIstatus::success - Functional succeeded.
348 // MIstatus::failure - Functional failed.
351 bool CMICmdCmdVarUpdate::ParseArgs() {
353 new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
354 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
355 return ParseValidateCmdOptions();
359 //------------------------------------------------------------------------------------
360 // Details: The invoker requires this function. The command does work in this
362 // The command is likely to communicate with the LLDB SBDebugger in
366 // Return: MIstatus::success - Functional succeeded.
367 // MIstatus::failure - Functional failed.
370 bool CMICmdCmdVarUpdate::Execute() {
371 CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
372 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
374 CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
375 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
376 if (pArgPrintValues->GetFound())
378 static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
379 pArgPrintValues->GetValue());
381 const CMIUtilString &rVarObjName(pArgName->GetValue());
382 CMICmnLLDBDebugSessionInfoVarObj varObj;
383 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
384 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
385 m_cmdData.strMiCmd.c_str(),
386 rVarObjName.c_str()));
387 return MIstatus::failure;
390 lldb::SBValue &rValue = varObj.GetValue();
391 if (!ExamineSBValueForChange(rValue, m_bValueChanged))
392 return MIstatus::failure;
394 if (m_bValueChanged) {
395 varObj.UpdateValue();
396 const bool bPrintValue(
398 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues) ||
400 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues &&
401 rValue.GetNumChildren() == 0));
402 const CMIUtilString strValue(bPrintValue ? varObj.GetValueFormatted() : "");
403 const CMIUtilString strInScope(rValue.IsInScope() ? "true" : "false");
404 MIFormResponse(rVarObjName, bPrintValue ? strValue.c_str() : nullptr,
408 return MIstatus::success;
412 //------------------------------------------------------------------------------------
413 // Details: The invoker requires this function. The command prepares a MI Record
415 // for the work carried out in the Execute().
418 // Return: MIstatus::success - Functional succeeded.
419 // MIstatus::failure - Functional failed.
422 bool CMICmdCmdVarUpdate::Acknowledge() {
423 if (m_bValueChanged) {
425 // "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
426 CMICmnMIValueResult miValueResult("changelist", m_miValueList);
427 const CMICmnMIResultRecord miRecordResult(
428 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
430 m_miResultRecord = miRecordResult;
432 // MI print "%s^done,changelist=[]"
433 const CMICmnMIValueList miValueList(true);
434 CMICmnMIValueResult miValueResult6("changelist", miValueList);
435 const CMICmnMIResultRecord miRecordResult(
436 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
438 m_miResultRecord = miRecordResult;
441 return MIstatus::success;
445 //------------------------------------------------------------------------------------
446 // Details: Required by the CMICmdFactory when registering *this command. The
448 // calls this function to create an instance of *this command.
449 // Type: Static method.
451 // Return: CMICmdBase * - Pointer to a new command.
454 CMICmdBase *CMICmdCmdVarUpdate::CreateSelf() {
455 return new CMICmdCmdVarUpdate();
459 //------------------------------------------------------------------------------------
460 // Details: Form the MI response for multiple variables.
462 // Args: vrStrVarName - (R) Session var object's name.
463 // vpValue - (R) Text version of the value held in the
465 // vrStrScope - (R) In scope "yes" or "no".
469 void CMICmdCmdVarUpdate::MIFormResponse(const CMIUtilString &vrStrVarName,
470 const char *const vpValue,
471 const CMIUtilString &vrStrScope) {
473 // "[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
474 const CMICmnMIValueConst miValueConst(vrStrVarName);
475 const CMICmnMIValueResult miValueResult("name", miValueConst);
476 CMICmnMIValueTuple miValueTuple(miValueResult);
477 if (vpValue != nullptr) {
478 const CMICmnMIValueConst miValueConst2(vpValue);
479 const CMICmnMIValueResult miValueResult2("value", miValueConst2);
480 miValueTuple.Add(miValueResult2);
482 const CMICmnMIValueConst miValueConst3(vrStrScope);
483 const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
484 miValueTuple.Add(miValueResult3);
485 const CMICmnMIValueConst miValueConst4("false");
486 const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
487 miValueTuple.Add(miValueResult4);
488 const CMICmnMIValueConst miValueConst5("0");
489 const CMICmnMIValueResult miValueResult5("has_more", miValueConst5);
490 miValueTuple.Add(miValueResult5);
491 m_miValueList.Add(miValueTuple);
495 //------------------------------------------------------------------------------------
496 // Details: Determine if the var object was changed.
498 // Args: vrVarObj - (R) Session var object to examine.
499 // vrwbChanged - (W) True = The var object was changed,
500 // False = It was not changed.
501 // Return: MIstatus::success - Functional succeeded.
502 // MIstatus::failure - Functional failed.
505 bool CMICmdCmdVarUpdate::ExamineSBValueForChange(lldb::SBValue &vrwValue,
507 if (vrwValue.GetValueDidChange()) {
509 return MIstatus::success;
512 lldb::SBType valueType = vrwValue.GetType();
513 if (!valueType.IsPointerType() && !valueType.IsReferenceType()) {
514 const MIuint nChildren = vrwValue.GetNumChildren();
515 for (MIuint i = 0; i < nChildren; ++i) {
516 lldb::SBValue member = vrwValue.GetChildAtIndex(i);
517 if (!member.IsValid())
520 if (member.GetValueDidChange()) {
522 return MIstatus::success;
523 } else if (ExamineSBValueForChange(member, vrwbChanged) && vrwbChanged)
524 // Handle composite types (i.e. struct or arrays)
525 return MIstatus::success;
530 return MIstatus::success;
533 //---------------------------------------------------------------------------------------
534 //---------------------------------------------------------------------------------------
535 //---------------------------------------------------------------------------------------
538 //------------------------------------------------------------------------------------
539 // Details: CMICmdCmdVarDelete constructor.
545 CMICmdCmdVarDelete::CMICmdCmdVarDelete() : m_constStrArgName("name") {
546 // Command factory matches this name with that received from the stdin stream
547 m_strMiCmd = "var-delete";
549 // Required by the CMICmdFactory when registering *this command
550 m_pSelfCreatorFn = &CMICmdCmdVarDelete::CreateSelf;
554 //------------------------------------------------------------------------------------
555 // Details: The invoker requires this function. The parses the command line
557 // arguments to extract values for each of those arguments.
560 // Return: MIstatus::success - Functional succeeded.
561 // MIstatus::failure - Functional failed.
564 bool CMICmdCmdVarDelete::ParseArgs() {
565 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
566 return ParseValidateCmdOptions();
570 //------------------------------------------------------------------------------------
571 // Details: CMICmdCmdVarDelete destructor.
572 // Type: Overrideable.
577 CMICmdCmdVarDelete::~CMICmdCmdVarDelete() {}
580 //------------------------------------------------------------------------------------
581 // Details: The invoker requires this function. The command does work in this
583 // The command is likely to communicate with the LLDB SBDebugger in
587 // Return: MIstatus::success - Functional succeeded.
588 // MIstatus::failure - Functional failed.
591 bool CMICmdCmdVarDelete::Execute() {
592 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
594 const CMIUtilString &rVarObjName(pArgName->GetValue());
595 CMICmnLLDBDebugSessionInfoVarObj::VarObjDelete(rVarObjName);
597 return MIstatus::success;
601 //------------------------------------------------------------------------------------
602 // Details: The invoker requires this function. The command prepares a MI Record
604 // for the work carried out in the Execute().
607 // Return: MIstatus::success - Functional succeeded.
608 // MIstatus::failure - Functional failed.
611 bool CMICmdCmdVarDelete::Acknowledge() {
612 const CMICmnMIResultRecord miRecordResult(
613 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
614 m_miResultRecord = miRecordResult;
616 return MIstatus::success;
620 //------------------------------------------------------------------------------------
621 // Details: Required by the CMICmdFactory when registering *this command. The
623 // calls this function to create an instance of *this command.
624 // Type: Static method.
626 // Return: CMICmdBase * - Pointer to a new command.
629 CMICmdBase *CMICmdCmdVarDelete::CreateSelf() {
630 return new CMICmdCmdVarDelete();
633 //---------------------------------------------------------------------------------------
634 //---------------------------------------------------------------------------------------
635 //---------------------------------------------------------------------------------------
638 //------------------------------------------------------------------------------------
639 // Details: CMICmdCmdVarAssign constructor.
645 CMICmdCmdVarAssign::CMICmdCmdVarAssign()
646 : m_bOk(true), m_constStrArgName("name"),
647 m_constStrArgExpression("expression") {
648 // Command factory matches this name with that received from the stdin stream
649 m_strMiCmd = "var-assign";
651 // Required by the CMICmdFactory when registering *this command
652 m_pSelfCreatorFn = &CMICmdCmdVarAssign::CreateSelf;
656 //------------------------------------------------------------------------------------
657 // Details: CMICmdCmdVarAssign destructor.
658 // Type: Overrideable.
663 CMICmdCmdVarAssign::~CMICmdCmdVarAssign() {}
666 //------------------------------------------------------------------------------------
667 // Details: The invoker requires this function. The parses the command line
669 // arguments to extract values for each of those arguments.
672 // Return: MIstatus::success - Functional succeeded.
673 // MIstatus::failure - Functional failed.
676 bool CMICmdCmdVarAssign::ParseArgs() {
677 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
678 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgExpression, true, true));
679 return ParseValidateCmdOptions();
683 //------------------------------------------------------------------------------------
684 // Details: The invoker requires this function. The command does work in this
686 // The command is likely to communicate with the LLDB SBDebugger in
690 // Return: MIstatus::success - Functional succeeded.
691 // MIstatus::failure - Functional failed.
694 bool CMICmdCmdVarAssign::Execute() {
695 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
696 CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
698 const CMIUtilString &rVarObjName(pArgName->GetValue());
699 const CMIUtilString &rExpression(pArgExpression->GetValue());
701 CMICmnLLDBDebugSessionInfoVarObj varObj;
702 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
703 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
704 m_cmdData.strMiCmd.c_str(),
705 rVarObjName.c_str()));
706 return MIstatus::failure;
708 m_varObjName = rVarObjName;
710 CMIUtilString strExpression(rExpression.Trim());
711 strExpression = strExpression.Trim('"');
712 lldb::SBValue &rValue(const_cast<lldb::SBValue &>(varObj.GetValue()));
713 m_bOk = rValue.SetValueFromCString(strExpression.c_str());
715 varObj.UpdateValue();
717 return MIstatus::success;
721 //------------------------------------------------------------------------------------
722 // Details: The invoker requires this function. The command prepares a MI Record
724 // for the work carried out in the Execute().
727 // Return: MIstatus::success - Functional succeeded.
728 // MIstatus::failure - Functional failed.
731 bool CMICmdCmdVarAssign::Acknowledge() {
733 // MI print "%s^done,value=\"%s\""
734 CMICmnLLDBDebugSessionInfoVarObj varObj;
735 CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
736 const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
737 const CMICmnMIValueResult miValueResult("value", miValueConst);
738 const CMICmnMIResultRecord miRecordResult(
739 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
741 m_miResultRecord = miRecordResult;
743 return MIstatus::success;
746 const CMICmnMIValueConst miValueConst("expression could not be evaluated");
747 const CMICmnMIValueResult miValueResult("msg", miValueConst);
748 const CMICmnMIResultRecord miRecordResult(
749 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
751 m_miResultRecord = miRecordResult;
753 return MIstatus::success;
757 //------------------------------------------------------------------------------------
758 // Details: Required by the CMICmdFactory when registering *this command. The
760 // calls this function to create an instance of *this command.
761 // Type: Static method.
763 // Return: CMICmdBase * - Pointer to a new command.
766 CMICmdBase *CMICmdCmdVarAssign::CreateSelf() {
767 return new CMICmdCmdVarAssign();
770 //---------------------------------------------------------------------------------------
771 //---------------------------------------------------------------------------------------
772 //---------------------------------------------------------------------------------------
775 //------------------------------------------------------------------------------------
776 // Details: CMICmdCmdVarSetFormat constructor.
782 CMICmdCmdVarSetFormat::CMICmdCmdVarSetFormat()
783 : m_constStrArgName("name"), m_constStrArgFormatSpec("format-spec") {
784 // Command factory matches this name with that received from the stdin stream
785 m_strMiCmd = "var-set-format";
787 // Required by the CMICmdFactory when registering *this command
788 m_pSelfCreatorFn = &CMICmdCmdVarSetFormat::CreateSelf;
792 //------------------------------------------------------------------------------------
793 // Details: CMICmdCmdVarSetFormat destructor.
794 // Type: Overrideable.
799 CMICmdCmdVarSetFormat::~CMICmdCmdVarSetFormat() {}
802 //------------------------------------------------------------------------------------
803 // Details: The invoker requires this function. The parses the command line
805 // arguments to extract values for each of those arguments.
808 // Return: MIstatus::success - Functional succeeded.
809 // MIstatus::failure - Functional failed.
812 bool CMICmdCmdVarSetFormat::ParseArgs() {
813 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
814 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFormatSpec, true, true));
815 return ParseValidateCmdOptions();
819 //------------------------------------------------------------------------------------
820 // Details: The invoker requires this function. The command does work in this
822 // The command is likely to communicate with the LLDB SBDebugger in
826 // Return: MIstatus::success - Functional succeeded.
827 // MIstatus::failure - Functional failed.
830 bool CMICmdCmdVarSetFormat::Execute() {
831 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
832 CMICMDBASE_GETOPTION(pArgFormatSpec, String, m_constStrArgFormatSpec);
834 const CMIUtilString &rVarObjName(pArgName->GetValue());
835 const CMIUtilString &rExpression(pArgFormatSpec->GetValue());
837 CMICmnLLDBDebugSessionInfoVarObj varObj;
838 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
839 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
840 m_cmdData.strMiCmd.c_str(),
841 rVarObjName.c_str()));
842 return MIstatus::failure;
844 if (!varObj.SetVarFormat(
845 CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString(
847 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_ENUM_INVALID),
848 m_cmdData.strMiCmd.c_str(),
849 rVarObjName.c_str(), rExpression.c_str()));
850 return MIstatus::failure;
852 varObj.UpdateValue();
854 m_varObjName = rVarObjName;
856 return MIstatus::success;
860 //------------------------------------------------------------------------------------
861 // Details: The invoker requires this function. The command prepares a MI Record
863 // for the work carried out in the Execute().
866 // Return: MIstatus::success - Functional succeeded.
867 // MIstatus::failure - Functional failed.
870 bool CMICmdCmdVarSetFormat::Acknowledge() {
872 // "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
873 CMICmnLLDBDebugSessionInfoVarObj varObj;
874 CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
875 const CMICmnMIValueConst miValueConst(m_varObjName);
876 const CMICmnMIValueResult miValueResult("name", miValueConst);
877 CMICmnMIValueTuple miValueTuple(miValueResult);
878 const CMICmnMIValueConst miValueConst2(varObj.GetValueFormatted());
879 const CMICmnMIValueResult miValueResult2("value", miValueConst2);
880 miValueTuple.Add(miValueResult2);
881 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
882 const CMICmnMIValueConst miValueConst3(rValue.IsInScope() ? "true" : "false");
883 const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
884 miValueTuple.Add(miValueResult3);
885 const CMICmnMIValueConst miValueConst4("false");
886 const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
887 miValueTuple.Add(miValueResult4);
888 const CMICmnMIValueConst miValueConst5("0");
889 const CMICmnMIValueResult miValueResult5("type_changed", miValueConst5);
890 miValueTuple.Add(miValueResult5);
891 const CMICmnMIValueList miValueList(miValueTuple);
892 const CMICmnMIValueResult miValueResult6("changelist", miValueList);
894 const CMICmnMIResultRecord miRecordResult(
895 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
897 m_miResultRecord = miRecordResult;
899 return MIstatus::success;
903 //------------------------------------------------------------------------------------
904 // Details: Required by the CMICmdFactory when registering *this command. The
906 // calls this function to create an instance of *this command.
907 // Type: Static method.
909 // Return: CMICmdBase * - Pointer to a new command.
912 CMICmdBase *CMICmdCmdVarSetFormat::CreateSelf() {
913 return new CMICmdCmdVarSetFormat();
916 //---------------------------------------------------------------------------------------
917 //---------------------------------------------------------------------------------------
918 //---------------------------------------------------------------------------------------
921 //------------------------------------------------------------------------------------
922 // Details: CMICmdCmdVarListChildren constructor.
928 CMICmdCmdVarListChildren::CMICmdCmdVarListChildren()
929 : m_constStrArgPrintValues("print-values"), m_constStrArgName("name"),
930 m_constStrArgFrom("from"), m_constStrArgTo("to"), m_bValueValid(false),
931 m_nChildren(0), m_miValueList(true), m_bHasMore(false) {
932 // Command factory matches this name with that received from the stdin stream
933 m_strMiCmd = "var-list-children";
935 // Required by the CMICmdFactory when registering *this command
936 m_pSelfCreatorFn = &CMICmdCmdVarListChildren::CreateSelf;
940 //------------------------------------------------------------------------------------
941 // Details: CMICmdCmdVarListChildren destructor.
942 // Type: Overrideable.
947 CMICmdCmdVarListChildren::~CMICmdCmdVarListChildren() {}
950 //------------------------------------------------------------------------------------
951 // Details: The invoker requires this function. The parses the command line
953 // arguments to extract values for each of those arguments.
956 // Return: MIstatus::success - Functional succeeded.
957 // MIstatus::failure - Functional failed.
960 bool CMICmdCmdVarListChildren::ParseArgs() {
962 new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
963 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true, true));
964 m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrom, false, true));
965 m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgTo, false, true));
966 return ParseValidateCmdOptions();
970 //------------------------------------------------------------------------------------
971 // Details: The invoker requires this function. The command does work in this
973 // The command is likely to communicate with the LLDB SBDebugger in
977 // Return: MIstatus::success - Functional succeeded.
978 // MIstatus::failure - Functional failed.
981 bool CMICmdCmdVarListChildren::Execute() {
982 CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
983 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
984 CMICMDBASE_GETOPTION(pArgFrom, Number, m_constStrArgFrom);
985 CMICMDBASE_GETOPTION(pArgTo, Number, m_constStrArgTo);
987 CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
988 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
989 if (pArgPrintValues->GetFound())
991 static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
992 pArgPrintValues->GetValue());
994 const CMIUtilString &rVarObjName(pArgName->GetValue());
995 CMICmnLLDBDebugSessionInfoVarObj varObj;
996 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
997 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
998 m_cmdData.strMiCmd.c_str(),
999 rVarObjName.c_str()));
1000 return MIstatus::failure;
1004 MIuint nTo = UINT32_MAX;
1005 if (pArgFrom->GetFound() && pArgTo->GetFound()) {
1006 nFrom = pArgFrom->GetValue();
1007 nTo = pArgTo->GetValue();
1008 } else if (pArgFrom->GetFound() || pArgTo->GetFound()) {
1009 // Only from or to was specified but both are required
1011 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID),
1012 m_cmdData.strMiCmd.c_str()));
1013 return MIstatus::failure;
1016 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1017 m_bValueValid = rValue.IsValid();
1019 return MIstatus::success;
1021 const MIuint nChildren = rValue.GetNumChildren();
1022 m_bHasMore = nTo < nChildren;
1023 nTo = std::min(nTo, nChildren);
1024 m_nChildren = nFrom < nTo ? nTo - nFrom : 0;
1025 for (MIuint i = nFrom; i < nTo; i++) {
1026 lldb::SBValue member = rValue.GetChildAtIndex(i);
1027 const CMICmnLLDBUtilSBValue utilValue(member);
1028 const CMIUtilString strExp = utilValue.GetName();
1029 const CMIUtilString name(
1030 strExp.empty() ? CMIUtilString::Format("%s.$%u", rVarObjName.c_str(), i)
1031 : CMIUtilString::Format("%s.%s", rVarObjName.c_str(),
1033 const MIuint nChildren = member.GetNumChildren();
1034 const CMIUtilString strThreadId(
1035 CMIUtilString::Format("%u", member.GetThread().GetIndexID()));
1037 // Varobj gets added to CMICmnLLDBDebugSessionInfoVarObj static container of
1039 CMICmnLLDBDebugSessionInfoVarObj var(strExp, name, member, rVarObjName);
1042 // "child={name=\"%s\",exp=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%u\",has_more=\"%u\"}"
1043 const CMICmnMIValueConst miValueConst(name);
1044 const CMICmnMIValueResult miValueResult("name", miValueConst);
1045 CMICmnMIValueTuple miValueTuple(miValueResult);
1046 const CMICmnMIValueConst miValueConst2(strExp);
1047 const CMICmnMIValueResult miValueResult2("exp", miValueConst2);
1048 miValueTuple.Add(miValueResult2);
1049 const CMIUtilString strNumChild(CMIUtilString::Format("%u", nChildren));
1050 const CMICmnMIValueConst miValueConst3(strNumChild);
1051 const CMICmnMIValueResult miValueResult3("numchild", miValueConst3);
1052 miValueTuple.Add(miValueResult3);
1053 const CMICmnMIValueConst miValueConst5(utilValue.GetTypeNameDisplay());
1054 const CMICmnMIValueResult miValueResult5("type", miValueConst5);
1055 miValueTuple.Add(miValueResult5);
1056 const CMICmnMIValueConst miValueConst6(strThreadId);
1057 const CMICmnMIValueResult miValueResult6("thread-id", miValueConst6);
1058 miValueTuple.Add(miValueResult6);
1059 // nChildren == 0 is used to check for simple values
1060 if (eVarInfoFormat ==
1061 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues ||
1063 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues &&
1065 const CMIUtilString strValue(
1066 CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(
1067 member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural));
1068 const CMICmnMIValueConst miValueConst7(strValue);
1069 const CMICmnMIValueResult miValueResult7("value", miValueConst7);
1070 miValueTuple.Add(miValueResult7);
1072 const CMICmnMIValueConst miValueConst8("0");
1073 const CMICmnMIValueResult miValueResult8("has_more", miValueConst8);
1074 miValueTuple.Add(miValueResult8);
1075 const CMICmnMIValueResult miValueResult9("child", miValueTuple);
1076 m_miValueList.Add(miValueResult9);
1079 return MIstatus::success;
1083 //------------------------------------------------------------------------------------
1084 // Details: The invoker requires this function. The command prepares a MI Record
1086 // for the work carried out in the Execute().
1087 // Type: Overridden.
1089 // Return: MIstatus::success - Functional succeeded.
1090 // MIstatus::failure - Functional failed.
1093 bool CMICmdCmdVarListChildren::Acknowledge() {
1094 if (m_bValueValid) {
1095 // MI print "%s^done,numchild=\"%u\",children=[%s],has_more=\"%d\""
1096 const CMIUtilString strNumChild(CMIUtilString::Format("%u", m_nChildren));
1097 const CMICmnMIValueConst miValueConst(strNumChild);
1098 CMICmnMIValueResult miValueResult("numchild", miValueConst);
1099 if (m_nChildren != 0)
1100 miValueResult.Add("children", m_miValueList);
1101 const CMIUtilString strHasMore(m_bHasMore ? "1" : "0");
1102 const CMICmnMIValueConst miValueConst2(strHasMore);
1103 miValueResult.Add("has_more", miValueConst2);
1105 const CMICmnMIResultRecord miRecordResult(
1106 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1108 m_miResultRecord = miRecordResult;
1110 return MIstatus::success;
1113 // MI print "%s^error,msg=\"variable invalid\""
1114 const CMICmnMIValueConst miValueConst("variable invalid");
1115 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1116 const CMICmnMIResultRecord miRecordResult(
1117 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1119 m_miResultRecord = miRecordResult;
1121 return MIstatus::success;
1125 //------------------------------------------------------------------------------------
1126 // Details: Required by the CMICmdFactory when registering *this command. The
1128 // calls this function to create an instance of *this command.
1129 // Type: Static method.
1131 // Return: CMICmdBase * - Pointer to a new command.
1134 CMICmdBase *CMICmdCmdVarListChildren::CreateSelf() {
1135 return new CMICmdCmdVarListChildren();
1138 //---------------------------------------------------------------------------------------
1139 //---------------------------------------------------------------------------------------
1140 //---------------------------------------------------------------------------------------
1143 //------------------------------------------------------------------------------------
1144 // Details: CMICmdCmdVarEvaluateExpression constructor.
1150 CMICmdCmdVarEvaluateExpression::CMICmdCmdVarEvaluateExpression()
1151 : m_bValueValid(true), m_constStrArgFormatSpec("-f"),
1152 m_constStrArgName("name") {
1153 // Command factory matches this name with that received from the stdin stream
1154 m_strMiCmd = "var-evaluate-expression";
1156 // Required by the CMICmdFactory when registering *this command
1157 m_pSelfCreatorFn = &CMICmdCmdVarEvaluateExpression::CreateSelf;
1161 //------------------------------------------------------------------------------------
1162 // Details: CMICmdCmdVarEvaluateExpression destructor.
1163 // Type: Overrideable.
1168 CMICmdCmdVarEvaluateExpression::~CMICmdCmdVarEvaluateExpression() {}
1171 //------------------------------------------------------------------------------------
1172 // Details: The invoker requires this function. The parses the command line
1174 // arguments to extract values for each of those arguments.
1175 // Type: Overridden.
1177 // Return: MIstatus::success - Functional succeeded.
1178 // MIstatus::failure - Functional failed.
1181 bool CMICmdCmdVarEvaluateExpression::ParseArgs() {
1183 new CMICmdArgValOptionShort(m_constStrArgFormatSpec, false, false,
1184 CMICmdArgValListBase::eArgValType_String, 1));
1185 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1186 return ParseValidateCmdOptions();
1190 //------------------------------------------------------------------------------------
1191 // Details: The invoker requires this function. The command does work in this
1193 // The command is likely to communicate with the LLDB SBDebugger in
1195 // Type: Overridden.
1197 // Return: MIstatus::success - Functional succeeded.
1198 // MIstatus::failure - Functional failed.
1201 bool CMICmdCmdVarEvaluateExpression::Execute() {
1202 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1204 const CMIUtilString &rVarObjName(pArgName->GetValue());
1205 CMICmnLLDBDebugSessionInfoVarObj varObj;
1206 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1207 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1208 m_cmdData.strMiCmd.c_str(),
1209 rVarObjName.c_str()));
1210 return MIstatus::failure;
1213 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1214 m_bValueValid = rValue.IsValid();
1216 return MIstatus::success;
1218 m_varObjName = rVarObjName;
1219 varObj.UpdateValue();
1221 return MIstatus::success;
1225 //------------------------------------------------------------------------------------
1226 // Details: The invoker requires this function. The command prepares a MI Record
1228 // for the work carried out in the Execute().
1229 // Type: Overridden.
1231 // Return: MIstatus::success - Functional succeeded.
1232 // MIstatus::failure - Functional failed.
1235 bool CMICmdCmdVarEvaluateExpression::Acknowledge() {
1236 if (m_bValueValid) {
1237 CMICmnLLDBDebugSessionInfoVarObj varObj;
1238 CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
1239 const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
1240 const CMICmnMIValueResult miValueResult("value", miValueConst);
1241 const CMICmnMIResultRecord miRecordResult(
1242 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1244 m_miResultRecord = miRecordResult;
1245 return MIstatus::success;
1248 const CMICmnMIValueConst miValueConst("variable invalid");
1249 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1250 const CMICmnMIResultRecord miRecordResult(
1251 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1253 m_miResultRecord = miRecordResult;
1254 return MIstatus::success;
1258 //------------------------------------------------------------------------------------
1259 // Details: Required by the CMICmdFactory when registering *this command. The
1261 // calls this function to create an instance of *this command.
1262 // Type: Static method.
1264 // Return: CMICmdBase * - Pointer to a new command.
1267 CMICmdBase *CMICmdCmdVarEvaluateExpression::CreateSelf() {
1268 return new CMICmdCmdVarEvaluateExpression();
1271 //---------------------------------------------------------------------------------------
1272 //---------------------------------------------------------------------------------------
1273 //---------------------------------------------------------------------------------------
1276 //------------------------------------------------------------------------------------
1277 // Details: CMICmdCmdVarInfoPathExpression constructor.
1283 CMICmdCmdVarInfoPathExpression::CMICmdCmdVarInfoPathExpression()
1284 : m_bValueValid(true), m_constStrArgName("name") {
1285 // Command factory matches this name with that received from the stdin stream
1286 m_strMiCmd = "var-info-path-expression";
1288 // Required by the CMICmdFactory when registering *this command
1289 m_pSelfCreatorFn = &CMICmdCmdVarInfoPathExpression::CreateSelf;
1293 //------------------------------------------------------------------------------------
1294 // Details: CMICmdCmdVarInfoPathExpression destructor.
1295 // Type: Overrideable.
1300 CMICmdCmdVarInfoPathExpression::~CMICmdCmdVarInfoPathExpression() {}
1303 //------------------------------------------------------------------------------------
1304 // Details: The invoker requires this function. The parses the command line
1306 // arguments to extract values for each of those arguments.
1307 // Type: Overridden.
1309 // Return: MIstatus::success - Functional succeeded.
1310 // MIstatus::failure - Functional failed.
1313 bool CMICmdCmdVarInfoPathExpression::ParseArgs() {
1314 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1315 return ParseValidateCmdOptions();
1319 //------------------------------------------------------------------------------------
1320 // Details: The invoker requires this function. The command does work in this
1322 // The command is likely to communicate with the LLDB SBDebugger in
1324 // Type: Overridden.
1326 // Return: MIstatus::success - Functional succeeded.
1327 // MIstatus::failure - Functional failed.
1330 bool CMICmdCmdVarInfoPathExpression::Execute() {
1331 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1333 const CMIUtilString &rVarObjName(pArgName->GetValue());
1334 CMICmnLLDBDebugSessionInfoVarObj varObj;
1335 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1336 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1337 m_cmdData.strMiCmd.c_str(),
1338 rVarObjName.c_str()));
1339 return MIstatus::failure;
1342 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1343 m_bValueValid = rValue.IsValid();
1345 return MIstatus::success;
1347 lldb::SBStream stream;
1348 if (!rValue.GetExpressionPath(stream, true)) {
1349 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH),
1350 m_cmdData.strMiCmd.c_str(),
1351 rVarObjName.c_str()));
1352 return MIstatus::failure;
1355 const char *pPathExpression = stream.GetData();
1356 if (pPathExpression == nullptr) {
1357 // Build expression from what we do know
1358 m_strPathExpression = varObj.GetNameReal();
1359 return MIstatus::success;
1362 // Has LLDB returned a var signature of it's own
1363 if (pPathExpression[0] != '$') {
1364 m_strPathExpression = pPathExpression;
1365 return MIstatus::success;
1368 // Build expression from what we do know
1369 const CMIUtilString &rVarParentName(varObj.GetVarParentName());
1370 if (rVarParentName.empty()) {
1371 m_strPathExpression = varObj.GetNameReal();
1373 CMICmnLLDBDebugSessionInfoVarObj varObjParent;
1374 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarParentName,
1376 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1377 m_cmdData.strMiCmd.c_str(),
1378 rVarParentName.c_str()));
1379 return MIstatus::failure;
1381 m_strPathExpression =
1382 CMIUtilString::Format("%s.%s", varObjParent.GetNameReal().c_str(),
1383 varObj.GetNameReal().c_str());
1386 return MIstatus::success;
1390 //------------------------------------------------------------------------------------
1391 // Details: The invoker requires this function. The command prepares a MI Record
1393 // for the work carried out in the Execute().
1394 // Type: Overridden.
1396 // Return: MIstatus::success - Functional succeeded.
1397 // MIstatus::failure - Functional failed.
1400 bool CMICmdCmdVarInfoPathExpression::Acknowledge() {
1401 if (m_bValueValid) {
1402 const CMICmnMIValueConst miValueConst(m_strPathExpression);
1403 const CMICmnMIValueResult miValueResult("path_expr", miValueConst);
1404 const CMICmnMIResultRecord miRecordResult(
1405 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1407 m_miResultRecord = miRecordResult;
1408 return MIstatus::success;
1411 const CMICmnMIValueConst miValueConst("variable invalid");
1412 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1413 const CMICmnMIResultRecord miRecordResult(
1414 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1416 m_miResultRecord = miRecordResult;
1418 return MIstatus::success;
1422 //------------------------------------------------------------------------------------
1423 // Details: Required by the CMICmdFactory when registering *this command. The
1425 // calls this function to create an instance of *this command.
1426 // Type: Static method.
1428 // Return: CMICmdBase * - Pointer to a new command.
1431 CMICmdBase *CMICmdCmdVarInfoPathExpression::CreateSelf() {
1432 return new CMICmdCmdVarInfoPathExpression();
1435 //---------------------------------------------------------------------------------------
1436 //---------------------------------------------------------------------------------------
1437 //---------------------------------------------------------------------------------------
1440 //------------------------------------------------------------------------------------
1441 // Details: CMICmdCmdVarShowAttributes constructor.
1447 CMICmdCmdVarShowAttributes::CMICmdCmdVarShowAttributes()
1448 : m_constStrArgName("name") {
1449 // Command factory matches this name with that received from the stdin stream
1450 m_strMiCmd = "var-show-attributes";
1452 // Required by the CMICmdFactory when registering *this command
1453 m_pSelfCreatorFn = &CMICmdCmdVarShowAttributes::CreateSelf;
1457 //------------------------------------------------------------------------------------
1458 // Details: CMICmdCmdVarShowAttributes destructor.
1459 // Type: Overrideable.
1464 CMICmdCmdVarShowAttributes::~CMICmdCmdVarShowAttributes() {}
1467 //------------------------------------------------------------------------------------
1468 // Details: The invoker requires this function. The parses the command line
1470 // arguments to extract values for each of those arguments.
1471 // Type: Overridden.
1473 // Return: MIstatus::success - Functional succeeded.
1474 // MIstatus::failure - Functional failed.
1477 bool CMICmdCmdVarShowAttributes::ParseArgs() {
1478 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1479 return ParseValidateCmdOptions();
1483 //------------------------------------------------------------------------------------
1484 // Details: The invoker requires this function. The command does work in this
1486 // The command is likely to communicate with the LLDB SBDebugger in
1488 // Type: Overridden.
1490 // Return: MIstatus::success - Functional succeeded.
1491 // MIstatus::failure - Functional failed.
1494 bool CMICmdCmdVarShowAttributes::Execute() {
1495 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1497 const CMIUtilString &rVarObjName(pArgName->GetValue());
1498 CMICmnLLDBDebugSessionInfoVarObj varObj;
1499 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1500 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1501 m_cmdData.strMiCmd.c_str(),
1502 rVarObjName.c_str()));
1503 return MIstatus::failure;
1506 return MIstatus::success;
1510 //------------------------------------------------------------------------------------
1511 // Details: The invoker requires this function. The command prepares a MI Record
1513 // for the work carried out in the Execute().
1514 // Type: Overridden.
1516 // Return: MIstatus::success - Functional succeeded.
1517 // MIstatus::failure - Functional failed.
1520 bool CMICmdCmdVarShowAttributes::Acknowledge() {
1521 // MI output: "%s^done,status=\"editable\"]"
1522 const CMICmnMIValueConst miValueConst("editable");
1523 const CMICmnMIValueResult miValueResult("status", miValueConst);
1524 const CMICmnMIResultRecord miRecordResult(
1525 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1527 m_miResultRecord = miRecordResult;
1529 return MIstatus::success;
1533 //------------------------------------------------------------------------------------
1534 // Details: Required by the CMICmdFactory when registering *this command. The
1536 // calls this function to create an instance of *this command.
1537 // Type: Static method.
1539 // Return: CMICmdBase * - Pointer to a new command.
1542 CMICmdBase *CMICmdCmdVarShowAttributes::CreateSelf() {
1543 return new CMICmdCmdVarShowAttributes();