1 //===-- CommandObjectArgs.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 #include "lldb/lldb-python.h"
12 #include "CommandObjectArgs.h"
16 // Other libraries and framework includes
18 #include "lldb/Interpreter/Args.h"
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/Module.h"
21 #include "lldb/Core/Value.h"
22 #include "lldb/Expression/ClangExpression.h"
23 #include "lldb/Expression/ClangExpressionVariable.h"
24 #include "lldb/Expression/ClangFunction.h"
25 #include "lldb/Host/Host.h"
26 #include "lldb/Interpreter/CommandInterpreter.h"
27 #include "lldb/Interpreter/CommandReturnObject.h"
28 #include "lldb/Symbol/ObjectFile.h"
29 #include "lldb/Symbol/Variable.h"
30 #include "lldb/Target/Process.h"
31 #include "lldb/Target/Target.h"
32 #include "lldb/Target/Thread.h"
33 #include "lldb/Target/StackFrame.h"
36 using namespace lldb_private;
38 // This command is a toy. I'm just using it to have a way to construct the arguments to
42 CommandObjectArgs::CommandOptions::CommandOptions (CommandInterpreter &interpreter) :
45 // Keep only one place to reset the values to their defaults
46 OptionParsingStarting();
50 CommandObjectArgs::CommandOptions::~CommandOptions ()
55 CommandObjectArgs::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
59 const int short_option = m_getopt_table[option_idx].val;
64 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
72 CommandObjectArgs::CommandOptions::OptionParsingStarting ()
76 const OptionDefinition*
77 CommandObjectArgs::CommandOptions::GetDefinitions ()
79 return g_option_table;
82 CommandObjectArgs::CommandObjectArgs (CommandInterpreter &interpreter) :
83 CommandObjectParsed (interpreter,
85 "When stopped at the start of a function, reads function arguments of type (u?)int(8|16|32|64)_t, (void|char)*",
87 m_options (interpreter)
91 CommandObjectArgs::~CommandObjectArgs ()
96 CommandObjectArgs::GetOptions ()
102 CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result)
104 ConstString target_triple;
107 Process *process = m_exe_ctx.GetProcessPtr();
110 result.AppendError ("Args found no process.");
111 result.SetStatus (eReturnStatusFailed);
115 const ABI *abi = process->GetABI().get();
118 result.AppendError ("The current process has no ABI.");
119 result.SetStatus (eReturnStatusFailed);
123 const size_t num_args = args.GetArgumentCount ();
128 result.AppendError ("args requires at least one argument");
129 result.SetStatus (eReturnStatusFailed);
133 Thread *thread = m_exe_ctx.GetThreadPtr();
137 result.AppendError ("args found no thread.");
138 result.SetStatus (eReturnStatusFailed);
142 lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame ();
143 if (!thread_cur_frame)
145 result.AppendError ("The current thread has no current frame.");
146 result.SetStatus (eReturnStatusFailed);
150 ModuleSP thread_module_sp (thread_cur_frame->GetFrameCodeAddress ().GetModule());
151 if (!thread_module_sp)
153 result.AppendError ("The PC has no associated module.");
154 result.SetStatus (eReturnStatusFailed);
158 ClangASTContext &ast_context = thread_module_sp->GetClangASTContext();
160 ValueList value_list;
162 for (arg_index = 0; arg_index < num_args; ++arg_index)
164 const char *arg_type_cstr = args.GetArgumentAtIndex(arg_index);
166 value.SetValueType(Value::eValueTypeScalar);
167 ClangASTType clang_type;
170 if ((int_pos = strstr (const_cast<char*>(arg_type_cstr), "int")))
172 Encoding encoding = eEncodingSint;
176 if (int_pos > arg_type_cstr + 1)
178 result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
179 result.SetStatus (eReturnStatusFailed);
182 if (int_pos == arg_type_cstr + 1 && arg_type_cstr[0] != 'u')
184 result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
185 result.SetStatus (eReturnStatusFailed);
188 if (arg_type_cstr[0] == 'u')
190 encoding = eEncodingUint;
193 char *width_pos = int_pos + 3;
195 if (!strcmp (width_pos, "8_t"))
197 else if (!strcmp (width_pos, "16_t"))
199 else if (!strcmp (width_pos, "32_t"))
201 else if (!strcmp (width_pos, "64_t"))
205 result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
206 result.SetStatus (eReturnStatusFailed);
210 clang_type = ast_context.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
212 if (!clang_type.IsValid())
214 result.AppendErrorWithFormat ("Couldn't get Clang type for format %s (%s integer, width %d).\n",
216 (encoding == eEncodingSint ? "signed" : "unsigned"),
219 result.SetStatus (eReturnStatusFailed);
223 else if (strchr (arg_type_cstr, '*'))
225 if (!strcmp (arg_type_cstr, "void*"))
226 clang_type = ast_context.GetBasicType(eBasicTypeVoid).GetPointerType();
227 else if (!strcmp (arg_type_cstr, "char*"))
228 clang_type = ast_context.GetCStringType (false);
231 result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
232 result.SetStatus (eReturnStatusFailed);
238 result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
239 result.SetStatus (eReturnStatusFailed);
243 value.SetClangType (clang_type);
244 value_list.PushValue(value);
247 if (!abi->GetArgumentValues (*thread, value_list))
249 result.AppendError ("Couldn't get argument values");
250 result.SetStatus (eReturnStatusFailed);
254 result.GetOutputStream ().Printf("Arguments : \n");
256 for (arg_index = 0; arg_index < num_args; ++arg_index)
258 result.GetOutputStream ().Printf ("%zu (%s): ", arg_index, args.GetArgumentAtIndex (arg_index));
259 value_list.GetValueAtIndex (arg_index)->Dump (&result.GetOutputStream ());
260 result.GetOutputStream ().Printf("\n");
263 return result.Succeeded();
267 CommandObjectArgs::CommandOptions::g_option_table[] =
269 { LLDB_OPT_SET_1, false, "debug", 'g', no_argument, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."},
270 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }