mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-01 17:26:04 +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
438 lines
11 KiB
C++
438 lines
11 KiB
C++
//===-- ValueObjectRegister.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/Core/ValueObjectRegister.h"
|
|
|
|
// C Includes
|
|
// C++ Includes
|
|
// Other libraries and framework includes
|
|
// Project includes
|
|
#include "lldb/Core/Module.h"
|
|
#include "lldb/Symbol/CompilerType.h"
|
|
#include "lldb/Symbol/ClangASTContext.h"
|
|
#include "lldb/Symbol/TypeList.h"
|
|
#include "lldb/Target/ExecutionContext.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Target/RegisterContext.h"
|
|
#include "lldb/Target/Target.h"
|
|
#include "lldb/Target/Thread.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
#pragma mark ValueObjectRegisterContext
|
|
|
|
ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject &parent, RegisterContextSP ®_ctx) :
|
|
ValueObject (parent),
|
|
m_reg_ctx_sp (reg_ctx)
|
|
{
|
|
assert (reg_ctx);
|
|
m_name.SetCString("Registers");
|
|
SetValueIsValid (true);
|
|
}
|
|
|
|
ValueObjectRegisterContext::~ValueObjectRegisterContext()
|
|
{
|
|
}
|
|
|
|
CompilerType
|
|
ValueObjectRegisterContext::GetCompilerTypeImpl ()
|
|
{
|
|
return CompilerType();
|
|
}
|
|
|
|
ConstString
|
|
ValueObjectRegisterContext::GetTypeName()
|
|
{
|
|
return ConstString();
|
|
}
|
|
|
|
ConstString
|
|
ValueObjectRegisterContext::GetDisplayTypeName()
|
|
{
|
|
return ConstString();
|
|
}
|
|
|
|
ConstString
|
|
ValueObjectRegisterContext::GetQualifiedTypeName()
|
|
{
|
|
return ConstString();
|
|
}
|
|
|
|
size_t
|
|
ValueObjectRegisterContext::CalculateNumChildren()
|
|
{
|
|
return m_reg_ctx_sp->GetRegisterSetCount();
|
|
}
|
|
|
|
uint64_t
|
|
ValueObjectRegisterContext::GetByteSize()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
bool
|
|
ValueObjectRegisterContext::UpdateValue ()
|
|
{
|
|
m_error.Clear();
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
StackFrame *frame = exe_ctx.GetFramePtr();
|
|
if (frame)
|
|
m_reg_ctx_sp = frame->GetRegisterContext();
|
|
else
|
|
m_reg_ctx_sp.reset();
|
|
|
|
if (m_reg_ctx_sp.get() == NULL)
|
|
{
|
|
SetValueIsValid (false);
|
|
m_error.SetErrorToGenericError();
|
|
}
|
|
else
|
|
SetValueIsValid (true);
|
|
|
|
return m_error.Success();
|
|
}
|
|
|
|
ValueObject *
|
|
ValueObjectRegisterContext::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
|
|
{
|
|
ValueObject *new_valobj = NULL;
|
|
|
|
const size_t num_children = GetNumChildren();
|
|
if (idx < num_children)
|
|
{
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
new_valobj = new ValueObjectRegisterSet(exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
|
|
}
|
|
|
|
return new_valobj;
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark ValueObjectRegisterSet
|
|
|
|
ValueObjectSP
|
|
ValueObjectRegisterSet::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, uint32_t set_idx)
|
|
{
|
|
return (new ValueObjectRegisterSet (exe_scope, reg_ctx_sp, set_idx))->GetSP();
|
|
}
|
|
|
|
|
|
ValueObjectRegisterSet::ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx, uint32_t reg_set_idx) :
|
|
ValueObject (exe_scope),
|
|
m_reg_ctx_sp (reg_ctx),
|
|
m_reg_set (NULL),
|
|
m_reg_set_idx (reg_set_idx)
|
|
{
|
|
assert (reg_ctx);
|
|
m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
|
|
if (m_reg_set)
|
|
{
|
|
m_name.SetCString (m_reg_set->name);
|
|
}
|
|
}
|
|
|
|
ValueObjectRegisterSet::~ValueObjectRegisterSet()
|
|
{
|
|
}
|
|
|
|
CompilerType
|
|
ValueObjectRegisterSet::GetCompilerTypeImpl ()
|
|
{
|
|
return CompilerType();
|
|
}
|
|
|
|
ConstString
|
|
ValueObjectRegisterSet::GetTypeName()
|
|
{
|
|
return ConstString();
|
|
}
|
|
|
|
ConstString
|
|
ValueObjectRegisterSet::GetQualifiedTypeName()
|
|
{
|
|
return ConstString();
|
|
}
|
|
|
|
size_t
|
|
ValueObjectRegisterSet::CalculateNumChildren()
|
|
{
|
|
const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
|
|
if (reg_set)
|
|
return reg_set->num_registers;
|
|
return 0;
|
|
}
|
|
|
|
uint64_t
|
|
ValueObjectRegisterSet::GetByteSize()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
bool
|
|
ValueObjectRegisterSet::UpdateValue ()
|
|
{
|
|
m_error.Clear();
|
|
SetValueDidChange (false);
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
StackFrame *frame = exe_ctx.GetFramePtr();
|
|
if (frame == NULL)
|
|
m_reg_ctx_sp.reset();
|
|
else
|
|
{
|
|
m_reg_ctx_sp = frame->GetRegisterContext ();
|
|
if (m_reg_ctx_sp)
|
|
{
|
|
const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet (m_reg_set_idx);
|
|
if (reg_set == NULL)
|
|
m_reg_ctx_sp.reset();
|
|
else if (m_reg_set != reg_set)
|
|
{
|
|
SetValueDidChange (true);
|
|
m_name.SetCString(reg_set->name);
|
|
}
|
|
}
|
|
}
|
|
if (m_reg_ctx_sp)
|
|
{
|
|
SetValueIsValid (true);
|
|
}
|
|
else
|
|
{
|
|
SetValueIsValid (false);
|
|
m_error.SetErrorToGenericError ();
|
|
m_children.Clear();
|
|
}
|
|
return m_error.Success();
|
|
}
|
|
|
|
|
|
ValueObject *
|
|
ValueObjectRegisterSet::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
|
|
{
|
|
ValueObject *valobj = NULL;
|
|
if (m_reg_ctx_sp && m_reg_set)
|
|
{
|
|
const size_t num_children = GetNumChildren();
|
|
if (idx < num_children)
|
|
valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, m_reg_set->registers[idx]);
|
|
}
|
|
return valobj;
|
|
}
|
|
|
|
lldb::ValueObjectSP
|
|
ValueObjectRegisterSet::GetChildMemberWithName (const ConstString &name, bool can_create)
|
|
{
|
|
ValueObject *valobj = NULL;
|
|
if (m_reg_ctx_sp && m_reg_set)
|
|
{
|
|
const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
|
|
if (reg_info != NULL)
|
|
valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]);
|
|
}
|
|
if (valobj)
|
|
return valobj->GetSP();
|
|
else
|
|
return ValueObjectSP();
|
|
}
|
|
|
|
size_t
|
|
ValueObjectRegisterSet::GetIndexOfChildWithName (const ConstString &name)
|
|
{
|
|
if (m_reg_ctx_sp && m_reg_set)
|
|
{
|
|
const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
|
|
if (reg_info != NULL)
|
|
return reg_info->kinds[eRegisterKindLLDB];
|
|
}
|
|
return UINT32_MAX;
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark ValueObjectRegister
|
|
|
|
void
|
|
ValueObjectRegister::ConstructObject (uint32_t reg_num)
|
|
{
|
|
const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex (reg_num);
|
|
if (reg_info)
|
|
{
|
|
m_reg_info = *reg_info;
|
|
if (reg_info->name)
|
|
m_name.SetCString(reg_info->name);
|
|
else if (reg_info->alt_name)
|
|
m_name.SetCString(reg_info->alt_name);
|
|
}
|
|
}
|
|
|
|
ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num) :
|
|
ValueObject (parent),
|
|
m_reg_ctx_sp (reg_ctx_sp),
|
|
m_reg_info (),
|
|
m_reg_value (),
|
|
m_type_name (),
|
|
m_clang_type ()
|
|
{
|
|
assert (reg_ctx_sp.get());
|
|
ConstructObject(reg_num);
|
|
}
|
|
|
|
ValueObjectSP
|
|
ValueObjectRegister::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num)
|
|
{
|
|
return (new ValueObjectRegister (exe_scope, reg_ctx_sp, reg_num))->GetSP();
|
|
}
|
|
|
|
ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx, uint32_t reg_num) :
|
|
ValueObject (exe_scope),
|
|
m_reg_ctx_sp (reg_ctx),
|
|
m_reg_info (),
|
|
m_reg_value (),
|
|
m_type_name (),
|
|
m_clang_type ()
|
|
{
|
|
assert (reg_ctx);
|
|
ConstructObject(reg_num);
|
|
}
|
|
|
|
ValueObjectRegister::~ValueObjectRegister()
|
|
{
|
|
}
|
|
|
|
CompilerType
|
|
ValueObjectRegister::GetCompilerTypeImpl ()
|
|
{
|
|
if (!m_clang_type.IsValid())
|
|
{
|
|
ExecutionContext exe_ctx (GetExecutionContextRef());
|
|
Target *target = exe_ctx.GetTargetPtr();
|
|
if (target)
|
|
{
|
|
Module *exe_module = target->GetExecutableModulePointer();
|
|
if (exe_module)
|
|
{
|
|
m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info.encoding,
|
|
m_reg_info.byte_size * 8);
|
|
}
|
|
}
|
|
}
|
|
return m_clang_type;
|
|
}
|
|
|
|
ConstString
|
|
ValueObjectRegister::GetTypeName()
|
|
{
|
|
if (m_type_name.IsEmpty())
|
|
m_type_name = GetCompilerType().GetConstTypeName ();
|
|
return m_type_name;
|
|
}
|
|
|
|
size_t
|
|
ValueObjectRegister::CalculateNumChildren()
|
|
{
|
|
return GetCompilerType().GetNumChildren(true);
|
|
}
|
|
|
|
uint64_t
|
|
ValueObjectRegister::GetByteSize()
|
|
{
|
|
return m_reg_info.byte_size;
|
|
}
|
|
|
|
bool
|
|
ValueObjectRegister::UpdateValue ()
|
|
{
|
|
m_error.Clear();
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
StackFrame *frame = exe_ctx.GetFramePtr();
|
|
if (frame == NULL)
|
|
{
|
|
m_reg_ctx_sp.reset();
|
|
m_reg_value.Clear();
|
|
}
|
|
|
|
|
|
if (m_reg_ctx_sp)
|
|
{
|
|
if (m_reg_ctx_sp->ReadRegister (&m_reg_info, m_reg_value))
|
|
{
|
|
if (m_reg_value.GetData (m_data))
|
|
{
|
|
Process *process = exe_ctx.GetProcessPtr();
|
|
if (process)
|
|
m_data.SetAddressByteSize(process->GetAddressByteSize());
|
|
m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)&m_reg_info);
|
|
m_value.SetValueType(Value::eValueTypeHostAddress);
|
|
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
|
|
SetValueIsValid (true);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
SetValueIsValid (false);
|
|
m_error.SetErrorToGenericError ();
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
ValueObjectRegister::SetValueFromCString (const char *value_str, Error& error)
|
|
{
|
|
// The new value will be in the m_data. Copy that into our register value.
|
|
error = m_reg_value.SetValueFromCString (&m_reg_info, value_str);
|
|
if (error.Success())
|
|
{
|
|
if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value))
|
|
{
|
|
SetNeedsUpdate();
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
ValueObjectRegister::SetData (DataExtractor &data, Error &error)
|
|
{
|
|
error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
|
|
if (error.Success())
|
|
{
|
|
if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value))
|
|
{
|
|
SetNeedsUpdate();
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
ValueObjectRegister::ResolveValue (Scalar &scalar)
|
|
{
|
|
if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
|
|
return m_reg_value.GetScalarValue(scalar);
|
|
return false;
|
|
}
|
|
|
|
void
|
|
ValueObjectRegister::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
|
|
{
|
|
s.Printf("$%s", m_reg_info.name);
|
|
}
|
|
|
|
|