mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-08 13:06:07 +00:00

Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
267 lines
8.1 KiB
C++
267 lines
8.1 KiB
C++
//===-- CommandObjectArgs.cpp -----------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "CommandObjectArgs.h"
|
|
|
|
// C Includes
|
|
// C++ Includes
|
|
// Other libraries and framework includes
|
|
// Project includes
|
|
#include "lldb/Interpreter/Args.h"
|
|
#include "lldb/Core/Debugger.h"
|
|
#include "lldb/Core/Module.h"
|
|
#include "lldb/Core/Value.h"
|
|
#include "lldb/Expression/ClangExpression.h"
|
|
#include "lldb/Expression/ClangExpressionVariable.h"
|
|
#include "lldb/Expression/ClangFunction.h"
|
|
#include "lldb/Host/Host.h"
|
|
#include "lldb/Interpreter/CommandInterpreter.h"
|
|
#include "lldb/Interpreter/CommandReturnObject.h"
|
|
#include "lldb/Symbol/ClangASTContext.h"
|
|
#include "lldb/Symbol/ObjectFile.h"
|
|
#include "lldb/Symbol/Variable.h"
|
|
#include "lldb/Target/ABI.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Target/Target.h"
|
|
#include "lldb/Target/Thread.h"
|
|
#include "lldb/Target/StackFrame.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
// This command is a toy. I'm just using it to have a way to construct the arguments to
|
|
// calling functions.
|
|
//
|
|
|
|
CommandObjectArgs::CommandOptions::CommandOptions (CommandInterpreter &interpreter) :
|
|
Options(interpreter)
|
|
{
|
|
// Keep only one place to reset the values to their defaults
|
|
OptionParsingStarting();
|
|
}
|
|
|
|
|
|
CommandObjectArgs::CommandOptions::~CommandOptions ()
|
|
{
|
|
}
|
|
|
|
Error
|
|
CommandObjectArgs::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
|
|
{
|
|
Error error;
|
|
|
|
const int short_option = m_getopt_table[option_idx].val;
|
|
error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
|
|
|
|
return error;
|
|
}
|
|
|
|
void
|
|
CommandObjectArgs::CommandOptions::OptionParsingStarting ()
|
|
{
|
|
}
|
|
|
|
const OptionDefinition*
|
|
CommandObjectArgs::CommandOptions::GetDefinitions ()
|
|
{
|
|
return g_option_table;
|
|
}
|
|
|
|
CommandObjectArgs::CommandObjectArgs (CommandInterpreter &interpreter) :
|
|
CommandObjectParsed (interpreter,
|
|
"args",
|
|
"When stopped at the start of a function, reads function arguments of type (u?)int(8|16|32|64)_t, (void|char)*",
|
|
"args"),
|
|
m_options (interpreter)
|
|
{
|
|
}
|
|
|
|
CommandObjectArgs::~CommandObjectArgs ()
|
|
{
|
|
}
|
|
|
|
Options *
|
|
CommandObjectArgs::GetOptions ()
|
|
{
|
|
return &m_options;
|
|
}
|
|
|
|
bool
|
|
CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result)
|
|
{
|
|
ConstString target_triple;
|
|
|
|
|
|
Process *process = m_exe_ctx.GetProcessPtr();
|
|
if (!process)
|
|
{
|
|
result.AppendError ("Args found no process.");
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
|
|
const ABI *abi = process->GetABI().get();
|
|
if (!abi)
|
|
{
|
|
result.AppendError ("The current process has no ABI.");
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
|
|
const size_t num_args = args.GetArgumentCount ();
|
|
size_t arg_index;
|
|
|
|
if (!num_args)
|
|
{
|
|
result.AppendError ("args requires at least one argument");
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
|
|
Thread *thread = m_exe_ctx.GetThreadPtr();
|
|
|
|
if (!thread)
|
|
{
|
|
result.AppendError ("args found no thread.");
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
|
|
lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame ();
|
|
if (!thread_cur_frame)
|
|
{
|
|
result.AppendError ("The current thread has no current frame.");
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
|
|
ModuleSP thread_module_sp (thread_cur_frame->GetFrameCodeAddress ().GetModule());
|
|
if (!thread_module_sp)
|
|
{
|
|
result.AppendError ("The PC has no associated module.");
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
|
|
ClangASTContext &ast_context = thread_module_sp->GetClangASTContext();
|
|
|
|
ValueList value_list;
|
|
|
|
for (arg_index = 0; arg_index < num_args; ++arg_index)
|
|
{
|
|
const char *arg_type_cstr = args.GetArgumentAtIndex(arg_index);
|
|
Value value;
|
|
value.SetValueType(Value::eValueTypeScalar);
|
|
CompilerType clang_type;
|
|
|
|
char *int_pos;
|
|
if ((int_pos = strstr (const_cast<char*>(arg_type_cstr), "int")))
|
|
{
|
|
Encoding encoding = eEncodingSint;
|
|
|
|
int width = 0;
|
|
|
|
if (int_pos > arg_type_cstr + 1)
|
|
{
|
|
result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
if (int_pos == arg_type_cstr + 1 && arg_type_cstr[0] != 'u')
|
|
{
|
|
result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
if (arg_type_cstr[0] == 'u')
|
|
{
|
|
encoding = eEncodingUint;
|
|
}
|
|
|
|
char *width_pos = int_pos + 3;
|
|
|
|
if (!strcmp (width_pos, "8_t"))
|
|
width = 8;
|
|
else if (!strcmp (width_pos, "16_t"))
|
|
width = 16;
|
|
else if (!strcmp (width_pos, "32_t"))
|
|
width = 32;
|
|
else if (!strcmp (width_pos, "64_t"))
|
|
width = 64;
|
|
else
|
|
{
|
|
result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
|
|
clang_type = ast_context.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
|
|
|
|
if (!clang_type.IsValid())
|
|
{
|
|
result.AppendErrorWithFormat ("Couldn't get Clang type for format %s (%s integer, width %d).\n",
|
|
arg_type_cstr,
|
|
(encoding == eEncodingSint ? "signed" : "unsigned"),
|
|
width);
|
|
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
}
|
|
else if (strchr (arg_type_cstr, '*'))
|
|
{
|
|
if (!strcmp (arg_type_cstr, "void*"))
|
|
clang_type = ast_context.GetBasicType(eBasicTypeVoid).GetPointerType();
|
|
else if (!strcmp (arg_type_cstr, "char*"))
|
|
clang_type = ast_context.GetCStringType (false);
|
|
else
|
|
{
|
|
result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
|
|
value.SetCompilerType (clang_type);
|
|
value_list.PushValue(value);
|
|
}
|
|
|
|
if (!abi->GetArgumentValues (*thread, value_list))
|
|
{
|
|
result.AppendError ("Couldn't get argument values");
|
|
result.SetStatus (eReturnStatusFailed);
|
|
return false;
|
|
}
|
|
|
|
result.GetOutputStream ().Printf("Arguments : \n");
|
|
|
|
for (arg_index = 0; arg_index < num_args; ++arg_index)
|
|
{
|
|
result.GetOutputStream ().Printf ("%" PRIu64 " (%s): ", (uint64_t)arg_index, args.GetArgumentAtIndex (arg_index));
|
|
value_list.GetValueAtIndex (arg_index)->Dump (&result.GetOutputStream ());
|
|
result.GetOutputStream ().Printf("\n");
|
|
}
|
|
|
|
return result.Succeeded();
|
|
}
|
|
|
|
OptionDefinition
|
|
CommandObjectArgs::CommandOptions::g_option_table[] =
|
|
{
|
|
{ LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."},
|
|
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
|
|
};
|
|
|