1 //===-- MICmdCmdVar.cpp -----------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // Overview: CMICmdCmdVarCreate implementation.
11 // CMICmdCmdVarUpdate implementation.
12 // CMICmdCmdVarDelete implementation.
13 // CMICmdCmdVarAssign implementation.
14 // CMICmdCmdVarSetFormat implementation.
15 // CMICmdCmdVarListChildren implementation.
16 // CMICmdCmdVarEvaluateExpression implementation.
17 // CMICmdCmdVarInfoPathExpression implementation.
18 // CMICmdCmdVarShowAttributes implementation.
19
20 // Third Party Headers:
21 #include "lldb/API/SBStream.h"
22 #include "lldb/API/SBThread.h"
23 #include "lldb/API/SBType.h"
24
25 // In-house headers:
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"
40
41 #include <algorithm>
42
43 //++
44 //------------------------------------------------------------------------------------
45 // Details: CMICmdCmdVarCreate constructor.
46 // Type: Method.
47 // Args: None.
48 // Return: None.
49 // Throws: None.
50 //--
CMICmdCmdVarCreate()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";
58
59 // Required by the CMICmdFactory when registering *this command
60 m_pSelfCreatorFn = &CMICmdCmdVarCreate::CreateSelf;
61 }
62
63 //++
64 //------------------------------------------------------------------------------------
65 // Details: CMICmdCmdVarCreate destructor.
66 // Type: Overrideable.
67 // Args: None.
68 // Return: None.
69 // Throws: None.
70 //--
~CMICmdCmdVarCreate()71 CMICmdCmdVarCreate::~CMICmdCmdVarCreate() {}
72
73 //++
74 //------------------------------------------------------------------------------------
75 // Details: The invoker requires this function. The parses the command line
76 // options
77 // arguments to extract values for each of those arguments.
78 // Type: Overridden.
79 // Args: None.
80 // Return: MIstatus::success - Functional succeeded.
81 // MIstatus::failure - Functional failed.
82 // Throws: None.
83 //--
ParseArgs()84 bool CMICmdCmdVarCreate::ParseArgs() {
85 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, false, true));
86 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFrameAddr, false, true));
87 m_setCmdArgs.Add(
88 new CMICmdArgValString(m_constStrArgExpression, true, true, true, true));
89 return ParseValidateCmdOptions();
90 }
91
92 //++
93 //------------------------------------------------------------------------------------
94 // Details: The invoker requires this function. The command does work in this
95 // function.
96 // The command is likely to communicate with the LLDB SBDebugger in
97 // here.
98 // Type: Overridden.
99 // Args: None.
100 // Return: MIstatus::success - Functional succeeded.
101 // MIstatus::failure - Functional failed.
102 // Throws: None.
103 //--
Execute()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);
110
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;
119 }
120
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;
129 }
130
131 const CMICmdArgValOptionLong::VecArgObjPtr_t &rVecFrameId(
132 pArgFrame->GetExpectedOptions());
133 CMICmdArgValOptionLong::VecArgObjPtr_t::const_iterator it2 =
134 rVecFrameId.begin();
135 if (it2 != rVecFrameId.end()) {
136 const CMICmdArgValNumber *pOption = static_cast<CMICmdArgValNumber *>(*it2);
137 nFrame = pOption->GetValue();
138 }
139
140 m_strVarName = "<unnamedvariable>";
141 if (pArgName->GetFound()) {
142 const CMIUtilString &rArg = pArgName->GetValue();
143 const bool bAutoName = (rArg == "-");
144 if (bAutoName) {
145 m_strVarName = CMIUtilString::Format(
146 "var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet());
147 CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
148 } else
149 m_strVarName = rArg;
150 }
151
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
158 // specified.
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;
163 }
164 }
165
166 const CMIUtilString &rStrExpression(pArgExpression->GetValue());
167 m_strExpression = rStrExpression;
168
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);
178 lldb::SBValue value;
179
180 if (rStrExpression[0] == '$') {
181 const CMIUtilString rStrRegister(rStrExpression.substr(1));
182 value = frame.FindRegister(rStrRegister.c_str());
183 } else {
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());
191 }
192
193 if (!value.IsValid())
194 value = frame.EvaluateExpression(rStrExpression.c_str());
195
196 if (value.IsValid() && value.GetError().Success()) {
197 CompleteSBValue(value);
198 m_bValid = true;
199 m_nChildren = value.GetNumChildren();
200 m_strType = CMICmnLLDBUtilSBValue(value).GetTypeNameDisplay();
201
202 // This gets added to CMICmnLLDBDebugSessionInfoVarObj static container of
203 // varObjs
204 CMICmnLLDBDebugSessionInfoVarObj varObj(rStrExpression, m_strVarName,
205 value);
206 m_strValue = varObj.GetValueFormatted();
207 } else {
208 m_strValue = value.GetError().GetCString();
209 }
210
211 return MIstatus::success;
212 }
213
214 //++
215 //------------------------------------------------------------------------------------
216 // Details: The invoker requires this function. The command prepares a MI Record
217 // Result
218 // for the work carried out in the Execute().
219 // Type: Overridden.
220 // Args: None.
221 // Return: MIstatus::success - Functional succeeded.
222 // MIstatus::failure - Functional failed.
223 // Throws: None.
224 //--
Acknowledge()225 bool CMICmdCmdVarCreate::Acknowledge() {
226 if (m_bValid) {
227 // MI print
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);
243
244 const CMICmnMIResultRecord miRecordResult(
245 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
246 miValueResultAll);
247 m_miResultRecord = miRecordResult;
248
249 return MIstatus::success;
250 }
251
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,
261 miValueResult);
262 m_miResultRecord = miRecordResult;
263
264 return MIstatus::success;
265 }
266
267 //++
268 //------------------------------------------------------------------------------------
269 // Details: Required by the CMICmdFactory when registering *this command. The
270 // factory
271 // calls this function to create an instance of *this command.
272 // Type: Static method.
273 // Args: None.
274 // Return: CMICmdBase * - Pointer to a new command.
275 // Throws: None.
276 //--
CreateSelf()277 CMICmdBase *CMICmdCmdVarCreate::CreateSelf() {
278 return new CMICmdCmdVarCreate();
279 }
280
281 //++
282 //------------------------------------------------------------------------------------
283 // Details: Complete SBValue object and its children to get
284 // SBValue::GetValueDidChange
285 // work.
286 // Type: Method.
287 // Args: vrwValue - (R) Value to update.
288 // Return: MIstatus::success - Functional succeeded.
289 // MIstatus::failure - Functional failed.
290 // Throws: None.
291 //--
CompleteSBValue(lldb::SBValue & vrwValue)292 void CMICmdCmdVarCreate::CompleteSBValue(lldb::SBValue &vrwValue) {
293 // Force a value to update
294 vrwValue.GetValueDidChange();
295
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);
304 }
305 }
306 }
307
308 //---------------------------------------------------------------------------------------
309 //---------------------------------------------------------------------------------------
310 //---------------------------------------------------------------------------------------
311
312 //++
313 //------------------------------------------------------------------------------------
314 // Details: CMICmdCmdVarUpdate constructor.
315 // Type: Method.
316 // Args: None.
317 // Return: None.
318 // Throws: None.
319 //--
CMICmdCmdVarUpdate()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";
325
326 // Required by the CMICmdFactory when registering *this command
327 m_pSelfCreatorFn = &CMICmdCmdVarUpdate::CreateSelf;
328 }
329
330 //++
331 //------------------------------------------------------------------------------------
332 // Details: CMICmdCmdVarUpdate destructor.
333 // Type: Overrideable.
334 // Args: None.
335 // Return: None.
336 // Throws: None.
337 //--
~CMICmdCmdVarUpdate()338 CMICmdCmdVarUpdate::~CMICmdCmdVarUpdate() {}
339
340 //++
341 //------------------------------------------------------------------------------------
342 // Details: The invoker requires this function. The parses the command line
343 // options
344 // arguments to extract values for each of those arguments.
345 // Type: Overridden.
346 // Args: None.
347 // Return: MIstatus::success - Functional succeeded.
348 // MIstatus::failure - Functional failed.
349 // Throws: None.
350 //--
ParseArgs()351 bool CMICmdCmdVarUpdate::ParseArgs() {
352 m_setCmdArgs.Add(
353 new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
354 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
355 return ParseValidateCmdOptions();
356 }
357
358 //++
359 //------------------------------------------------------------------------------------
360 // Details: The invoker requires this function. The command does work in this
361 // function.
362 // The command is likely to communicate with the LLDB SBDebugger in
363 // here.
364 // Type: Overridden.
365 // Args: None.
366 // Return: MIstatus::success - Functional succeeded.
367 // MIstatus::failure - Functional failed.
368 // Throws: None.
369 //--
Execute()370 bool CMICmdCmdVarUpdate::Execute() {
371 CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
372 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
373
374 CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
375 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
376 if (pArgPrintValues->GetFound())
377 eVarInfoFormat =
378 static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
379 pArgPrintValues->GetValue());
380
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;
388 }
389
390 lldb::SBValue &rValue = varObj.GetValue();
391 if (!ExamineSBValueForChange(rValue, m_bValueChanged))
392 return MIstatus::failure;
393
394 if (m_bValueChanged) {
395 varObj.UpdateValue();
396 const bool bPrintValue(
397 (eVarInfoFormat ==
398 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues) ||
399 (eVarInfoFormat ==
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,
405 strInScope);
406 }
407
408 return MIstatus::success;
409 }
410
411 //++
412 //------------------------------------------------------------------------------------
413 // Details: The invoker requires this function. The command prepares a MI Record
414 // Result
415 // for the work carried out in the Execute().
416 // Type: Overridden.
417 // Args: None.
418 // Return: MIstatus::success - Functional succeeded.
419 // MIstatus::failure - Functional failed.
420 // Throws: None.
421 //--
Acknowledge()422 bool CMICmdCmdVarUpdate::Acknowledge() {
423 if (m_bValueChanged) {
424 // MI print
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,
429 miValueResult);
430 m_miResultRecord = miRecordResult;
431 } else {
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,
437 miValueResult6);
438 m_miResultRecord = miRecordResult;
439 }
440
441 return MIstatus::success;
442 }
443
444 //++
445 //------------------------------------------------------------------------------------
446 // Details: Required by the CMICmdFactory when registering *this command. The
447 // factory
448 // calls this function to create an instance of *this command.
449 // Type: Static method.
450 // Args: None.
451 // Return: CMICmdBase * - Pointer to a new command.
452 // Throws: None.
453 //--
CreateSelf()454 CMICmdBase *CMICmdCmdVarUpdate::CreateSelf() {
455 return new CMICmdCmdVarUpdate();
456 }
457
458 //++
459 //------------------------------------------------------------------------------------
460 // Details: Form the MI response for multiple variables.
461 // Type: Method.
462 // Args: vrStrVarName - (R) Session var object's name.
463 // vpValue - (R) Text version of the value held in the
464 // variable.
465 // vrStrScope - (R) In scope "yes" or "no".
466 // Return: None.
467 // Throws: None.
468 //--
MIFormResponse(const CMIUtilString & vrStrVarName,const char * const vpValue,const CMIUtilString & vrStrScope)469 void CMICmdCmdVarUpdate::MIFormResponse(const CMIUtilString &vrStrVarName,
470 const char *const vpValue,
471 const CMIUtilString &vrStrScope) {
472 // MI print
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);
481 }
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);
492 }
493
494 //++
495 //------------------------------------------------------------------------------------
496 // Details: Determine if the var object was changed.
497 // Type: Method.
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.
503 // Throws: None.
504 //--
ExamineSBValueForChange(lldb::SBValue & vrwValue,bool & vrwbChanged)505 bool CMICmdCmdVarUpdate::ExamineSBValueForChange(lldb::SBValue &vrwValue,
506 bool &vrwbChanged) {
507 if (vrwValue.GetValueDidChange()) {
508 vrwbChanged = true;
509 return MIstatus::success;
510 }
511
512 const MIuint nChildren = vrwValue.GetNumChildren();
513 for (MIuint i = 0; i < nChildren; ++i) {
514 lldb::SBValue member = vrwValue.GetChildAtIndex(i);
515 if (!member.IsValid())
516 continue;
517
518 // skip pointers and references to avoid infinite loop
519 if (member.GetType().GetTypeFlags() &
520 (lldb::eTypeIsPointer | lldb::eTypeIsReference))
521 continue;
522
523 // Handle composite types (i.e. struct or arrays)
524 if (ExamineSBValueForChange(member, vrwbChanged) && vrwbChanged)
525 return MIstatus::success;
526 }
527 vrwbChanged = false;
528 return MIstatus::success;
529 }
530
531 //---------------------------------------------------------------------------------------
532 //---------------------------------------------------------------------------------------
533 //---------------------------------------------------------------------------------------
534
535 //++
536 //------------------------------------------------------------------------------------
537 // Details: CMICmdCmdVarDelete constructor.
538 // Type: Method.
539 // Args: None.
540 // Return: None.
541 // Throws: None.
542 //--
CMICmdCmdVarDelete()543 CMICmdCmdVarDelete::CMICmdCmdVarDelete() : m_constStrArgName("name") {
544 // Command factory matches this name with that received from the stdin stream
545 m_strMiCmd = "var-delete";
546
547 // Required by the CMICmdFactory when registering *this command
548 m_pSelfCreatorFn = &CMICmdCmdVarDelete::CreateSelf;
549 }
550
551 //++
552 //------------------------------------------------------------------------------------
553 // Details: The invoker requires this function. The parses the command line
554 // options
555 // arguments to extract values for each of those arguments.
556 // Type: Overridden.
557 // Args: None.
558 // Return: MIstatus::success - Functional succeeded.
559 // MIstatus::failure - Functional failed.
560 // Throws: None.
561 //--
ParseArgs()562 bool CMICmdCmdVarDelete::ParseArgs() {
563 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
564 return ParseValidateCmdOptions();
565 }
566
567 //++
568 //------------------------------------------------------------------------------------
569 // Details: CMICmdCmdVarDelete destructor.
570 // Type: Overrideable.
571 // Args: None.
572 // Return: None.
573 // Throws: None.
574 //--
~CMICmdCmdVarDelete()575 CMICmdCmdVarDelete::~CMICmdCmdVarDelete() {}
576
577 //++
578 //------------------------------------------------------------------------------------
579 // Details: The invoker requires this function. The command does work in this
580 // function.
581 // The command is likely to communicate with the LLDB SBDebugger in
582 // here.
583 // Type: Overridden.
584 // Args: None.
585 // Return: MIstatus::success - Functional succeeded.
586 // MIstatus::failure - Functional failed.
587 // Throws: None.
588 //--
Execute()589 bool CMICmdCmdVarDelete::Execute() {
590 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
591
592 const CMIUtilString &rVarObjName(pArgName->GetValue());
593 CMICmnLLDBDebugSessionInfoVarObj::VarObjDelete(rVarObjName);
594
595 return MIstatus::success;
596 }
597
598 //++
599 //------------------------------------------------------------------------------------
600 // Details: The invoker requires this function. The command prepares a MI Record
601 // Result
602 // for the work carried out in the Execute().
603 // Type: Overridden.
604 // Args: None.
605 // Return: MIstatus::success - Functional succeeded.
606 // MIstatus::failure - Functional failed.
607 // Throws: None.
608 //--
Acknowledge()609 bool CMICmdCmdVarDelete::Acknowledge() {
610 const CMICmnMIResultRecord miRecordResult(
611 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
612 m_miResultRecord = miRecordResult;
613
614 return MIstatus::success;
615 }
616
617 //++
618 //------------------------------------------------------------------------------------
619 // Details: Required by the CMICmdFactory when registering *this command. The
620 // factory
621 // calls this function to create an instance of *this command.
622 // Type: Static method.
623 // Args: None.
624 // Return: CMICmdBase * - Pointer to a new command.
625 // Throws: None.
626 //--
CreateSelf()627 CMICmdBase *CMICmdCmdVarDelete::CreateSelf() {
628 return new CMICmdCmdVarDelete();
629 }
630
631 //---------------------------------------------------------------------------------------
632 //---------------------------------------------------------------------------------------
633 //---------------------------------------------------------------------------------------
634
635 //++
636 //------------------------------------------------------------------------------------
637 // Details: CMICmdCmdVarAssign constructor.
638 // Type: Method.
639 // Args: None.
640 // Return: None.
641 // Throws: None.
642 //--
CMICmdCmdVarAssign()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";
648
649 // Required by the CMICmdFactory when registering *this command
650 m_pSelfCreatorFn = &CMICmdCmdVarAssign::CreateSelf;
651 }
652
653 //++
654 //------------------------------------------------------------------------------------
655 // Details: CMICmdCmdVarAssign destructor.
656 // Type: Overrideable.
657 // Args: None.
658 // Return: None.
659 // Throws: None.
660 //--
~CMICmdCmdVarAssign()661 CMICmdCmdVarAssign::~CMICmdCmdVarAssign() {}
662
663 //++
664 //------------------------------------------------------------------------------------
665 // Details: The invoker requires this function. The parses the command line
666 // options
667 // arguments to extract values for each of those arguments.
668 // Type: Overridden.
669 // Args: None.
670 // Return: MIstatus::success - Functional succeeded.
671 // MIstatus::failure - Functional failed.
672 // Throws: None.
673 //--
ParseArgs()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();
678 }
679
680 //++
681 //------------------------------------------------------------------------------------
682 // Details: The invoker requires this function. The command does work in this
683 // function.
684 // The command is likely to communicate with the LLDB SBDebugger in
685 // here.
686 // Type: Overridden.
687 // Args: None.
688 // Return: MIstatus::success - Functional succeeded.
689 // MIstatus::failure - Functional failed.
690 // Throws: None.
691 //--
Execute()692 bool CMICmdCmdVarAssign::Execute() {
693 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
694 CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
695
696 const CMIUtilString &rVarObjName(pArgName->GetValue());
697 const CMIUtilString &rExpression(pArgExpression->GetValue());
698
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;
705 }
706 m_varObjName = rVarObjName;
707
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());
712 if (m_bOk)
713 varObj.UpdateValue();
714
715 return MIstatus::success;
716 }
717
718 //++
719 //------------------------------------------------------------------------------------
720 // Details: The invoker requires this function. The command prepares a MI Record
721 // Result
722 // for the work carried out in the Execute().
723 // Type: Overridden.
724 // Args: None.
725 // Return: MIstatus::success - Functional succeeded.
726 // MIstatus::failure - Functional failed.
727 // Throws: None.
728 //--
Acknowledge()729 bool CMICmdCmdVarAssign::Acknowledge() {
730 if (m_bOk) {
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,
738 miValueResult);
739 m_miResultRecord = miRecordResult;
740
741 return MIstatus::success;
742 }
743
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,
748 miValueResult);
749 m_miResultRecord = miRecordResult;
750
751 return MIstatus::success;
752 }
753
754 //++
755 //------------------------------------------------------------------------------------
756 // Details: Required by the CMICmdFactory when registering *this command. The
757 // factory
758 // calls this function to create an instance of *this command.
759 // Type: Static method.
760 // Args: None.
761 // Return: CMICmdBase * - Pointer to a new command.
762 // Throws: None.
763 //--
CreateSelf()764 CMICmdBase *CMICmdCmdVarAssign::CreateSelf() {
765 return new CMICmdCmdVarAssign();
766 }
767
768 //---------------------------------------------------------------------------------------
769 //---------------------------------------------------------------------------------------
770 //---------------------------------------------------------------------------------------
771
772 //++
773 //------------------------------------------------------------------------------------
774 // Details: CMICmdCmdVarSetFormat constructor.
775 // Type: Method.
776 // Args: None.
777 // Return: None.
778 // Throws: None.
779 //--
CMICmdCmdVarSetFormat()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";
784
785 // Required by the CMICmdFactory when registering *this command
786 m_pSelfCreatorFn = &CMICmdCmdVarSetFormat::CreateSelf;
787 }
788
789 //++
790 //------------------------------------------------------------------------------------
791 // Details: CMICmdCmdVarSetFormat destructor.
792 // Type: Overrideable.
793 // Args: None.
794 // Return: None.
795 // Throws: None.
796 //--
~CMICmdCmdVarSetFormat()797 CMICmdCmdVarSetFormat::~CMICmdCmdVarSetFormat() {}
798
799 //++
800 //------------------------------------------------------------------------------------
801 // Details: The invoker requires this function. The parses the command line
802 // options
803 // arguments to extract values for each of those arguments.
804 // Type: Overridden.
805 // Args: None.
806 // Return: MIstatus::success - Functional succeeded.
807 // MIstatus::failure - Functional failed.
808 // Throws: None.
809 //--
ParseArgs()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();
814 }
815
816 //++
817 //------------------------------------------------------------------------------------
818 // Details: The invoker requires this function. The command does work in this
819 // function.
820 // The command is likely to communicate with the LLDB SBDebugger in
821 // here.
822 // Type: Overridden.
823 // Args: None.
824 // Return: MIstatus::success - Functional succeeded.
825 // MIstatus::failure - Functional failed.
826 // Throws: None.
827 //--
Execute()828 bool CMICmdCmdVarSetFormat::Execute() {
829 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
830 CMICMDBASE_GETOPTION(pArgFormatSpec, String, m_constStrArgFormatSpec);
831
832 const CMIUtilString &rVarObjName(pArgName->GetValue());
833 const CMIUtilString &rExpression(pArgFormatSpec->GetValue());
834
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;
841 }
842 if (!varObj.SetVarFormat(
843 CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString(
844 rExpression))) {
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;
849 }
850 varObj.UpdateValue();
851
852 m_varObjName = rVarObjName;
853
854 return MIstatus::success;
855 }
856
857 //++
858 //------------------------------------------------------------------------------------
859 // Details: The invoker requires this function. The command prepares a MI Record
860 // Result
861 // for the work carried out in the Execute().
862 // Type: Overridden.
863 // Args: None.
864 // Return: MIstatus::success - Functional succeeded.
865 // MIstatus::failure - Functional failed.
866 // Throws: None.
867 //--
Acknowledge()868 bool CMICmdCmdVarSetFormat::Acknowledge() {
869 // MI print
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);
891
892 const CMICmnMIResultRecord miRecordResult(
893 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
894 miValueResult6);
895 m_miResultRecord = miRecordResult;
896
897 return MIstatus::success;
898 }
899
900 //++
901 //------------------------------------------------------------------------------------
902 // Details: Required by the CMICmdFactory when registering *this command. The
903 // factory
904 // calls this function to create an instance of *this command.
905 // Type: Static method.
906 // Args: None.
907 // Return: CMICmdBase * - Pointer to a new command.
908 // Throws: None.
909 //--
CreateSelf()910 CMICmdBase *CMICmdCmdVarSetFormat::CreateSelf() {
911 return new CMICmdCmdVarSetFormat();
912 }
913
914 //---------------------------------------------------------------------------------------
915 //---------------------------------------------------------------------------------------
916 //---------------------------------------------------------------------------------------
917
918 //++
919 //------------------------------------------------------------------------------------
920 // Details: CMICmdCmdVarListChildren constructor.
921 // Type: Method.
922 // Args: None.
923 // Return: None.
924 // Throws: None.
925 //--
CMICmdCmdVarListChildren()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";
932
933 // Required by the CMICmdFactory when registering *this command
934 m_pSelfCreatorFn = &CMICmdCmdVarListChildren::CreateSelf;
935 }
936
937 //++
938 //------------------------------------------------------------------------------------
939 // Details: CMICmdCmdVarListChildren destructor.
940 // Type: Overrideable.
941 // Args: None.
942 // Return: None.
943 // Throws: None.
944 //--
~CMICmdCmdVarListChildren()945 CMICmdCmdVarListChildren::~CMICmdCmdVarListChildren() {}
946
947 //++
948 //------------------------------------------------------------------------------------
949 // Details: The invoker requires this function. The parses the command line
950 // options
951 // arguments to extract values for each of those arguments.
952 // Type: Overridden.
953 // Args: None.
954 // Return: MIstatus::success - Functional succeeded.
955 // MIstatus::failure - Functional failed.
956 // Throws: None.
957 //--
ParseArgs()958 bool CMICmdCmdVarListChildren::ParseArgs() {
959 m_setCmdArgs.Add(
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();
965 }
966
967 //++
968 //------------------------------------------------------------------------------------
969 // Details: The invoker requires this function. The command does work in this
970 // function.
971 // The command is likely to communicate with the LLDB SBDebugger in
972 // here.
973 // Type: Overridden.
974 // Args: None.
975 // Return: MIstatus::success - Functional succeeded.
976 // MIstatus::failure - Functional failed.
977 // Throws: None.
978 //--
Execute()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);
984
985 CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
986 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
987 if (pArgPrintValues->GetFound())
988 eVarInfoFormat =
989 static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
990 pArgPrintValues->GetValue());
991
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;
999 }
1000
1001 MIuint nFrom = 0;
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
1008 SetError(
1009 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID),
1010 m_cmdData.strMiCmd.c_str()));
1011 return MIstatus::failure;
1012 }
1013
1014 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1015 m_bValueValid = rValue.IsValid();
1016 if (!m_bValueValid)
1017 return MIstatus::success;
1018
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(),
1030 strExp.c_str()));
1031 const MIuint nChildren = member.GetNumChildren();
1032 const CMIUtilString strThreadId(
1033 CMIUtilString::Format("%u", member.GetThread().GetIndexID()));
1034
1035 // Varobj gets added to CMICmnLLDBDebugSessionInfoVarObj static container of
1036 // varObjs
1037 CMICmnLLDBDebugSessionInfoVarObj var(strExp, name, member, rVarObjName);
1038
1039 // MI print
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 ||
1060 (eVarInfoFormat ==
1061 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues &&
1062 nChildren == 0)) {
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);
1069 }
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);
1075 }
1076
1077 return MIstatus::success;
1078 }
1079
1080 //++
1081 //------------------------------------------------------------------------------------
1082 // Details: The invoker requires this function. The command prepares a MI Record
1083 // Result
1084 // for the work carried out in the Execute().
1085 // Type: Overridden.
1086 // Args: None.
1087 // Return: MIstatus::success - Functional succeeded.
1088 // MIstatus::failure - Functional failed.
1089 // Throws: None.
1090 //--
Acknowledge()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);
1102
1103 const CMICmnMIResultRecord miRecordResult(
1104 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1105 miValueResult);
1106 m_miResultRecord = miRecordResult;
1107
1108 return MIstatus::success;
1109 }
1110
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,
1116 miValueResult);
1117 m_miResultRecord = miRecordResult;
1118
1119 return MIstatus::success;
1120 }
1121
1122 //++
1123 //------------------------------------------------------------------------------------
1124 // Details: Required by the CMICmdFactory when registering *this command. The
1125 // factory
1126 // calls this function to create an instance of *this command.
1127 // Type: Static method.
1128 // Args: None.
1129 // Return: CMICmdBase * - Pointer to a new command.
1130 // Throws: None.
1131 //--
CreateSelf()1132 CMICmdBase *CMICmdCmdVarListChildren::CreateSelf() {
1133 return new CMICmdCmdVarListChildren();
1134 }
1135
1136 //---------------------------------------------------------------------------------------
1137 //---------------------------------------------------------------------------------------
1138 //---------------------------------------------------------------------------------------
1139
1140 //++
1141 //------------------------------------------------------------------------------------
1142 // Details: CMICmdCmdVarEvaluateExpression constructor.
1143 // Type: Method.
1144 // Args: None.
1145 // Return: None.
1146 // Throws: None.
1147 //--
CMICmdCmdVarEvaluateExpression()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";
1153
1154 // Required by the CMICmdFactory when registering *this command
1155 m_pSelfCreatorFn = &CMICmdCmdVarEvaluateExpression::CreateSelf;
1156 }
1157
1158 //++
1159 //------------------------------------------------------------------------------------
1160 // Details: CMICmdCmdVarEvaluateExpression destructor.
1161 // Type: Overrideable.
1162 // Args: None.
1163 // Return: None.
1164 // Throws: None.
1165 //--
~CMICmdCmdVarEvaluateExpression()1166 CMICmdCmdVarEvaluateExpression::~CMICmdCmdVarEvaluateExpression() {}
1167
1168 //++
1169 //------------------------------------------------------------------------------------
1170 // Details: The invoker requires this function. The parses the command line
1171 // options
1172 // arguments to extract values for each of those arguments.
1173 // Type: Overridden.
1174 // Args: None.
1175 // Return: MIstatus::success - Functional succeeded.
1176 // MIstatus::failure - Functional failed.
1177 // Throws: None.
1178 //--
ParseArgs()1179 bool CMICmdCmdVarEvaluateExpression::ParseArgs() {
1180 m_setCmdArgs.Add(
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();
1185 }
1186
1187 //++
1188 //------------------------------------------------------------------------------------
1189 // Details: The invoker requires this function. The command does work in this
1190 // function.
1191 // The command is likely to communicate with the LLDB SBDebugger in
1192 // here.
1193 // Type: Overridden.
1194 // Args: None.
1195 // Return: MIstatus::success - Functional succeeded.
1196 // MIstatus::failure - Functional failed.
1197 // Throws: None.
1198 //--
Execute()1199 bool CMICmdCmdVarEvaluateExpression::Execute() {
1200 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1201
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;
1209 }
1210
1211 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1212 m_bValueValid = rValue.IsValid();
1213 if (!m_bValueValid)
1214 return MIstatus::success;
1215
1216 m_varObjName = rVarObjName;
1217 varObj.UpdateValue();
1218
1219 return MIstatus::success;
1220 }
1221
1222 //++
1223 //------------------------------------------------------------------------------------
1224 // Details: The invoker requires this function. The command prepares a MI Record
1225 // Result
1226 // for the work carried out in the Execute().
1227 // Type: Overridden.
1228 // Args: None.
1229 // Return: MIstatus::success - Functional succeeded.
1230 // MIstatus::failure - Functional failed.
1231 // Throws: None.
1232 //--
Acknowledge()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,
1241 miValueResult);
1242 m_miResultRecord = miRecordResult;
1243 return MIstatus::success;
1244 }
1245
1246 const CMICmnMIValueConst miValueConst("variable invalid");
1247 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1248 const CMICmnMIResultRecord miRecordResult(
1249 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1250 miValueResult);
1251 m_miResultRecord = miRecordResult;
1252 return MIstatus::success;
1253 }
1254
1255 //++
1256 //------------------------------------------------------------------------------------
1257 // Details: Required by the CMICmdFactory when registering *this command. The
1258 // factory
1259 // calls this function to create an instance of *this command.
1260 // Type: Static method.
1261 // Args: None.
1262 // Return: CMICmdBase * - Pointer to a new command.
1263 // Throws: None.
1264 //--
CreateSelf()1265 CMICmdBase *CMICmdCmdVarEvaluateExpression::CreateSelf() {
1266 return new CMICmdCmdVarEvaluateExpression();
1267 }
1268
1269 //---------------------------------------------------------------------------------------
1270 //---------------------------------------------------------------------------------------
1271 //---------------------------------------------------------------------------------------
1272
1273 //++
1274 //------------------------------------------------------------------------------------
1275 // Details: CMICmdCmdVarInfoPathExpression constructor.
1276 // Type: Method.
1277 // Args: None.
1278 // Return: None.
1279 // Throws: None.
1280 //--
CMICmdCmdVarInfoPathExpression()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";
1285
1286 // Required by the CMICmdFactory when registering *this command
1287 m_pSelfCreatorFn = &CMICmdCmdVarInfoPathExpression::CreateSelf;
1288 }
1289
1290 //++
1291 //------------------------------------------------------------------------------------
1292 // Details: CMICmdCmdVarInfoPathExpression destructor.
1293 // Type: Overrideable.
1294 // Args: None.
1295 // Return: None.
1296 // Throws: None.
1297 //--
~CMICmdCmdVarInfoPathExpression()1298 CMICmdCmdVarInfoPathExpression::~CMICmdCmdVarInfoPathExpression() {}
1299
1300 //++
1301 //------------------------------------------------------------------------------------
1302 // Details: The invoker requires this function. The parses the command line
1303 // options
1304 // arguments to extract values for each of those arguments.
1305 // Type: Overridden.
1306 // Args: None.
1307 // Return: MIstatus::success - Functional succeeded.
1308 // MIstatus::failure - Functional failed.
1309 // Throws: None.
1310 //--
ParseArgs()1311 bool CMICmdCmdVarInfoPathExpression::ParseArgs() {
1312 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1313 return ParseValidateCmdOptions();
1314 }
1315
1316 //++
1317 //------------------------------------------------------------------------------------
1318 // Details: The invoker requires this function. The command does work in this
1319 // function.
1320 // The command is likely to communicate with the LLDB SBDebugger in
1321 // here.
1322 // Type: Overridden.
1323 // Args: None.
1324 // Return: MIstatus::success - Functional succeeded.
1325 // MIstatus::failure - Functional failed.
1326 // Throws: None.
1327 //--
Execute()1328 bool CMICmdCmdVarInfoPathExpression::Execute() {
1329 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1330
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;
1338 }
1339
1340 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1341 m_bValueValid = rValue.IsValid();
1342 if (!m_bValueValid)
1343 return MIstatus::success;
1344
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;
1351 }
1352
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;
1358 }
1359
1360 // Has LLDB returned a var signature of it's own
1361 if (pPathExpression[0] != '$') {
1362 m_strPathExpression = pPathExpression;
1363 return MIstatus::success;
1364 }
1365
1366 // Build expression from what we do know
1367 const CMIUtilString &rVarParentName(varObj.GetVarParentName());
1368 if (rVarParentName.empty()) {
1369 m_strPathExpression = varObj.GetNameReal();
1370 } else {
1371 CMICmnLLDBDebugSessionInfoVarObj varObjParent;
1372 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarParentName,
1373 varObjParent)) {
1374 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1375 m_cmdData.strMiCmd.c_str(),
1376 rVarParentName.c_str()));
1377 return MIstatus::failure;
1378 }
1379 m_strPathExpression =
1380 CMIUtilString::Format("%s.%s", varObjParent.GetNameReal().c_str(),
1381 varObj.GetNameReal().c_str());
1382 }
1383
1384 return MIstatus::success;
1385 }
1386
1387 //++
1388 //------------------------------------------------------------------------------------
1389 // Details: The invoker requires this function. The command prepares a MI Record
1390 // Result
1391 // for the work carried out in the Execute().
1392 // Type: Overridden.
1393 // Args: None.
1394 // Return: MIstatus::success - Functional succeeded.
1395 // MIstatus::failure - Functional failed.
1396 // Throws: None.
1397 //--
Acknowledge()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,
1404 miValueResult);
1405 m_miResultRecord = miRecordResult;
1406 return MIstatus::success;
1407 }
1408
1409 const CMICmnMIValueConst miValueConst("variable invalid");
1410 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1411 const CMICmnMIResultRecord miRecordResult(
1412 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1413 miValueResult);
1414 m_miResultRecord = miRecordResult;
1415
1416 return MIstatus::success;
1417 }
1418
1419 //++
1420 //------------------------------------------------------------------------------------
1421 // Details: Required by the CMICmdFactory when registering *this command. The
1422 // factory
1423 // calls this function to create an instance of *this command.
1424 // Type: Static method.
1425 // Args: None.
1426 // Return: CMICmdBase * - Pointer to a new command.
1427 // Throws: None.
1428 //--
CreateSelf()1429 CMICmdBase *CMICmdCmdVarInfoPathExpression::CreateSelf() {
1430 return new CMICmdCmdVarInfoPathExpression();
1431 }
1432
1433 //---------------------------------------------------------------------------------------
1434 //---------------------------------------------------------------------------------------
1435 //---------------------------------------------------------------------------------------
1436
1437 //++
1438 //------------------------------------------------------------------------------------
1439 // Details: CMICmdCmdVarShowAttributes constructor.
1440 // Type: Method.
1441 // Args: None.
1442 // Return: None.
1443 // Throws: None.
1444 //--
CMICmdCmdVarShowAttributes()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";
1449
1450 // Required by the CMICmdFactory when registering *this command
1451 m_pSelfCreatorFn = &CMICmdCmdVarShowAttributes::CreateSelf;
1452 }
1453
1454 //++
1455 //------------------------------------------------------------------------------------
1456 // Details: CMICmdCmdVarShowAttributes destructor.
1457 // Type: Overrideable.
1458 // Args: None.
1459 // Return: None.
1460 // Throws: None.
1461 //--
~CMICmdCmdVarShowAttributes()1462 CMICmdCmdVarShowAttributes::~CMICmdCmdVarShowAttributes() {}
1463
1464 //++
1465 //------------------------------------------------------------------------------------
1466 // Details: The invoker requires this function. The parses the command line
1467 // options
1468 // arguments to extract values for each of those arguments.
1469 // Type: Overridden.
1470 // Args: None.
1471 // Return: MIstatus::success - Functional succeeded.
1472 // MIstatus::failure - Functional failed.
1473 // Throws: None.
1474 //--
ParseArgs()1475 bool CMICmdCmdVarShowAttributes::ParseArgs() {
1476 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1477 return ParseValidateCmdOptions();
1478 }
1479
1480 //++
1481 //------------------------------------------------------------------------------------
1482 // Details: The invoker requires this function. The command does work in this
1483 // function.
1484 // The command is likely to communicate with the LLDB SBDebugger in
1485 // here.
1486 // Type: Overridden.
1487 // Args: None.
1488 // Return: MIstatus::success - Functional succeeded.
1489 // MIstatus::failure - Functional failed.
1490 // Throws: None.
1491 //--
Execute()1492 bool CMICmdCmdVarShowAttributes::Execute() {
1493 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1494
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;
1502 }
1503
1504 return MIstatus::success;
1505 }
1506
1507 //++
1508 //------------------------------------------------------------------------------------
1509 // Details: The invoker requires this function. The command prepares a MI Record
1510 // Result
1511 // for the work carried out in the Execute().
1512 // Type: Overridden.
1513 // Args: None.
1514 // Return: MIstatus::success - Functional succeeded.
1515 // MIstatus::failure - Functional failed.
1516 // Throws: None.
1517 //--
Acknowledge()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,
1524 miValueResult);
1525 m_miResultRecord = miRecordResult;
1526
1527 return MIstatus::success;
1528 }
1529
1530 //++
1531 //------------------------------------------------------------------------------------
1532 // Details: Required by the CMICmdFactory when registering *this command. The
1533 // factory
1534 // calls this function to create an instance of *this command.
1535 // Type: Static method.
1536 // Args: None.
1537 // Return: CMICmdBase * - Pointer to a new command.
1538 // Throws: None.
1539 //--
CreateSelf()1540 CMICmdBase *CMICmdCmdVarShowAttributes::CreateSelf() {
1541 return new CMICmdCmdVarShowAttributes();
1542 }
1543