llvm-project/lldb/source/Core/ValueObjectRegister.cpp
Greg Clayton 1be10fca5f Fixed the forward declaration issue that was present in the DWARF parser after
adding methods to C++ and objective C classes. In order to make methods, we
need the function prototype which means we need the arguments. Parsing these
could cause a circular reference that caused an  assertion.

Added a new typedef for the clang opaque types which are just void pointers:
lldb::clang_type_t. This appears in lldb-types.h.

This was fixed by enabling struct, union, class, and enum types to only get
a forward declaration when we make the clang opaque qual type for these
types. When they need to actually be resolved, lldb_private::Type will call
a new function in the SymbolFile protocol to resolve a clang type when it is
not fully defined (clang::TagDecl::getDefinition() returns NULL). This allows
us to be a lot more lazy when parsing clang types and keeps down the amount
of data that gets parsed into the ASTContext for each module. 

Getting the clang type from a "lldb_private::Type" object now takes a boolean
that indicates if a forward declaration is ok:

    clang_type_t lldb_private::Type::GetClangType (bool forward_decl_is_ok);
    
So function prototypes that define parameters that are "const T&" can now just
parse the forward declaration for type 'T' and we avoid circular references in
the type system.

llvm-svn: 115012
2010-09-29 01:12:09 +00:00

