Files
clang-p2996/lldb/source/Core/ValueObjectChild.cpp
Greg Clayton 99558cc424 Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions.
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
2015-08-24 23:46:31 +00:00

256 lines
8.3 KiB
C++

//===-- ValueObjectChild.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/ValueObjectChild.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
using namespace lldb_private;
ValueObjectChild::ValueObjectChild
(
ValueObject &parent,
const CompilerType &clang_type,
const ConstString &name,
uint64_t byte_size,
int32_t byte_offset,
uint32_t bitfield_bit_size,
uint32_t bitfield_bit_offset,
bool is_base_class,
bool is_deref_of_parent,
AddressType child_ptr_or_ref_addr_type
) :
ValueObject (parent),
m_clang_type (clang_type),
m_byte_size (byte_size),
m_byte_offset (byte_offset),
m_bitfield_bit_size (bitfield_bit_size),
m_bitfield_bit_offset (bitfield_bit_offset),
m_is_base_class (is_base_class),
m_is_deref_of_parent (is_deref_of_parent),
m_can_update_with_invalid_exe_ctx()
{
m_name = name;
SetAddressTypeOfChildren(child_ptr_or_ref_addr_type);
}
ValueObjectChild::~ValueObjectChild()
{
}
lldb::ValueType
ValueObjectChild::GetValueType() const
{
return m_parent->GetValueType();
}
size_t
ValueObjectChild::CalculateNumChildren()
{
return GetCompilerType().GetNumChildren (true);
}
static void
AdjustForBitfieldness(ConstString& name,
uint8_t bitfield_bit_size)
{
if (name && bitfield_bit_size)
{
const char *clang_type_name = name.AsCString();
if (clang_type_name)
{
std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0);
::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, bitfield_bit_size);
name.SetCString(&bitfield_type_name.front());
}
}
}
ConstString
ValueObjectChild::GetTypeName()
{
if (m_type_name.IsEmpty())
{
m_type_name = GetCompilerType().GetConstTypeName ();
AdjustForBitfieldness(m_type_name, m_bitfield_bit_size);
}
return m_type_name;
}
ConstString
ValueObjectChild::GetQualifiedTypeName()
{
ConstString qualified_name = GetCompilerType().GetConstTypeName();
AdjustForBitfieldness(qualified_name, m_bitfield_bit_size);
return qualified_name;
}
ConstString
ValueObjectChild::GetDisplayTypeName()
{
ConstString display_name = GetCompilerType().GetDisplayTypeName();
AdjustForBitfieldness(display_name, m_bitfield_bit_size);
return display_name;
}
LazyBool
ValueObjectChild::CanUpdateWithInvalidExecutionContext ()
{
if (m_can_update_with_invalid_exe_ctx.hasValue())
return m_can_update_with_invalid_exe_ctx.getValue();
if (m_parent)
{
ValueObject *opinionated_parent = m_parent->FollowParentChain([] (ValueObject* valobj) -> bool {
return (valobj->CanUpdateWithInvalidExecutionContext() == eLazyBoolCalculate);
});
if (opinionated_parent)
return (m_can_update_with_invalid_exe_ctx = opinionated_parent->CanUpdateWithInvalidExecutionContext()).getValue();
}
return (m_can_update_with_invalid_exe_ctx = this->ValueObject::CanUpdateWithInvalidExecutionContext()).getValue();
}
bool
ValueObjectChild::UpdateValue ()
{
m_error.Clear();
SetValueIsValid (false);
ValueObject* parent = m_parent;
if (parent)
{
if (parent->UpdateValueIfNeeded(false))
{
m_value.SetCompilerType(GetCompilerType());
// Copy the parent scalar value and the scalar value type
m_value.GetScalar() = parent->GetValue().GetScalar();
Value::ValueType value_type = parent->GetValue().GetValueType();
m_value.SetValueType (value_type);
if (parent->GetCompilerType().IsPointerOrReferenceType ())
{
lldb::addr_t addr = parent->GetPointerValue ();
m_value.GetScalar() = addr;
if (addr == LLDB_INVALID_ADDRESS)
{
m_error.SetErrorString ("parent address is invalid.");
}
else if (addr == 0)
{
m_error.SetErrorString ("parent is NULL");
}
else
{
m_value.GetScalar() += m_byte_offset;
AddressType addr_type = parent->GetAddressTypeOfChildren();
switch (addr_type)
{
case eAddressTypeFile:
{
lldb::ProcessSP process_sp (GetProcessSP());
if (process_sp && process_sp->IsAlive() == true)
m_value.SetValueType (Value::eValueTypeLoadAddress);
else
m_value.SetValueType(Value::eValueTypeFileAddress);
}
break;
case eAddressTypeLoad:
m_value.SetValueType (Value::eValueTypeLoadAddress);
break;
case eAddressTypeHost:
m_value.SetValueType(Value::eValueTypeHostAddress);
break;
case eAddressTypeInvalid:
// TODO: does this make sense?
m_value.SetValueType(Value::eValueTypeScalar);
break;
}
}
}
else
{
switch (value_type)
{
case Value::eValueTypeLoadAddress:
case Value::eValueTypeFileAddress:
case Value::eValueTypeHostAddress:
{
lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
if (addr == LLDB_INVALID_ADDRESS)
{
m_error.SetErrorString ("parent address is invalid.");
}
else if (addr == 0)
{
m_error.SetErrorString ("parent is NULL");
}
else
{
// Set this object's scalar value to the address of its
// value by adding its byte offset to the parent address
m_value.GetScalar() += GetByteOffset();
}
}
break;
case Value::eValueTypeScalar:
// TODO: What if this is a register value? Do we try and
// extract the child value from within the parent data?
// Probably...
default:
m_error.SetErrorString ("parent has invalid value.");
break;
}
}
if (m_error.Success())
{
const bool thread_and_frame_only_if_stopped = true;
ExecutionContext exe_ctx (GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
if (GetCompilerType().GetTypeInfo() & lldb::eTypeHasValue)
m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
else
m_error.Clear(); // No value so nothing to read...
}
}
else
{
m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString());
}
}
else
{
m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject.");
}
return m_error.Success();
}
bool
ValueObjectChild::IsInScope ()
{
ValueObject* root(GetRoot());
if (root)
return root->IsInScope ();
return false;
}