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();
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;
528 return MIstatus::success;
531 //---------------------------------------------------------------------------------------
532 //---------------------------------------------------------------------------------------
533 //---------------------------------------------------------------------------------------
536 //------------------------------------------------------------------------------------
537 // Details: CMICmdCmdVarDelete constructor.
543 CMICmdCmdVarDelete::CMICmdCmdVarDelete() : m_constStrArgName("name") {
544 // Command factory matches this name with that received from the stdin stream
545 m_strMiCmd = "var-delete";
547 // Required by the CMICmdFactory when registering *this command
548 m_pSelfCreatorFn = &CMICmdCmdVarDelete::CreateSelf;
552 //------------------------------------------------------------------------------------
553 // Details: The invoker requires this function. The parses the command line
555 // arguments to extract values for each of those arguments.
558 // Return: MIstatus::success - Functional succeeded.
559 // MIstatus::failure - Functional failed.
562 bool CMICmdCmdVarDelete::ParseArgs() {
563 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
564 return ParseValidateCmdOptions();
568 //------------------------------------------------------------------------------------
569 // Details: CMICmdCmdVarDelete destructor.
570 // Type: Overrideable.
575 CMICmdCmdVarDelete::~CMICmdCmdVarDelete() {}
578 //------------------------------------------------------------------------------------
579 // Details: The invoker requires this function. The command does work in this
581 // The command is likely to communicate with the LLDB SBDebugger in
585 // Return: MIstatus::success - Functional succeeded.
586 // MIstatus::failure - Functional failed.
589 bool CMICmdCmdVarDelete::Execute() {
590 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
592 const CMIUtilString &rVarObjName(pArgName->GetValue());
593 CMICmnLLDBDebugSessionInfoVarObj::VarObjDelete(rVarObjName);
595 return MIstatus::success;
599 //------------------------------------------------------------------------------------
600 // Details: The invoker requires this function. The command prepares a MI Record
602 // for the work carried out in the Execute().
605 // Return: MIstatus::success - Functional succeeded.
606 // MIstatus::failure - Functional failed.
609 bool CMICmdCmdVarDelete::Acknowledge() {
610 const CMICmnMIResultRecord miRecordResult(
611 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
612 m_miResultRecord = miRecordResult;
614 return MIstatus::success;
618 //------------------------------------------------------------------------------------
619 // Details: Required by the CMICmdFactory when registering *this command. The
621 // calls this function to create an instance of *this command.
622 // Type: Static method.
624 // Return: CMICmdBase * - Pointer to a new command.
627 CMICmdBase *CMICmdCmdVarDelete::CreateSelf() {
628 return new CMICmdCmdVarDelete();
631 //---------------------------------------------------------------------------------------
632 //---------------------------------------------------------------------------------------
633 //---------------------------------------------------------------------------------------
636 //------------------------------------------------------------------------------------
637 // Details: CMICmdCmdVarAssign constructor.
643 CMICmdCmdVarAssign::CMICmdCmdVarAssign()
644 : m_bOk(true), m_constStrArgName("name"),
645 m_constStrArgExpression("expression") {
646 // Command factory matches this name with that received from the stdin stream
647 m_strMiCmd = "var-assign";
649 // Required by the CMICmdFactory when registering *this command
650 m_pSelfCreatorFn = &CMICmdCmdVarAssign::CreateSelf;
654 //------------------------------------------------------------------------------------
655 // Details: CMICmdCmdVarAssign destructor.
656 // Type: Overrideable.
661 CMICmdCmdVarAssign::~CMICmdCmdVarAssign() {}
664 //------------------------------------------------------------------------------------
665 // Details: The invoker requires this function. The parses the command line
667 // arguments to extract values for each of those arguments.
670 // Return: MIstatus::success - Functional succeeded.
671 // MIstatus::failure - Functional failed.
674 bool CMICmdCmdVarAssign::ParseArgs() {
675 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
676 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgExpression, true, true));
677 return ParseValidateCmdOptions();
681 //------------------------------------------------------------------------------------
682 // Details: The invoker requires this function. The command does work in this
684 // The command is likely to communicate with the LLDB SBDebugger in
688 // Return: MIstatus::success - Functional succeeded.
689 // MIstatus::failure - Functional failed.
692 bool CMICmdCmdVarAssign::Execute() {
693 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
694 CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
696 const CMIUtilString &rVarObjName(pArgName->GetValue());
697 const CMIUtilString &rExpression(pArgExpression->GetValue());
699 CMICmnLLDBDebugSessionInfoVarObj varObj;
700 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
701 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
702 m_cmdData.strMiCmd.c_str(),
703 rVarObjName.c_str()));
704 return MIstatus::failure;
706 m_varObjName = rVarObjName;
708 CMIUtilString strExpression(rExpression.Trim());
709 strExpression = strExpression.Trim('"');
710 lldb::SBValue &rValue(const_cast<lldb::SBValue &>(varObj.GetValue()));
711 m_bOk = rValue.SetValueFromCString(strExpression.c_str());
713 varObj.UpdateValue();
715 return MIstatus::success;
719 //------------------------------------------------------------------------------------
720 // Details: The invoker requires this function. The command prepares a MI Record
722 // for the work carried out in the Execute().
725 // Return: MIstatus::success - Functional succeeded.
726 // MIstatus::failure - Functional failed.
729 bool CMICmdCmdVarAssign::Acknowledge() {
731 // MI print "%s^done,value=\"%s\""
732 CMICmnLLDBDebugSessionInfoVarObj varObj;
733 CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
734 const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
735 const CMICmnMIValueResult miValueResult("value", miValueConst);
736 const CMICmnMIResultRecord miRecordResult(
737 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
739 m_miResultRecord = miRecordResult;
741 return MIstatus::success;
744 const CMICmnMIValueConst miValueConst("expression could not be evaluated");
745 const CMICmnMIValueResult miValueResult("msg", miValueConst);
746 const CMICmnMIResultRecord miRecordResult(
747 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
749 m_miResultRecord = miRecordResult;
751 return MIstatus::success;
755 //------------------------------------------------------------------------------------
756 // Details: Required by the CMICmdFactory when registering *this command. The
758 // calls this function to create an instance of *this command.
759 // Type: Static method.
761 // Return: CMICmdBase * - Pointer to a new command.
764 CMICmdBase *CMICmdCmdVarAssign::CreateSelf() {
765 return new CMICmdCmdVarAssign();
768 //---------------------------------------------------------------------------------------
769 //---------------------------------------------------------------------------------------
770 //---------------------------------------------------------------------------------------
773 //------------------------------------------------------------------------------------
774 // Details: CMICmdCmdVarSetFormat constructor.
780 CMICmdCmdVarSetFormat::CMICmdCmdVarSetFormat()
781 : m_constStrArgName("name"), m_constStrArgFormatSpec("format-spec") {
782 // Command factory matches this name with that received from the stdin stream
783 m_strMiCmd = "var-set-format";
785 // Required by the CMICmdFactory when registering *this command
786 m_pSelfCreatorFn = &CMICmdCmdVarSetFormat::CreateSelf;
790 //------------------------------------------------------------------------------------
791 // Details: CMICmdCmdVarSetFormat destructor.
792 // Type: Overrideable.
797 CMICmdCmdVarSetFormat::~CMICmdCmdVarSetFormat() {}
800 //------------------------------------------------------------------------------------
801 // Details: The invoker requires this function. The parses the command line
803 // arguments to extract values for each of those arguments.
806 // Return: MIstatus::success - Functional succeeded.
807 // MIstatus::failure - Functional failed.
810 bool CMICmdCmdVarSetFormat::ParseArgs() {
811 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
812 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFormatSpec, true, true));
813 return ParseValidateCmdOptions();
817 //------------------------------------------------------------------------------------
818 // Details: The invoker requires this function. The command does work in this
820 // The command is likely to communicate with the LLDB SBDebugger in
824 // Return: MIstatus::success - Functional succeeded.
825 // MIstatus::failure - Functional failed.
828 bool CMICmdCmdVarSetFormat::Execute() {
829 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
830 CMICMDBASE_GETOPTION(pArgFormatSpec, String, m_constStrArgFormatSpec);
832 const CMIUtilString &rVarObjName(pArgName->GetValue());
833 const CMIUtilString &rExpression(pArgFormatSpec->GetValue());
835 CMICmnLLDBDebugSessionInfoVarObj varObj;
836 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
837 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
838 m_cmdData.strMiCmd.c_str(),
839 rVarObjName.c_str()));
840 return MIstatus::failure;
842 if (!varObj.SetVarFormat(
843 CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString(
845 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_ENUM_INVALID),
846 m_cmdData.strMiCmd.c_str(),
847 rVarObjName.c_str(), rExpression.c_str()));
848 return MIstatus::failure;
850 varObj.UpdateValue();
852 m_varObjName = rVarObjName;
854 return MIstatus::success;
858 //------------------------------------------------------------------------------------
859 // Details: The invoker requires this function. The command prepares a MI Record
861 // for the work carried out in the Execute().
864 // Return: MIstatus::success - Functional succeeded.
865 // MIstatus::failure - Functional failed.
868 bool CMICmdCmdVarSetFormat::Acknowledge() {
870 // "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
871 CMICmnLLDBDebugSessionInfoVarObj varObj;
872 CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
873 const CMICmnMIValueConst miValueConst(m_varObjName);
874 const CMICmnMIValueResult miValueResult("name", miValueConst);
875 CMICmnMIValueTuple miValueTuple(miValueResult);
876 const CMICmnMIValueConst miValueConst2(varObj.GetValueFormatted());
877 const CMICmnMIValueResult miValueResult2("value", miValueConst2);
878 miValueTuple.Add(miValueResult2);
879 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
880 const CMICmnMIValueConst miValueConst3(rValue.IsInScope() ? "true" : "false");
881 const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
882 miValueTuple.Add(miValueResult3);
883 const CMICmnMIValueConst miValueConst4("false");
884 const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
885 miValueTuple.Add(miValueResult4);
886 const CMICmnMIValueConst miValueConst5("0");
887 const CMICmnMIValueResult miValueResult5("type_changed", miValueConst5);
888 miValueTuple.Add(miValueResult5);
889 const CMICmnMIValueList miValueList(miValueTuple);
890 const CMICmnMIValueResult miValueResult6("changelist", miValueList);
892 const CMICmnMIResultRecord miRecordResult(
893 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
895 m_miResultRecord = miRecordResult;
897 return MIstatus::success;
901 //------------------------------------------------------------------------------------
902 // Details: Required by the CMICmdFactory when registering *this command. The
904 // calls this function to create an instance of *this command.
905 // Type: Static method.
907 // Return: CMICmdBase * - Pointer to a new command.
910 CMICmdBase *CMICmdCmdVarSetFormat::CreateSelf() {
911 return new CMICmdCmdVarSetFormat();
914 //---------------------------------------------------------------------------------------
915 //---------------------------------------------------------------------------------------
916 //---------------------------------------------------------------------------------------
919 //------------------------------------------------------------------------------------
920 // Details: CMICmdCmdVarListChildren constructor.
926 CMICmdCmdVarListChildren::CMICmdCmdVarListChildren()
927 : m_constStrArgPrintValues("print-values"), m_constStrArgName("name"),
928 m_constStrArgFrom("from"), m_constStrArgTo("to"), m_bValueValid(false),
929 m_nChildren(0), m_miValueList(true), m_bHasMore(false) {
930 // Command factory matches this name with that received from the stdin stream
931 m_strMiCmd = "var-list-children";
933 // Required by the CMICmdFactory when registering *this command
934 m_pSelfCreatorFn = &CMICmdCmdVarListChildren::CreateSelf;
938 //------------------------------------------------------------------------------------
939 // Details: CMICmdCmdVarListChildren destructor.
940 // Type: Overrideable.
945 CMICmdCmdVarListChildren::~CMICmdCmdVarListChildren() {}
948 //------------------------------------------------------------------------------------
949 // Details: The invoker requires this function. The parses the command line
951 // arguments to extract values for each of those arguments.
954 // Return: MIstatus::success - Functional succeeded.
955 // MIstatus::failure - Functional failed.
958 bool CMICmdCmdVarListChildren::ParseArgs() {
960 new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
961 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true, true));
962 m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrom, false, true));
963 m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgTo, false, true));
964 return ParseValidateCmdOptions();
968 //------------------------------------------------------------------------------------
969 // Details: The invoker requires this function. The command does work in this
971 // The command is likely to communicate with the LLDB SBDebugger in
975 // Return: MIstatus::success - Functional succeeded.
976 // MIstatus::failure - Functional failed.
979 bool CMICmdCmdVarListChildren::Execute() {
980 CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
981 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
982 CMICMDBASE_GETOPTION(pArgFrom, Number, m_constStrArgFrom);
983 CMICMDBASE_GETOPTION(pArgTo, Number, m_constStrArgTo);
985 CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
986 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
987 if (pArgPrintValues->GetFound())
989 static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
990 pArgPrintValues->GetValue());
992 const CMIUtilString &rVarObjName(pArgName->GetValue());
993 CMICmnLLDBDebugSessionInfoVarObj varObj;
994 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
995 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
996 m_cmdData.strMiCmd.c_str(),
997 rVarObjName.c_str()));
998 return MIstatus::failure;
1002 MIuint nTo = UINT32_MAX;
1003 if (pArgFrom->GetFound() && pArgTo->GetFound()) {
1004 nFrom = pArgFrom->GetValue();
1005 nTo = pArgTo->GetValue();
1006 } else if (pArgFrom->GetFound() || pArgTo->GetFound()) {
1007 // Only from or to was specified but both are required
1009 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID),
1010 m_cmdData.strMiCmd.c_str()));
1011 return MIstatus::failure;
1014 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1015 m_bValueValid = rValue.IsValid();
1017 return MIstatus::success;
1019 const MIuint nChildren = rValue.GetNumChildren();
1020 m_bHasMore = nTo < nChildren;
1021 nTo = std::min(nTo, nChildren);
1022 m_nChildren = nFrom < nTo ? nTo - nFrom : 0;
1023 for (MIuint i = nFrom; i < nTo; i++) {
1024 lldb::SBValue member = rValue.GetChildAtIndex(i);
1025 const CMICmnLLDBUtilSBValue utilValue(member);
1026 const CMIUtilString strExp = utilValue.GetName();
1027 const CMIUtilString name(
1028 strExp.empty() ? CMIUtilString::Format("%s.$%u", rVarObjName.c_str(), i)
1029 : CMIUtilString::Format("%s.%s", rVarObjName.c_str(),
1031 const MIuint nChildren = member.GetNumChildren();
1032 const CMIUtilString strThreadId(
1033 CMIUtilString::Format("%u", member.GetThread().GetIndexID()));
1035 // Varobj gets added to CMICmnLLDBDebugSessionInfoVarObj static container of
1037 CMICmnLLDBDebugSessionInfoVarObj var(strExp, name, member, rVarObjName);
1040 // "child={name=\"%s\",exp=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%u\",has_more=\"%u\"}"
1041 const CMICmnMIValueConst miValueConst(name);
1042 const CMICmnMIValueResult miValueResult("name", miValueConst);
1043 CMICmnMIValueTuple miValueTuple(miValueResult);
1044 const CMICmnMIValueConst miValueConst2(strExp);
1045 const CMICmnMIValueResult miValueResult2("exp", miValueConst2);
1046 miValueTuple.Add(miValueResult2);
1047 const CMIUtilString strNumChild(CMIUtilString::Format("%u", nChildren));
1048 const CMICmnMIValueConst miValueConst3(strNumChild);
1049 const CMICmnMIValueResult miValueResult3("numchild", miValueConst3);
1050 miValueTuple.Add(miValueResult3);
1051 const CMICmnMIValueConst miValueConst5(utilValue.GetTypeNameDisplay());
1052 const CMICmnMIValueResult miValueResult5("type", miValueConst5);
1053 miValueTuple.Add(miValueResult5);
1054 const CMICmnMIValueConst miValueConst6(strThreadId);
1055 const CMICmnMIValueResult miValueResult6("thread-id", miValueConst6);
1056 miValueTuple.Add(miValueResult6);
1057 // nChildren == 0 is used to check for simple values
1058 if (eVarInfoFormat ==
1059 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues ||
1061 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues &&
1063 const CMIUtilString strValue(
1064 CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(
1065 member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural));
1066 const CMICmnMIValueConst miValueConst7(strValue);
1067 const CMICmnMIValueResult miValueResult7("value", miValueConst7);
1068 miValueTuple.Add(miValueResult7);
1070 const CMICmnMIValueConst miValueConst8("0");
1071 const CMICmnMIValueResult miValueResult8("has_more", miValueConst8);
1072 miValueTuple.Add(miValueResult8);
1073 const CMICmnMIValueResult miValueResult9("child", miValueTuple);
1074 m_miValueList.Add(miValueResult9);
1077 return MIstatus::success;
1081 //------------------------------------------------------------------------------------
1082 // Details: The invoker requires this function. The command prepares a MI Record
1084 // for the work carried out in the Execute().
1085 // Type: Overridden.
1087 // Return: MIstatus::success - Functional succeeded.
1088 // MIstatus::failure - Functional failed.
1091 bool CMICmdCmdVarListChildren::Acknowledge() {
1092 if (m_bValueValid) {
1093 // MI print "%s^done,numchild=\"%u\",children=[%s],has_more=\"%d\""
1094 const CMIUtilString strNumChild(CMIUtilString::Format("%u", m_nChildren));
1095 const CMICmnMIValueConst miValueConst(strNumChild);
1096 CMICmnMIValueResult miValueResult("numchild", miValueConst);
1097 if (m_nChildren != 0)
1098 miValueResult.Add("children", m_miValueList);
1099 const CMIUtilString strHasMore(m_bHasMore ? "1" : "0");
1100 const CMICmnMIValueConst miValueConst2(strHasMore);
1101 miValueResult.Add("has_more", miValueConst2);
1103 const CMICmnMIResultRecord miRecordResult(
1104 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1106 m_miResultRecord = miRecordResult;
1108 return MIstatus::success;
1111 // MI print "%s^error,msg=\"variable invalid\""
1112 const CMICmnMIValueConst miValueConst("variable invalid");
1113 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1114 const CMICmnMIResultRecord miRecordResult(
1115 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1117 m_miResultRecord = miRecordResult;
1119 return MIstatus::success;
1123 //------------------------------------------------------------------------------------
1124 // Details: Required by the CMICmdFactory when registering *this command. The
1126 // calls this function to create an instance of *this command.
1127 // Type: Static method.
1129 // Return: CMICmdBase * - Pointer to a new command.
1132 CMICmdBase *CMICmdCmdVarListChildren::CreateSelf() {
1133 return new CMICmdCmdVarListChildren();
1136 //---------------------------------------------------------------------------------------
1137 //---------------------------------------------------------------------------------------
1138 //---------------------------------------------------------------------------------------
1141 //------------------------------------------------------------------------------------
1142 // Details: CMICmdCmdVarEvaluateExpression constructor.
1148 CMICmdCmdVarEvaluateExpression::CMICmdCmdVarEvaluateExpression()
1149 : m_bValueValid(true), m_constStrArgFormatSpec("-f"),
1150 m_constStrArgName("name") {
1151 // Command factory matches this name with that received from the stdin stream
1152 m_strMiCmd = "var-evaluate-expression";
1154 // Required by the CMICmdFactory when registering *this command
1155 m_pSelfCreatorFn = &CMICmdCmdVarEvaluateExpression::CreateSelf;
1159 //------------------------------------------------------------------------------------
1160 // Details: CMICmdCmdVarEvaluateExpression destructor.
1161 // Type: Overrideable.
1166 CMICmdCmdVarEvaluateExpression::~CMICmdCmdVarEvaluateExpression() {}
1169 //------------------------------------------------------------------------------------
1170 // Details: The invoker requires this function. The parses the command line
1172 // arguments to extract values for each of those arguments.
1173 // Type: Overridden.
1175 // Return: MIstatus::success - Functional succeeded.
1176 // MIstatus::failure - Functional failed.
1179 bool CMICmdCmdVarEvaluateExpression::ParseArgs() {
1181 new CMICmdArgValOptionShort(m_constStrArgFormatSpec, false, false,
1182 CMICmdArgValListBase::eArgValType_String, 1));
1183 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1184 return ParseValidateCmdOptions();
1188 //------------------------------------------------------------------------------------
1189 // Details: The invoker requires this function. The command does work in this
1191 // The command is likely to communicate with the LLDB SBDebugger in
1193 // Type: Overridden.
1195 // Return: MIstatus::success - Functional succeeded.
1196 // MIstatus::failure - Functional failed.
1199 bool CMICmdCmdVarEvaluateExpression::Execute() {
1200 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1202 const CMIUtilString &rVarObjName(pArgName->GetValue());
1203 CMICmnLLDBDebugSessionInfoVarObj varObj;
1204 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1205 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1206 m_cmdData.strMiCmd.c_str(),
1207 rVarObjName.c_str()));
1208 return MIstatus::failure;
1211 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1212 m_bValueValid = rValue.IsValid();
1214 return MIstatus::success;
1216 m_varObjName = rVarObjName;
1217 varObj.UpdateValue();
1219 return MIstatus::success;
1223 //------------------------------------------------------------------------------------
1224 // Details: The invoker requires this function. The command prepares a MI Record
1226 // for the work carried out in the Execute().
1227 // Type: Overridden.
1229 // Return: MIstatus::success - Functional succeeded.
1230 // MIstatus::failure - Functional failed.
1233 bool CMICmdCmdVarEvaluateExpression::Acknowledge() {
1234 if (m_bValueValid) {
1235 CMICmnLLDBDebugSessionInfoVarObj varObj;
1236 CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
1237 const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
1238 const CMICmnMIValueResult miValueResult("value", miValueConst);
1239 const CMICmnMIResultRecord miRecordResult(
1240 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1242 m_miResultRecord = miRecordResult;
1243 return MIstatus::success;
1246 const CMICmnMIValueConst miValueConst("variable invalid");
1247 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1248 const CMICmnMIResultRecord miRecordResult(
1249 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1251 m_miResultRecord = miRecordResult;
1252 return MIstatus::success;
1256 //------------------------------------------------------------------------------------
1257 // Details: Required by the CMICmdFactory when registering *this command. The
1259 // calls this function to create an instance of *this command.
1260 // Type: Static method.
1262 // Return: CMICmdBase * - Pointer to a new command.
1265 CMICmdBase *CMICmdCmdVarEvaluateExpression::CreateSelf() {
1266 return new CMICmdCmdVarEvaluateExpression();
1269 //---------------------------------------------------------------------------------------
1270 //---------------------------------------------------------------------------------------
1271 //---------------------------------------------------------------------------------------
1274 //------------------------------------------------------------------------------------
1275 // Details: CMICmdCmdVarInfoPathExpression constructor.
1281 CMICmdCmdVarInfoPathExpression::CMICmdCmdVarInfoPathExpression()
1282 : m_bValueValid(true), m_constStrArgName("name") {
1283 // Command factory matches this name with that received from the stdin stream
1284 m_strMiCmd = "var-info-path-expression";
1286 // Required by the CMICmdFactory when registering *this command
1287 m_pSelfCreatorFn = &CMICmdCmdVarInfoPathExpression::CreateSelf;
1291 //------------------------------------------------------------------------------------
1292 // Details: CMICmdCmdVarInfoPathExpression destructor.
1293 // Type: Overrideable.
1298 CMICmdCmdVarInfoPathExpression::~CMICmdCmdVarInfoPathExpression() {}
1301 //------------------------------------------------------------------------------------
1302 // Details: The invoker requires this function. The parses the command line
1304 // arguments to extract values for each of those arguments.
1305 // Type: Overridden.
1307 // Return: MIstatus::success - Functional succeeded.
1308 // MIstatus::failure - Functional failed.
1311 bool CMICmdCmdVarInfoPathExpression::ParseArgs() {
1312 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1313 return ParseValidateCmdOptions();
1317 //------------------------------------------------------------------------------------
1318 // Details: The invoker requires this function. The command does work in this
1320 // The command is likely to communicate with the LLDB SBDebugger in
1322 // Type: Overridden.
1324 // Return: MIstatus::success - Functional succeeded.
1325 // MIstatus::failure - Functional failed.
1328 bool CMICmdCmdVarInfoPathExpression::Execute() {
1329 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1331 const CMIUtilString &rVarObjName(pArgName->GetValue());
1332 CMICmnLLDBDebugSessionInfoVarObj varObj;
1333 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1334 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1335 m_cmdData.strMiCmd.c_str(),
1336 rVarObjName.c_str()));
1337 return MIstatus::failure;
1340 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1341 m_bValueValid = rValue.IsValid();
1343 return MIstatus::success;
1345 lldb::SBStream stream;
1346 if (!rValue.GetExpressionPath(stream, true)) {
1347 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH),
1348 m_cmdData.strMiCmd.c_str(),
1349 rVarObjName.c_str()));
1350 return MIstatus::failure;
1353 const char *pPathExpression = stream.GetData();
1354 if (pPathExpression == nullptr) {
1355 // Build expression from what we do know
1356 m_strPathExpression = varObj.GetNameReal();
1357 return MIstatus::success;
1360 // Has LLDB returned a var signature of it's own
1361 if (pPathExpression[0] != '$') {
1362 m_strPathExpression = pPathExpression;
1363 return MIstatus::success;
1366 // Build expression from what we do know
1367 const CMIUtilString &rVarParentName(varObj.GetVarParentName());
1368 if (rVarParentName.empty()) {
1369 m_strPathExpression = varObj.GetNameReal();
1371 CMICmnLLDBDebugSessionInfoVarObj varObjParent;
1372 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarParentName,
1374 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1375 m_cmdData.strMiCmd.c_str(),
1376 rVarParentName.c_str()));
1377 return MIstatus::failure;
1379 m_strPathExpression =
1380 CMIUtilString::Format("%s.%s", varObjParent.GetNameReal().c_str(),
1381 varObj.GetNameReal().c_str());
1384 return MIstatus::success;
1388 //------------------------------------------------------------------------------------
1389 // Details: The invoker requires this function. The command prepares a MI Record
1391 // for the work carried out in the Execute().
1392 // Type: Overridden.
1394 // Return: MIstatus::success - Functional succeeded.
1395 // MIstatus::failure - Functional failed.
1398 bool CMICmdCmdVarInfoPathExpression::Acknowledge() {
1399 if (m_bValueValid) {
1400 const CMICmnMIValueConst miValueConst(m_strPathExpression);
1401 const CMICmnMIValueResult miValueResult("path_expr", miValueConst);
1402 const CMICmnMIResultRecord miRecordResult(
1403 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1405 m_miResultRecord = miRecordResult;
1406 return MIstatus::success;
1409 const CMICmnMIValueConst miValueConst("variable invalid");
1410 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1411 const CMICmnMIResultRecord miRecordResult(
1412 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1414 m_miResultRecord = miRecordResult;
1416 return MIstatus::success;
1420 //------------------------------------------------------------------------------------
1421 // Details: Required by the CMICmdFactory when registering *this command. The
1423 // calls this function to create an instance of *this command.
1424 // Type: Static method.
1426 // Return: CMICmdBase * - Pointer to a new command.
1429 CMICmdBase *CMICmdCmdVarInfoPathExpression::CreateSelf() {
1430 return new CMICmdCmdVarInfoPathExpression();
1433 //---------------------------------------------------------------------------------------
1434 //---------------------------------------------------------------------------------------
1435 //---------------------------------------------------------------------------------------
1438 //------------------------------------------------------------------------------------
1439 // Details: CMICmdCmdVarShowAttributes constructor.
1445 CMICmdCmdVarShowAttributes::CMICmdCmdVarShowAttributes()
1446 : m_constStrArgName("name") {
1447 // Command factory matches this name with that received from the stdin stream
1448 m_strMiCmd = "var-show-attributes";
1450 // Required by the CMICmdFactory when registering *this command
1451 m_pSelfCreatorFn = &CMICmdCmdVarShowAttributes::CreateSelf;
1455 //------------------------------------------------------------------------------------
1456 // Details: CMICmdCmdVarShowAttributes destructor.
1457 // Type: Overrideable.
1462 CMICmdCmdVarShowAttributes::~CMICmdCmdVarShowAttributes() {}
1465 //------------------------------------------------------------------------------------
1466 // Details: The invoker requires this function. The parses the command line
1468 // arguments to extract values for each of those arguments.
1469 // Type: Overridden.
1471 // Return: MIstatus::success - Functional succeeded.
1472 // MIstatus::failure - Functional failed.
1475 bool CMICmdCmdVarShowAttributes::ParseArgs() {
1476 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1477 return ParseValidateCmdOptions();
1481 //------------------------------------------------------------------------------------
1482 // Details: The invoker requires this function. The command does work in this
1484 // The command is likely to communicate with the LLDB SBDebugger in
1486 // Type: Overridden.
1488 // Return: MIstatus::success - Functional succeeded.
1489 // MIstatus::failure - Functional failed.
1492 bool CMICmdCmdVarShowAttributes::Execute() {
1493 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1495 const CMIUtilString &rVarObjName(pArgName->GetValue());
1496 CMICmnLLDBDebugSessionInfoVarObj varObj;
1497 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1498 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1499 m_cmdData.strMiCmd.c_str(),
1500 rVarObjName.c_str()));
1501 return MIstatus::failure;
1504 return MIstatus::success;
1508 //------------------------------------------------------------------------------------
1509 // Details: The invoker requires this function. The command prepares a MI Record
1511 // for the work carried out in the Execute().
1512 // Type: Overridden.
1514 // Return: MIstatus::success - Functional succeeded.
1515 // MIstatus::failure - Functional failed.
1518 bool CMICmdCmdVarShowAttributes::Acknowledge() {
1519 // MI output: "%s^done,status=\"editable\"]"
1520 const CMICmnMIValueConst miValueConst("editable");
1521 const CMICmnMIValueResult miValueResult("status", miValueConst);
1522 const CMICmnMIResultRecord miRecordResult(
1523 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1525 m_miResultRecord = miRecordResult;
1527 return MIstatus::success;
1531 //------------------------------------------------------------------------------------
1532 // Details: Required by the CMICmdFactory when registering *this command. The
1534 // calls this function to create an instance of *this command.
1535 // Type: Static method.
1537 // Return: CMICmdBase * - Pointer to a new command.
1540 CMICmdBase *CMICmdCmdVarShowAttributes::CreateSelf() {
1541 return new CMICmdCmdVarShowAttributes();