333 lines
7.6 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/ClangASTType.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 (RegisterContext *reg_ctx) :
ValueObject (),
m_reg_ctx (reg_ctx)
{
assert (reg_ctx);
m_name.SetCString("Registers");
SetValueIsValid (true);
}
ValueObjectRegisterContext::~ValueObjectRegisterContext()
{
}
void *
ValueObjectRegisterContext::GetClangType ()
{
return NULL;
}
ConstString
ValueObjectRegisterContext::GetTypeName()
{
ConstString empty_type_name;
return empty_type_name;
}
uint32_t
ValueObjectRegisterContext::CalculateNumChildren()
{
return m_reg_ctx->GetRegisterSetCount();
}
clang::ASTContext *
ValueObjectRegisterContext::GetClangAST ()
{
return NULL;
}
size_t
ValueObjectRegisterContext::GetByteSize()
{
return 0;
}
void
ValueObjectRegisterContext::UpdateValue (ExecutionContextScope *exe_scope)
{
m_error.Clear();
StackFrame *frame = exe_scope->CalculateStackFrame();
if (frame)
m_reg_ctx = frame->GetRegisterContext();
else
m_reg_ctx = NULL;
SetValueIsValid (m_reg_ctx != NULL);
}
ValueObjectSP
ValueObjectRegisterContext::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
ValueObjectSP valobj_sp;
const uint32_t num_children = GetNumChildren();
if (idx < num_children)
valobj_sp.reset (new ValueObjectRegisterSet(m_reg_ctx, idx));
return valobj_sp;
}
#pragma mark -
#pragma mark ValueObjectRegisterSet
ValueObjectRegisterSet::ValueObjectRegisterSet (RegisterContext *reg_ctx, uint32_t reg_set_idx) :
ValueObject (),
m_reg_ctx (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()
{
}
void *
ValueObjectRegisterSet::GetClangType ()
{
return NULL;
}
ConstString
ValueObjectRegisterSet::GetTypeName()
{
return ConstString();
}
uint32_t
ValueObjectRegisterSet::CalculateNumChildren()
{
const RegisterSet *reg_set = m_reg_ctx->GetRegisterSet(m_reg_set_idx);
if (reg_set)
return reg_set->num_registers;
return 0;
}
clang::ASTContext *
ValueObjectRegisterSet::GetClangAST ()
{
return NULL;
}
size_t
ValueObjectRegisterSet::GetByteSize()
{
return 0;
}
void
ValueObjectRegisterSet::UpdateValue (ExecutionContextScope *exe_scope)
{
m_error.Clear();
SetValueDidChange (false);
StackFrame *frame = exe_scope->CalculateStackFrame();
if (frame == NULL)
m_reg_ctx = NULL;
else
{
m_reg_ctx = frame->GetRegisterContext ();
if (m_reg_ctx)
{
const RegisterSet *reg_set = m_reg_ctx->GetRegisterSet (m_reg_set_idx);
if (reg_set == NULL)
m_reg_ctx = NULL;
else if (m_reg_set != reg_set)
{
SetValueDidChange (true);
m_name.SetCString(reg_set->name);
}
}
}
if (m_reg_ctx)
{
SetValueIsValid (true);
}
else
{
SetValueIsValid (false);
m_children.clear();
}
}
ValueObjectSP
ValueObjectRegisterSet::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
ValueObjectSP valobj_sp;
if (m_reg_ctx && m_reg_set)
{
const uint32_t num_children = GetNumChildren();
if (idx < num_children)
valobj_sp.reset (new ValueObjectRegister(m_reg_ctx, m_reg_set->registers[idx]));
}
return valobj_sp;
}
#pragma mark -
#pragma mark ValueObjectRegister
ValueObjectRegister::ValueObjectRegister (RegisterContext *reg_ctx, uint32_t reg_num) :
ValueObject (),
m_reg_ctx (reg_ctx),
m_reg_info (NULL),
m_reg_num (reg_num),
m_type_name (),
m_clang_type (NULL)
{
assert (reg_ctx);
m_reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
if (m_reg_info)
{
if (m_reg_info->name)
m_name.SetCString(m_reg_info->name);
else if (m_reg_info->alt_name)
m_name.SetCString(m_reg_info->alt_name);
}
}
ValueObjectRegister::~ValueObjectRegister()
{
}
void *
ValueObjectRegister::GetClangType ()
{
if (m_clang_type == NULL && m_reg_info)
{
Process *process = m_reg_ctx->CalculateProcess ();
if (process)
{
Module *exe_module = process->GetTarget().GetExecutableModule ().get();
if (exe_module)
{
TypeList *type_list = exe_module->GetTypeList();
if (type_list)
m_clang_type = type_list->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 = ClangASTType::GetClangTypeName (GetClangType());
return m_type_name;
}
uint32_t
ValueObjectRegister::CalculateNumChildren()
{
return 0;
}
clang::ASTContext *
ValueObjectRegister::GetClangAST ()
{
Process *process = m_reg_ctx->CalculateProcess ();
if (process)
{
Module *exe_module = process->GetTarget().GetExecutableModule ().get();
if (exe_module)
{
TypeList *type_list = exe_module->GetTypeList();
if (type_list)
return type_list->GetClangASTContext().getASTContext();
}
}
return NULL;
}
size_t
ValueObjectRegister::GetByteSize()
{
return m_reg_info->byte_size;
}
void
ValueObjectRegister::UpdateValue (ExecutionContextScope *exe_scope)
{
m_error.Clear();
StackFrame *frame = exe_scope->CalculateStackFrame();
if (frame)
{
m_reg_ctx = frame->GetRegisterContext();
if (m_reg_ctx)
{
const RegisterInfo *reg_info = m_reg_ctx->GetRegisterInfoAtIndex(m_reg_num);
if (m_reg_info != reg_info)
{
m_reg_info = reg_info;
if (m_reg_info)
{
if (m_reg_info->name)
m_name.SetCString(m_reg_info->name);
else if (m_reg_info->alt_name)
m_name.SetCString(m_reg_info->alt_name);
}
}
}
}
else
{
m_reg_ctx = NULL;
m_reg_info = NULL;
}
if (m_reg_ctx && m_reg_info)
{
if (m_reg_ctx->ReadRegisterBytes (m_reg_num, m_data))
{
m_value.SetContext(Value::eContextTypeDCRegisterInfo, (void *)m_reg_info);
m_value.SetValueType(Value::eValueTypeHostAddress);
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
SetValueIsValid (true);
return;
}
}
SetValueIsValid (false);
}