Files
llvm/lldb/source/Target/ABI.cpp
Sean Callanan 9301ec1191 Eliminated redundant "constructors" for ClangExpressionVariable.
The ClangExpressionVariable::CreateVariableInList functions looked cute, but                                                                                                                                           
caused more confusion than they solved.  I removed them, and instead made sure                                                                                                                                         
that there are adequate facilities for easily adding newly-constructed                                                                                                                                                 
ExpressionVariables to lists.      

I also made some of the constructors that are common be generic, so that it's
possible to construct expression variables from generic places (like the ABI and
ValueObject) without having to know the specifics about the class.

llvm-svn: 249095
2015-10-01 23:07:06 +00:00

214 lines
6.5 KiB
C++

//===-- ABI.cpp -------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/Target/ABI.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
ABISP
ABI::FindPlugin (const ArchSpec &arch)
{
ABISP abi_sp;
ABICreateInstance create_callback;
for (uint32_t idx = 0;
(create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != NULL;
++idx)
{
abi_sp = create_callback(arch);
if (abi_sp)
return abi_sp;
}
abi_sp.reset();
return abi_sp;
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
ABI::ABI()
{
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
ABI::~ABI()
{
}
bool
ABI::GetRegisterInfoByName (const ConstString &name, RegisterInfo &info)
{
uint32_t count = 0;
const RegisterInfo *register_info_array = GetRegisterInfoArray (count);
if (register_info_array)
{
const char *unique_name_cstr = name.GetCString();
uint32_t i;
for (i=0; i<count; ++i)
{
if (register_info_array[i].name == unique_name_cstr)
{
info = register_info_array[i];
return true;
}
}
for (i=0; i<count; ++i)
{
if (register_info_array[i].alt_name == unique_name_cstr)
{
info = register_info_array[i];
return true;
}
}
}
return false;
}
bool
ABI::GetRegisterInfoByKind (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &info)
{
if (reg_kind < eRegisterKindEHFrame || reg_kind >= kNumRegisterKinds)
return false;
uint32_t count = 0;
const RegisterInfo *register_info_array = GetRegisterInfoArray (count);
if (register_info_array)
{
for (uint32_t i=0; i<count; ++i)
{
if (register_info_array[i].kinds[reg_kind] == reg_num)
{
info = register_info_array[i];
return true;
}
}
}
return false;
}
ValueObjectSP
ABI::GetReturnValueObject (Thread &thread,
CompilerType &ast_type,
bool persistent) const
{
if (!ast_type.IsValid())
return ValueObjectSP();
ValueObjectSP return_valobj_sp;
return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);
if (!return_valobj_sp)
return return_valobj_sp;
// Now turn this into a persistent variable.
// FIXME: This code is duplicated from Target::EvaluateExpression, and it is used in similar form in a couple
// of other places. Figure out the correct Create function to do all this work.
if (persistent)
{
PersistentExpressionState *persistent_expression_state = thread.CalculateTarget()->GetPersistentExpressionStateForLanguage(ast_type.GetMinimumLanguage());
if (!persistent_expression_state)
return ValueObjectSP();
ConstString persistent_variable_name (persistent_expression_state->GetNextPersistentVariableName());
lldb::ValueObjectSP const_valobj_sp;
// Check in case our value is already a constant value
if (return_valobj_sp->GetIsConstant())
{
const_valobj_sp = return_valobj_sp;
const_valobj_sp->SetName (persistent_variable_name);
}
else
const_valobj_sp = return_valobj_sp->CreateConstantValue (persistent_variable_name);
lldb::ValueObjectSP live_valobj_sp = return_valobj_sp;
return_valobj_sp = const_valobj_sp;
ExpressionVariableSP clang_expr_variable_sp(persistent_expression_state->CreatePersistentVariable(return_valobj_sp));
assert (clang_expr_variable_sp.get());
// Set flags and live data as appropriate
const Value &result_value = live_valobj_sp->GetValue();
switch (result_value.GetValueType())
{
case Value::eValueTypeHostAddress:
case Value::eValueTypeFileAddress:
// we don't do anything with these for now
break;
case Value::eValueTypeScalar:
case Value::eValueTypeVector:
clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried;
clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
break;
case Value::eValueTypeLoadAddress:
clang_expr_variable_sp->m_live_sp = live_valobj_sp;
clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference;
break;
}
return_valobj_sp = clang_expr_variable_sp->GetValueObject();
}
return return_valobj_sp;
}
ValueObjectSP
ABI::GetReturnValueObject(Thread &thread, llvm::Type &ast_type, bool persistent) const
{
ValueObjectSP return_valobj_sp;
return_valobj_sp = GetReturnValueObjectImpl( thread, ast_type );
return return_valobj_sp;
}
// specialized to work with llvm IR types
//
// for now we will specify a default implementation so that we don't need to
// modify other ABIs
lldb::ValueObjectSP
ABI::GetReturnValueObjectImpl( Thread &thread, llvm::Type &ir_type ) const
{
ValueObjectSP return_valobj_sp;
/* this is a dummy and will only be called if an ABI does not override this */
return return_valobj_sp;
}
bool
ABI::PrepareTrivialCall (Thread &thread,
lldb::addr_t sp,
lldb::addr_t functionAddress,
lldb::addr_t returnAddress,
llvm::Type &returntype,
llvm::ArrayRef<ABI::CallArgument> args) const
{
// dummy prepare trivial call
assert( !"Should never get here!" );
return false;
}