summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core')
-rw-r--r--lldb/source/Core/DataExtractor.cpp155
-rw-r--r--lldb/source/Core/DataVisualization.cpp10
-rw-r--r--lldb/source/Core/FormatClasses.cpp80
-rw-r--r--lldb/source/Core/FormatManager.cpp39
-rw-r--r--lldb/source/Core/ValueObject.cpp380
-rw-r--r--lldb/source/Core/ValueObjectChild.cpp35
-rw-r--r--lldb/source/Core/ValueObjectConstResult.cpp90
-rw-r--r--lldb/source/Core/ValueObjectConstResultChild.cpp82
-rw-r--r--lldb/source/Core/ValueObjectConstResultImpl.cpp221
-rw-r--r--lldb/source/Core/ValueObjectVariable.cpp25
10 files changed, 804 insertions, 313 deletions
diff --git a/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp
index d869aaef669..2cfced03800 100644
--- a/lldb/source/Core/DataExtractor.cpp
+++ b/lldb/source/Core/DataExtractor.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/MathExtras.h"
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Log.h"
@@ -178,15 +179,6 @@ DataExtractor::Clear ()
}
//------------------------------------------------------------------
-// Returns the total number of bytes that this object refers to
-//------------------------------------------------------------------
-size_t
-DataExtractor::GetByteSize () const
-{
- return m_end - m_start;
-}
-
-//------------------------------------------------------------------
// If this object contains shared data, this function returns the
// offset into that shared data. Else zero is returned.
//------------------------------------------------------------------
@@ -210,16 +202,6 @@ DataExtractor::GetSharedDataOffset () const
}
//------------------------------------------------------------------
-// Returns true if OFFSET is a valid offset into the data in this
-// object.
-//------------------------------------------------------------------
-bool
-DataExtractor::ValidOffset (uint32_t offset) const
-{
- return offset < GetByteSize();
-}
-
-//------------------------------------------------------------------
// Returns true if there are LENGTH bytes availabe starting OFFSET
// into the data that is in this object.
//------------------------------------------------------------------
@@ -245,65 +227,6 @@ DataExtractor::ValidOffsetForDataOfSize (uint32_t offset, uint32_t length) const
return ((offset + length) <= size);
}
-//------------------------------------------------------------------
-// Returns a pointer to the first byte contained in this object's
-// data, or NULL of there is no data in this object.
-//------------------------------------------------------------------
-const uint8_t *
-DataExtractor::GetDataStart () const
-{
- return m_start;
-}
-//------------------------------------------------------------------
-// Returns a pointer to the byte past the last byte contained in
-// this object's data, or NULL of there is no data in this object.
-//------------------------------------------------------------------
-const uint8_t *
-DataExtractor::GetDataEnd () const
-{
- return m_end;
-}
-
-//------------------------------------------------------------------
-// Returns true if this object will endian swap values as it
-// extracts data.
-//------------------------------------------------------------------
-ByteOrder
-DataExtractor::GetByteOrder () const
-{
- return m_byte_order;
-}
-//------------------------------------------------------------------
-// Set whether this object will endian swap values as it extracts
-// data.
-//------------------------------------------------------------------
-void
-DataExtractor::SetByteOrder (ByteOrder endian)
-{
- m_byte_order = endian;
-}
-
-
-//------------------------------------------------------------------
-// Return the size in bytes of any address values this object will
-// extract
-//------------------------------------------------------------------
-uint8_t
-DataExtractor::GetAddressByteSize () const
-{
- return m_addr_size;
-}
-
-//------------------------------------------------------------------
-// Set the size in bytes that will be used when extracting any
-// address values from data contained in this object.
-//------------------------------------------------------------------
-void
-DataExtractor::SetAddressByteSize (uint8_t addr_size)
-{
- m_addr_size = addr_size;
-}
-
//----------------------------------------------------------------------
// Set the data with which this object will extract from to data
// starting at BYTES and set the length of the data to LENGTH bytes
@@ -1901,3 +1824,79 @@ DataExtractor::DumpHexBytes (Stream *s,
base_addr, // Base address
0, 0); // Bitfield info
}
+
+size_t
+DataExtractor::Copy (DataExtractor &dest_data) const
+{
+ if (m_data_sp.get())
+ {
+ // we can pass along the SP to the data
+ dest_data.SetData(m_data_sp);
+ }
+ else
+ {
+ const uint8_t *base_ptr = m_start;
+ size_t data_size = GetByteSize();
+ dest_data.SetData(DataBufferSP(new DataBufferHeap(base_ptr, data_size)));
+ }
+ return GetByteSize();
+}
+
+bool
+DataExtractor::Append(DataExtractor& rhs)
+{
+ if (rhs.GetByteOrder() != GetByteOrder())
+ return false;
+
+ if (rhs.GetByteSize() == 0)
+ return true;
+
+ if (GetByteSize() == 0)
+ return (rhs.Copy(*this) > 0);
+
+ size_t bytes = GetByteSize() + rhs.GetByteSize();
+
+ DataBufferHeap *buffer_heap_ptr = NULL;
+ DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
+
+ if (buffer_sp.get() == NULL || buffer_heap_ptr == NULL)
+ return false;
+
+ uint8_t* bytes_ptr = buffer_heap_ptr->GetBytes();
+
+ memcpy(bytes_ptr, GetDataStart(), GetByteSize());
+ memcpy(bytes_ptr + GetByteSize(), rhs.GetDataStart(), rhs.GetByteSize());
+
+ SetData(buffer_sp);
+
+ return true;
+}
+
+bool
+DataExtractor::Append(void* buf, uint32_t length)
+{
+ if (buf == NULL)
+ return false;
+
+ if (length == 0)
+ return true;
+
+ size_t bytes = GetByteSize() + length;
+
+ DataBufferHeap *buffer_heap_ptr = NULL;
+ DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
+
+ if (buffer_sp.get() == NULL || buffer_heap_ptr == NULL)
+ return false;
+
+ uint8_t* bytes_ptr = buffer_heap_ptr->GetBytes();
+
+ if (GetByteSize() > 0)
+ memcpy(bytes_ptr, GetDataStart(), GetByteSize());
+
+ memcpy(bytes_ptr + GetByteSize(), buf, length);
+
+ SetData(buffer_sp);
+
+ return true;
+} \ No newline at end of file
diff --git a/lldb/source/Core/DataVisualization.cpp b/lldb/source/Core/DataVisualization.cpp
index 6974132617a..7c326ed6ec0 100644
--- a/lldb/source/Core/DataVisualization.cpp
+++ b/lldb/source/Core/DataVisualization.cpp
@@ -106,14 +106,14 @@ DataVisualization::AnyMatches (ConstString type_name,
bool
DataVisualization::Categories::Get (const ConstString &category, lldb::FormatCategorySP &entry)
{
- entry = GetFormatManager().Category(category);
+ entry = GetFormatManager().GetCategory(category);
return true;
}
void
DataVisualization::Categories::Add (const ConstString &category)
{
- GetFormatManager().Category(category);
+ GetFormatManager().GetCategory(category);
}
bool
@@ -132,13 +132,13 @@ DataVisualization::Categories::Clear ()
void
DataVisualization::Categories::Clear (ConstString &category)
{
- GetFormatManager().Category(category)->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
+ GetFormatManager().GetCategory(category)->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
}
void
DataVisualization::Categories::Enable (ConstString& category)
{
- if (GetFormatManager().Category(category)->IsEnabled() == false)
+ if (GetFormatManager().GetCategory(category)->IsEnabled() == false)
GetFormatManager().EnableCategory(category);
else
{
@@ -150,7 +150,7 @@ DataVisualization::Categories::Enable (ConstString& category)
void
DataVisualization::Categories::Disable (ConstString& category)
{
- if (GetFormatManager().Category(category)->IsEnabled() == true)
+ if (GetFormatManager().GetCategory(category)->IsEnabled() == true)
GetFormatManager().DisableCategory(category);
}
diff --git a/lldb/source/Core/FormatClasses.cpp b/lldb/source/Core/FormatClasses.cpp
index a23225d3825..ee689307ac1 100644
--- a/lldb/source/Core/FormatClasses.cpp
+++ b/lldb/source/Core/FormatClasses.cpp
@@ -41,30 +41,6 @@ ValueFormat::ValueFormat (lldb::Format f,
{
}
-std::string
-ValueFormat::FormatObject(lldb::ValueObjectSP object)
-{
- if (!object.get())
- return "NULL";
-
- StreamString sstr;
-
- if (ClangASTType::DumpTypeValue (object->GetClangAST(), // The clang AST
- object->GetClangType(), // The clang type to display
- &sstr,
- m_format, // Format to display this type with
- object->GetDataExtractor(), // Data to extract from
- 0, // Byte offset into "data"
- object->GetByteSize(), // Byte size of item in "data"
- object->GetBitfieldBitSize(), // Bitfield bit size
- object->GetBitfieldBitOffset())) // Bitfield bit offset
- return (sstr.GetString());
- else
- {
- return ("unsufficient data for value");
- }
-}
-
SummaryFormat::SummaryFormat(bool casc,
bool skipptr,
bool skipref,
@@ -186,29 +162,8 @@ ScriptSummaryFormat::ScriptSummaryFormat(bool casc,
std::string
ScriptSummaryFormat::FormatObject(lldb::ValueObjectSP object)
{
- lldb::ValueObjectSP target_object;
- if (object->GetIsExpressionResult() &&
- ClangASTContext::IsPointerType(object->GetClangType()) &&
- object->GetValue().GetValueType() == Value::eValueTypeHostAddress)
- {
- // when using the expression parser, an additional layer of "frozen data"
- // can be created, which is basically a byte-exact copy of the data returned
- // by the expression, but in host memory. because Python code might need to read
- // into the object memory in non-obvious ways, we need to hand it the target version
- // of the expression output
- lldb::addr_t tgt_address = object->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- target_object = ValueObjectConstResult::Create (object->GetExecutionContextScope(),
- object->GetClangAST(),
- object->GetClangType(),
- object->GetName(),
- tgt_address,
- eAddressTypeLoad,
- object->GetUpdatePoint().GetProcessSP()->GetAddressByteSize());
- }
- else
- target_object = object;
return std::string(ScriptInterpreterPython::CallPythonScriptFunction(m_function_name.c_str(),
- target_object).c_str());
+ object).c_str());
}
std::string
@@ -282,25 +237,6 @@ SyntheticScriptProvider::FrontEnd::FrontEnd(std::string pclass,
return;
}
- if (be->GetIsExpressionResult() &&
- ClangASTContext::IsPointerType(be->GetClangType()) &&
- be->GetValue().GetValueType() == Value::eValueTypeHostAddress)
- {
- // when using the expression parser, an additional layer of "frozen data"
- // can be created, which is basically a byte-exact copy of the data returned
- // by the expression, but in host memory. because Python code might need to read
- // into the object memory in non-obvious ways, we need to hand it the target version
- // of the expression output
- lldb::addr_t tgt_address = be->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- m_backend = ValueObjectConstResult::Create (be->GetExecutionContextScope(),
- be->GetClangAST(),
- be->GetClangType(),
- be->GetName(),
- tgt_address,
- eAddressTypeLoad,
- be->GetUpdatePoint().GetProcessSP()->GetAddressByteSize());
- }
-
m_interpreter = m_backend->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
if (m_interpreter == NULL)
@@ -315,19 +251,7 @@ SyntheticScriptProvider::FrontEnd::GetChildAtIndex (uint32_t idx, bool can_creat
if (m_wrapper == NULL || m_interpreter == NULL)
return lldb::ValueObjectSP();
- PyObject* py_return = (PyObject*)m_interpreter->GetChildAtIndex(m_wrapper, idx);
- if (py_return == NULL || py_return == Py_None)
- {
- Py_XDECREF(py_return);
- return lldb::ValueObjectSP();
- }
-
- lldb::SBValue *sb_ptr = m_interpreter->CastPyObjectToSBValue(py_return);
-
- if (py_return == NULL || sb_ptr == NULL)
- return lldb::ValueObjectSP();
-
- return sb_ptr->m_opaque_sp;
+ return m_interpreter->GetChildAtIndex(m_wrapper, idx);
}
std::string
diff --git a/lldb/source/Core/FormatManager.cpp b/lldb/source/Core/FormatManager.cpp
index 40d3a81da39..f9bb3e1a6e9 100644
--- a/lldb/source/Core/FormatManager.cpp
+++ b/lldb/source/Core/FormatManager.cpp
@@ -482,11 +482,11 @@ CategoryMap::LoopThrough(CallbackType callback, void* param)
}
lldb::FormatCategorySP
-FormatManager::Category (const ConstString& category_name,
+FormatManager::GetCategory (const ConstString& category_name,
bool can_create)
{
if (!category_name)
- return Category(m_default_category_name);
+ return GetCategory(m_default_category_name);
lldb::FormatCategorySP category;
if (m_categories_map.Get(category_name, category))
return category;
@@ -495,7 +495,7 @@ FormatManager::Category (const ConstString& category_name,
return lldb::FormatCategorySP();
m_categories_map.Add(category_name,lldb::FormatCategorySP(new FormatCategory(this, category_name.AsCString())));
- return Category(category_name);
+ return GetCategory(category_name);
}
lldb::Format
@@ -566,11 +566,13 @@ FormatManager::FormatManager() :
lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
- Category(m_system_category_name)->GetSummaryNavigator()->Add(ConstString("char *"), string_format);
- Category(m_system_category_name)->GetSummaryNavigator()->Add(ConstString("const char *"), string_format);
- Category(m_system_category_name)->GetRegexSummaryNavigator()->Add(any_size_char_arr, string_array_format);
+ FormatCategory::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
- Category(m_default_category_name); // this call is there to force LLDB into creating an empty "default" category
+ sys_category_sp->GetSummaryNavigator()->Add(ConstString("char *"), string_format);
+ sys_category_sp->GetSummaryNavigator()->Add(ConstString("const char *"), string_format);
+ sys_category_sp->GetRegexSummaryNavigator()->Add(any_size_char_arr, string_array_format);
+
+ GetCategory(m_default_category_name); // this call is there to force LLDB into creating an empty "default" category
// WARNING: temporary code!!
// The platform should be responsible for initializing its own formatters
@@ -586,24 +588,27 @@ FormatManager::FormatManager() :
true,
false,
"${var._M_dataplus._M_p}"));
- Category(m_gnu_cpp_category_name)->GetSummaryNavigator()->Add(ConstString("std::string"),
- std_string_summary_sp);
- Category(m_gnu_cpp_category_name)->GetSummaryNavigator()->Add(ConstString("std::basic_string<char>"),
- std_string_summary_sp);
- Category(m_gnu_cpp_category_name)->GetSummaryNavigator()->Add(ConstString("std::basic_string<char,std::char_traits<char>,std::allocator<char> >"),
- std_string_summary_sp);
-
- Category(m_gnu_cpp_category_name)->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("std::vector<")),
+
+ FormatCategory::SharedPointer gnu_category_sp = GetCategory(m_gnu_cpp_category_name);
+
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::string"),
+ std_string_summary_sp);
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<char>"),
+ std_string_summary_sp);
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<char,std::char_traits<char>,std::allocator<char> >"),
+ std_string_summary_sp);
+
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?vector<.+>$")),
SyntheticChildrenSP(new SyntheticScriptProvider(true,
false,
false,
"gnu_libstdcpp.StdVectorSynthProvider")));
- Category(m_gnu_cpp_category_name)->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("std::map<")),
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?map<.+> >$")),
SyntheticChildrenSP(new SyntheticScriptProvider(true,
false,
false,
"gnu_libstdcpp.StdMapSynthProvider")));
- Category(m_gnu_cpp_category_name)->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("std::list<")),
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?list<.+>$")),
SyntheticChildrenSP(new SyntheticScriptProvider(true,
false,
false,
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 2ab5ac4cbcf..78e18ac9f3d 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -89,14 +89,13 @@ ValueObject::ValueObject (ValueObject &parent) :
m_value_did_change (false),
m_children_count_valid (false),
m_old_value_valid (false),
- m_pointers_point_to_load_addrs (false),
m_is_deref_of_parent (false),
m_is_array_item_for_pointer(false),
m_is_bitfield_for_scalar(false),
m_is_expression_path_child(false),
m_is_child_at_offset(false),
- m_is_expression_result(parent.m_is_expression_result),
- m_dump_printable_counter(0)
+ m_dump_printable_counter(0),
+ m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid)
{
m_manager->ManageObject(this);
}
@@ -104,7 +103,8 @@ ValueObject::ValueObject (ValueObject &parent) :
//----------------------------------------------------------------------
// ValueObject constructor
//----------------------------------------------------------------------
-ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
+ValueObject::ValueObject (ExecutionContextScope *exe_scope,
+ AddressType child_ptr_or_ref_addr_type) :
UserID (++g_value_obj_uid), // Unique identifier for every value object
m_parent (NULL),
m_update_point (exe_scope),
@@ -135,14 +135,13 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
m_value_did_change (false),
m_children_count_valid (false),
m_old_value_valid (false),
- m_pointers_point_to_load_addrs (false),
m_is_deref_of_parent (false),
m_is_array_item_for_pointer(false),
m_is_bitfield_for_scalar(false),
m_is_expression_path_child(false),
m_is_child_at_offset(false),
- m_is_expression_result(false),
- m_dump_printable_counter(0)
+ m_dump_printable_counter(0),
+ m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type)
{
m_manager = new ValueObjectManager();
m_manager->ManageObject (this);
@@ -165,13 +164,24 @@ bool
ValueObject::UpdateValueIfNeeded (DynamicValueType use_dynamic, bool update_format)
{
+ bool did_change_formats = false;
+
if (update_format)
- UpdateFormatsIfNeeded(use_dynamic);
+ did_change_formats = UpdateFormatsIfNeeded(use_dynamic);
// If this is a constant value, then our success is predicated on whether
// we have an error or not
if (GetIsConstant())
+ {
+ // if you were asked to update your formatters, but did not get a chance to do it
+ // clear your own values (this serves the purpose of faking a stop-id for frozen
+ // objects (which are regarded as constant, but could have changes behind their backs
+ // because of the frozen-pointer depth limit)
+ // TODO: decouple summary from value and then remove this code and only force-clear the summary
+ if (update_format && !did_change_formats)
+ m_summary_str.clear();
return m_error.Success();
+ }
bool first_update = m_update_point.IsFirstEvaluation();
@@ -216,7 +226,7 @@ ValueObject::UpdateValueIfNeeded (DynamicValueType use_dynamic, bool update_form
return m_error.Success();
}
-void
+bool
ValueObject::UpdateFormatsIfNeeded(DynamicValueType use_dynamic)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
@@ -225,10 +235,14 @@ ValueObject::UpdateFormatsIfNeeded(DynamicValueType use_dynamic)
GetName().GetCString(),
m_last_format_mgr_revision,
DataVisualization::GetCurrentRevision());
+
+ bool any_change = false;
+
if (HasCustomSummaryFormat() && m_update_point.GetModID() != m_user_id_of_forced_summary)
{
ClearCustomSummaryFormat();
m_summary_str.clear();
+ any_change = true;
}
if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision()) ||
m_last_format_mgr_dynamic != use_dynamic)
@@ -242,6 +256,7 @@ ValueObject::UpdateFormatsIfNeeded(DynamicValueType use_dynamic)
m_synthetic_value = NULL;
+ any_change = true;
DataVisualization::ValueFormats::Get(*this, eNoDynamicValues, m_last_value_format);
DataVisualization::GetSummaryFormat(*this, use_dynamic, m_last_summary_format);
DataVisualization::GetSyntheticChildren(*this, use_dynamic, m_last_synthetic_filter);
@@ -251,6 +266,9 @@ ValueObject::UpdateFormatsIfNeeded(DynamicValueType use_dynamic)
ClearUserVisibleData();
}
+
+ return any_change;
+
}
void
@@ -538,10 +556,11 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3
child_bitfield_bit_size,
child_bitfield_bit_offset,
child_is_base_class,
- child_is_deref_of_parent);
- if (m_pointers_point_to_load_addrs)
- valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
- }
+ child_is_deref_of_parent,
+ eAddressTypeInvalid);
+ //if (valobj)
+ // valobj->SetAddressTypeOfChildren(eAddressTypeInvalid);
+ }
return valobj;
}
@@ -578,8 +597,7 @@ ValueObject::GetSummaryAsCString ()
if (ClangASTContext::IsFunctionPointerType (clang_type))
{
AddressType func_ptr_address_type = eAddressTypeInvalid;
- addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
-
+ addr_t func_ptr_address = GetPointerValue (&func_ptr_address_type);
if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
{
switch (func_ptr_address_type)
@@ -643,10 +661,157 @@ ValueObject::IsCStringContainer(bool check_pointer)
return true;
addr_t cstr_address = LLDB_INVALID_ADDRESS;
AddressType cstr_address_type = eAddressTypeInvalid;
- cstr_address = GetAddressOf (cstr_address_type, true);
+ cstr_address = GetAddressOf (true, &cstr_address_type);
return (cstr_address != LLDB_INVALID_ADDRESS);
}
+size_t
+ValueObject::GetPointeeData (DataExtractor& data,
+ uint32_t item_idx,
+ uint32_t item_count)
+{
+ if (!IsPointerType() && !IsArrayType())
+ return 0;
+
+ if (item_count == 0)
+ return 0;
+
+ uint32_t stride = 0;
+
+ ClangASTType type(GetClangAST(),
+ GetClangType());
+
+ const uint64_t item_type_size = (IsPointerType() ? ClangASTType::GetTypeByteSize(GetClangAST(), type.GetPointeeType()) :
+ ClangASTType::GetTypeByteSize(GetClangAST(), type.GetArrayElementType(stride)));
+
+ const uint64_t bytes = item_count * item_type_size;
+
+ const uint64_t offset = item_idx * item_type_size;
+
+ if (item_idx == 0 && item_count == 1) // simply a deref
+ {
+ if (IsPointerType())
+ {
+ Error error;
+ ValueObjectSP pointee_sp = Dereference(error);
+ if (error.Fail() || pointee_sp.get() == NULL)
+ return 0;
+ return pointee_sp->GetDataExtractor().Copy(data);
+ }
+ else
+ {
+ ValueObjectSP child_sp = GetChildAtIndex(0, true);
+ if (child_sp.get() == NULL)
+ return 0;
+ return child_sp->GetDataExtractor().Copy(data);
+ }
+ return true;
+ }
+ else /* (items > 1) */
+ {
+ Error error;
+ lldb_private::DataBufferHeap* heap_buf_ptr = NULL;
+ lldb::DataBufferSP data_sp(heap_buf_ptr = new lldb_private::DataBufferHeap());
+
+ AddressType addr_type;
+ lldb::addr_t addr = IsPointerType() ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type);
+
+ ExecutionContextScope *exe_scope = m_update_point.GetExecutionContextScope();
+
+
+ switch (addr_type)
+ {
+ case eAddressTypeFile:
+ {
+ Module* module = GetModule();
+ if (module)
+ {
+ Address so_addr;
+ module->ResolveFileAddress(addr, so_addr);
+ if (exe_scope)
+ {
+ Target* target = exe_scope->CalculateTarget();
+ if (target)
+ {
+ heap_buf_ptr->SetByteSize(bytes);
+ size_t bytes_read = target->ReadMemory(so_addr, false, heap_buf_ptr->GetBytes(), bytes, error);
+ if (error.Success())
+ {
+ data.SetData(data_sp);
+ return bytes_read;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case eAddressTypeLoad:
+ if (exe_scope)
+ {
+ Process *process = exe_scope->CalculateProcess();
+ if (process)
+ {
+ heap_buf_ptr->SetByteSize(bytes);
+ size_t bytes_read = process->ReadMemory(addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
+ if (error.Success())
+ {
+ data.SetData(data_sp);
+ return bytes_read;
+ }
+ }
+ }
+ break;
+ case eAddressTypeHost:
+ {
+ heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes);
+ data.SetData(data_sp);
+ return bytes;
+ }
+ break;
+ case eAddressTypeInvalid:
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+size_t
+ValueObject::GetData (DataExtractor& data)
+{
+ UpdateValueIfNeeded(false);
+ ExecutionContext exe_ctx;
+ GetExecutionContextScope()->CalculateExecutionContext(exe_ctx);
+ Error error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), data, 0, GetModule());
+ if (error.Fail())
+ return 0;
+ data.SetAddressByteSize(m_data.GetAddressByteSize());
+ data.SetByteOrder(m_data.GetByteOrder());
+ return data.GetByteSize();
+}
+
+// will compute strlen(str), but without consuming more than
+// maxlen bytes out of str (this serves the purpose of reading
+// chunks of a string without having to worry about
+// missing NULL terminators in the chunk)
+// of course, if strlen(str) > maxlen, the function will return
+// maxlen_value (which should be != maxlen, because that allows you
+// to know whether strlen(str) == maxlen or strlen(str) > maxlen)
+static uint32_t
+strlen_or_inf (const char* str,
+ uint32_t maxlen,
+ uint32_t maxlen_value)
+{
+ uint32_t len = 0;
+ while(*str)
+ {
+ len++;str++;
+ if (len > maxlen)
+ return maxlen_value;
+ }
+ return len;
+}
+
void
ValueObject::ReadPointedString(Stream& s,
Error& error,
@@ -656,7 +821,7 @@ ValueObject::ReadPointedString(Stream& s,
{
if (max_length == 0)
- max_length = 128; // FIXME this should be a setting, or a formatting parameter
+ max_length = GetUpdatePoint().GetTargetSP()->GetMaximumSizeOfStringSummary();
clang_type_t clang_type = GetClangType();
clang_type_t elem_or_pointee_clang_type;
@@ -690,14 +855,14 @@ ValueObject::ReadPointedString(Stream& s,
capped_data = true;
cstr_len = max_length;
}
- cstr_address = GetAddressOf (cstr_address_type, true);
+ cstr_address = GetAddressOf (true, &cstr_address_type);
}
else
{
// We have a pointer
- cstr_address = GetPointerValue (cstr_address_type, true);
+ cstr_address = GetPointerValue (&cstr_address_type);
}
- if (cstr_address == LLDB_INVALID_ADDRESS)
+ if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS)
{
s << "<invalid address for data>";
}
@@ -706,18 +871,13 @@ ValueObject::ReadPointedString(Stream& s,
Address cstr_so_addr (NULL, cstr_address);
DataExtractor data;
size_t bytes_read = 0;
- std::vector<char> data_buffer;
- bool prefer_file_cache = false;
if (cstr_len > 0 && honor_array)
{
- data_buffer.resize(cstr_len);
- data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
- bytes_read = target->ReadMemory (cstr_so_addr,
- prefer_file_cache,
- &data_buffer.front(),
- cstr_len,
- error);
- if (bytes_read > 0)
+ // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
+ // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
+ GetPointeeData(data, 0, cstr_len);
+
+ if ( (bytes_read = data.GetByteSize()) > 0)
{
s << '"';
data.Dump (&s,
@@ -740,29 +900,31 @@ ValueObject::ReadPointedString(Stream& s,
{
cstr_len = max_length;
const size_t k_max_buf_size = 64;
- data_buffer.resize (k_max_buf_size + 1);
- // NULL terminate in case we don't get the entire C string
- data_buffer.back() = '\0';
-
- s << '"';
+
+ size_t offset = 0;
bool any_data = false;
-
- data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
- while ((bytes_read = target->ReadMemory (cstr_so_addr,
- prefer_file_cache,
- &data_buffer.front(),
- k_max_buf_size,
- error)) > 0)
+ bool finished = false;
+ // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
+ // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
+ while ( (bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0 )
{
- any_data = true;
- size_t len = strlen(&data_buffer.front());
+ size_t len = strlen_or_inf(data.PeekCStr(0), k_max_buf_size, k_max_buf_size+1);
+ if (len > k_max_buf_size)
+ len = k_max_buf_size;
+ if (!any_data)
+ {
+ s << '"';
+ any_data = true;
+ }
if (len == 0)
break;
if (len > bytes_read)
len = bytes_read;
if (len > cstr_len)
len = cstr_len;
+ else
+ finished = true;
data.Dump (&s,
0, // Start offset in "data"
@@ -776,19 +938,22 @@ ValueObject::ReadPointedString(Stream& s,
if (len < k_max_buf_size)
break;
+
if (len >= cstr_len)
- {
- s << "...";
break;
- }
+
cstr_len -= len;
- cstr_so_addr.Slide (k_max_buf_size);
+ offset += len;
}
if (any_data == false)
s << "<data not available>";
-
- s << '"';
+ else
+ {
+ s << '"';
+ if (finished == false)
+ s << "...";
+ }
}
}
}
@@ -868,39 +1033,40 @@ ValueObject::GetValueAsCString ()
case Value::eContextTypeLLDBType:
case Value::eContextTypeVariable:
{
+ lldb::Format my_format = GetFormat();
clang_type_t clang_type = GetClangType ();
if (clang_type)
{
- if (m_format == lldb::eFormatDefault && m_last_value_format)
- {
- m_value_str = m_last_value_format->FormatObject(GetSP());
- }
- else
+ if (m_format == lldb::eFormatDefault)
{
- StreamString sstr;
- Format format = GetFormat();
- if (format == eFormatDefault)
- format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
- ClangASTType::GetFormat(clang_type));
-
- if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
- clang_type, // The clang type to display
- &sstr,
- format, // Format to display this type with
- m_data, // Data to extract from
- 0, // Byte offset into "m_data"
- GetByteSize(), // Byte size of item in "m_data"
- GetBitfieldBitSize(), // Bitfield bit size
- GetBitfieldBitOffset())) // Bitfield bit offset
- m_value_str.swap(sstr.GetString());
+ if (m_last_value_format)
+ my_format = m_last_value_format->GetFormat();
else
{
- m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
- m_data.GetByteSize(),
- GetByteSize());
- m_value_str.clear();
+ if (m_is_bitfield_for_scalar)
+ my_format = eFormatUnsigned;
+ else
+ my_format = ClangASTType::GetFormat(clang_type);
}
}
+ StreamString sstr;
+ if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
+ clang_type, // The clang type to display
+ &sstr,
+ my_format, // Format to display this type with
+ m_data, // Data to extract from
+ 0, // Byte offset into "m_data"
+ GetByteSize(), // Byte size of item in "m_data"
+ GetBitfieldBitSize(), // Bitfield bit size
+ GetBitfieldBitOffset())) // Bitfield bit offset
+ m_value_str.swap(sstr.GetString());
+ else
+ {
+ m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
+ m_data.GetByteSize(),
+ GetByteSize());
+ m_value_str.clear();
+ }
}
}
break;
@@ -1218,7 +1384,7 @@ ValueObject::DumpPrintableRepresentation(Stream& s,
}
addr_t
-ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
+ValueObject::GetAddressOf (bool scalar_is_load_address, AddressType *address_type)
{
if (!UpdateValueIfNeeded(false))
return LLDB_INVALID_ADDRESS;
@@ -1228,7 +1394,8 @@ ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_addres
case Value::eValueTypeScalar:
if (scalar_is_load_address)
{
- address_type = eAddressTypeLoad;
+ if(address_type)
+ *address_type = eAddressTypeLoad;
return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
}
break;
@@ -1237,20 +1404,23 @@ ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_addres
case Value::eValueTypeFileAddress:
case Value::eValueTypeHostAddress:
{
- address_type = m_value.GetValueAddressType ();
+ if(address_type)
+ *address_type = m_value.GetValueAddressType ();
return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
}
break;
}
- address_type = eAddressTypeInvalid;
+ if (address_type)
+ *address_type = eAddressTypeInvalid;
return LLDB_INVALID_ADDRESS;
}
addr_t
-ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address)
+ValueObject::GetPointerValue (AddressType *address_type)
{
addr_t address = LLDB_INVALID_ADDRESS;
- address_type = eAddressTypeInvalid;
+ if(address_type)
+ *address_type = eAddressTypeInvalid;
if (!UpdateValueIfNeeded(false))
return address;
@@ -1258,28 +1428,21 @@ ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_add
switch (m_value.GetValueType())
{
case Value::eValueTypeScalar:
- if (scalar_is_load_address)
- {
- address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- address_type = eAddressTypeLoad;
- }
+ address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
break;
+ case Value::eValueTypeHostAddress:
case Value::eValueTypeLoadAddress:
case Value::eValueTypeFileAddress:
- case Value::eValueTypeHostAddress:
{
uint32_t data_offset = 0;
address = m_data.GetPointer(&data_offset);
- address_type = m_value.GetValueAddressType();
- if (address_type == eAddressTypeInvalid)
- address_type = eAddressTypeLoad;
}
break;
}
- if (m_pointers_point_to_load_addrs)
- address_type = eAddressTypeLoad;
+ if (address_type)
+ *address_type = GetAddressTypeOfChildren();
return address;
}
@@ -1553,7 +1716,8 @@ ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_cre
to-from+1,
from,
false,
- false);
+ false,
+ eAddressTypeInvalid);
// Cache the value if we got one back...
if (synthetic_child)
@@ -1633,7 +1797,8 @@ ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type
0,
0,
false,
- false);
+ false,
+ eAddressTypeInvalid);
if (synthetic_child)
{
AddSyntheticChild(name_const_str, synthetic_child);
@@ -2950,7 +3115,7 @@ ValueObject::DumpValueObject
// We have a pointer or reference whose value is an address.
// Make sure that address is not NULL
AddressType ptr_address_type;
- if (valobj->GetPointerValue (ptr_address_type, true) == 0)
+ if (valobj->GetPointerValue (&ptr_address_type) == 0)
print_children = false;
else if (is_ref && curr_depth == 0)
@@ -3084,7 +3249,8 @@ ValueObject::CreateConstantValue (const ConstString &name)
ast,
GetClangType(),
name,
- data);
+ data,
+ GetAddressOf());
}
}
@@ -3152,7 +3318,8 @@ ValueObject::Dereference (Error &error)
child_bitfield_bit_size,
child_bitfield_bit_offset,
child_is_base_class,
- child_is_deref_of_parent);
+ child_is_deref_of_parent,
+ eAddressTypeInvalid);
}
}
@@ -3182,7 +3349,7 @@ ValueObject::AddressOf (Error &error)
AddressType address_type = eAddressTypeInvalid;
const bool scalar_is_load_address = false;
- addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
+ addr_t addr = GetAddressOf (scalar_is_load_address, &address_type);
error.Clear();
if (addr != LLDB_INVALID_ADDRESS)
{
@@ -3228,8 +3395,7 @@ ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
{
ValueObjectSP valobj_sp;
AddressType address_type;
- const bool scalar_is_load_address = true;
- addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
+ addr_t ptr_value = GetPointerValue (&address_type);
if (ptr_value != LLDB_INVALID_ADDRESS)
{
@@ -3248,8 +3414,7 @@ ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
{
ValueObjectSP valobj_sp;
AddressType address_type;
- const bool scalar_is_load_address = true;
- addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address);
+ addr_t ptr_value = GetPointerValue (&address_type);
if (ptr_value != LLDB_INVALID_ADDRESS)
{
@@ -3540,3 +3705,14 @@ ValueObject::ClearUserVisibleData()
m_summary_str.clear();
m_object_desc_str.clear();
}
+
+SymbolContextScope *
+ValueObject::GetSymbolContextScope()
+{
+ if (m_parent)
+ {
+ if (!m_parent->IsPointerOrReferenceType())
+ return m_parent->GetSymbolContextScope();
+ }
+ return NULL;
+}
diff --git a/lldb/source/Core/ValueObjectChild.cpp b/lldb/source/Core/ValueObjectChild.cpp
index 4075f60ebb3..b07b38c7544 100644
--- a/lldb/source/Core/ValueObjectChild.cpp
+++ b/lldb/source/Core/ValueObjectChild.cpp
@@ -35,7 +35,8 @@ ValueObjectChild::ValueObjectChild
uint32_t bitfield_bit_size,
uint32_t bitfield_bit_offset,
bool is_base_class,
- bool is_deref_of_parent
+ bool is_deref_of_parent,
+ AddressType child_ptr_or_ref_addr_type
) :
ValueObject (parent),
m_clang_ast (clang_ast),
@@ -48,6 +49,7 @@ ValueObjectChild::ValueObjectChild
m_is_deref_of_parent (is_deref_of_parent)
{
m_name = name;
+ SetAddressTypeOfChildren(child_ptr_or_ref_addr_type);
}
ValueObjectChild::~ValueObjectChild()
@@ -108,10 +110,7 @@ ValueObjectChild::UpdateValue ()
if (ClangASTContext::IsPointerOrReferenceType (parent->GetClangType()))
{
- const bool scalar_is_load_address = true;
- AddressType address_type;
-
- lldb::addr_t addr = parent->GetPointerValue (address_type, scalar_is_load_address);
+ lldb::addr_t addr = parent->GetPointerValue ();
m_value.GetScalar() = addr;
if (addr == LLDB_INVALID_ADDRESS)
@@ -125,10 +124,28 @@ ValueObjectChild::UpdateValue ()
else
{
m_value.GetScalar() += m_byte_offset;
- if (m_pointers_point_to_load_addrs ||
- value_type == Value::eValueTypeScalar ||
- value_type == Value::eValueTypeFileAddress)
- m_value.SetValueType (Value::eValueTypeLoadAddress);
+ AddressType addr_type = parent->GetAddressTypeOfChildren();
+
+ switch (addr_type)
+ {
+ case eAddressTypeFile:
+ if (m_update_point.GetProcessSP().get() != NULL && m_update_point.GetProcessSP()->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:
+ default:
+ // TODO: does this make sense?
+ m_value.SetValueType(Value::eValueTypeScalar);
+ break;
+ }
}
}
else
diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp
index 7ceddc99607..9a23ca82a1b 100644
--- a/lldb/source/Core/ValueObjectConstResult.cpp
+++ b/lldb/source/Core/ValueObjectConstResult.cpp
@@ -9,6 +9,8 @@
#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Core/ValueObjectConstResultChild.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ValueObjectList.h"
@@ -31,30 +33,34 @@ ValueObjectConstResult::Create
(
ExecutionContextScope *exe_scope,
ByteOrder byte_order,
- uint32_t addr_byte_size
+ uint32_t addr_byte_size,
+ lldb::addr_t address
)
{
return (new ValueObjectConstResult (exe_scope,
byte_order,
- addr_byte_size))->GetSP();
+ addr_byte_size,
+ address))->GetSP();
}
ValueObjectConstResult::ValueObjectConstResult
(
ExecutionContextScope *exe_scope,
ByteOrder byte_order,
- uint32_t addr_byte_size
+ uint32_t addr_byte_size,
+ lldb::addr_t address
) :
ValueObject (exe_scope),
m_clang_ast (NULL),
m_type_name (),
- m_byte_size (0)
+ m_byte_size (0),
+ m_impl(this, address)
{
SetIsConstant ();
SetValueIsValid(true);
m_data.SetByteOrder(byte_order);
m_data.SetAddressByteSize(addr_byte_size);
- m_pointers_point_to_load_addrs = true;
+ SetAddressTypeOfChildren(eAddressTypeLoad);
}
ValueObjectSP
@@ -64,14 +70,16 @@ ValueObjectConstResult::Create
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
- const DataExtractor &data
+ const DataExtractor &data,
+ lldb::addr_t address
)
{
return (new ValueObjectConstResult (exe_scope,
clang_ast,
clang_type,
name,
- data))->GetSP();
+ data,
+ address))->GetSP();
}
ValueObjectConstResult::ValueObjectConstResult
@@ -80,12 +88,14 @@ ValueObjectConstResult::ValueObjectConstResult
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
- const DataExtractor &data
+ const DataExtractor &data,
+ lldb::addr_t address
) :
ValueObject (exe_scope),
m_clang_ast (clang_ast),
m_type_name (),
- m_byte_size (0)
+ m_byte_size (0),
+ m_impl(this, address)
{
m_data = data;
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
@@ -94,7 +104,7 @@ ValueObjectConstResult::ValueObjectConstResult
m_name = name;
SetIsConstant ();
SetValueIsValid(true);
- m_pointers_point_to_load_addrs = true;
+ SetAddressTypeOfChildren(eAddressTypeLoad);
}
ValueObjectSP
@@ -106,7 +116,8 @@ ValueObjectConstResult::Create
const ConstString &name,
const lldb::DataBufferSP &data_sp,
lldb::ByteOrder data_byte_order,
- uint8_t data_addr_size
+ uint8_t data_addr_size,
+ lldb::addr_t address
)
{
return (new ValueObjectConstResult (exe_scope,
@@ -115,7 +126,8 @@ ValueObjectConstResult::Create
name,
data_sp,
data_byte_order,
- data_addr_size))->GetSP();
+ data_addr_size,
+ address))->GetSP();
}
ValueObjectConstResult::ValueObjectConstResult
@@ -126,12 +138,14 @@ ValueObjectConstResult::ValueObjectConstResult
const ConstString &name,
const lldb::DataBufferSP &data_sp,
lldb::ByteOrder data_byte_order,
- uint8_t data_addr_size
+ uint8_t data_addr_size,
+ lldb::addr_t address
) :
ValueObject (exe_scope),
m_clang_ast (clang_ast),
m_type_name (),
- m_byte_size (0)
+ m_byte_size (0),
+ m_impl(this, address)
{
m_data.SetByteOrder(data_byte_order);
m_data.SetAddressByteSize(data_addr_size);
@@ -142,7 +156,7 @@ ValueObjectConstResult::ValueObjectConstResult
m_name = name;
SetIsConstant ();
SetValueIsValid(true);
- m_pointers_point_to_load_addrs = true;
+ SetAddressTypeOfChildren(eAddressTypeLoad);
}
ValueObjectSP
@@ -179,7 +193,8 @@ ValueObjectConstResult::ValueObjectConstResult
ValueObject (exe_scope),
m_clang_ast (clang_ast),
m_type_name (),
- m_byte_size (0)
+ m_byte_size (0),
+ m_impl(this, address)
{
m_value.GetScalar() = address;
m_data.SetAddressByteSize(addr_byte_size);
@@ -197,7 +212,7 @@ ValueObjectConstResult::ValueObjectConstResult
m_name = name;
SetIsConstant ();
SetValueIsValid(true);
- m_pointers_point_to_load_addrs = true;
+ SetAddressTypeOfChildren(eAddressTypeLoad);
}
ValueObjectSP
@@ -217,11 +232,11 @@ ValueObjectConstResult::ValueObjectConstResult (
ValueObject (exe_scope),
m_clang_ast (NULL),
m_type_name (),
- m_byte_size (0)
+ m_byte_size (0),
+ m_impl(this)
{
m_error = error;
SetIsConstant ();
- m_pointers_point_to_load_addrs = true;
}
ValueObjectConstResult::~ValueObjectConstResult()
@@ -244,10 +259,7 @@ size_t
ValueObjectConstResult::GetByteSize()
{
if (m_byte_size == 0)
- {
- uint64_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetClangType());
- m_byte_size = (bit_width + 7 ) / 8;
- }
+ m_byte_size = ClangASTType::GetTypeByteSize(GetClangAST(), GetClangType());
return m_byte_size;
}
@@ -293,3 +305,35 @@ ValueObjectConstResult::IsInScope ()
// information needed to contain the constant value.
return true;
}
+
+lldb::ValueObjectSP
+ValueObjectConstResult::Dereference (Error &error)
+{
+ return m_impl.Dereference(error);
+}
+
+lldb::ValueObjectSP
+ValueObjectConstResult::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
+{
+ return m_impl.GetSyntheticChildAtOffset(offset, type, can_create);
+}
+
+lldb::ValueObjectSP
+ValueObjectConstResult::AddressOf (Error &error)
+{
+ return m_impl.AddressOf(error);
+}
+
+ValueObject *
+ValueObjectConstResult::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
+{
+ return m_impl.CreateChildAtIndex(idx, synthetic_array_member, synthetic_index);
+}
+
+size_t
+ValueObjectConstResult::GetPointeeData (DataExtractor& data,
+ uint32_t item_idx,
+ uint32_t item_count)
+{
+ return m_impl.GetPointeeData(data, item_idx, item_count);
+}
diff --git a/lldb/source/Core/ValueObjectConstResultChild.cpp b/lldb/source/Core/ValueObjectConstResultChild.cpp
new file mode 100644
index 00000000000..2a305a1bea5
--- /dev/null
+++ b/lldb/source/Core/ValueObjectConstResultChild.cpp
@@ -0,0 +1,82 @@
+//===-- ValueObjectConstResultChild.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/ValueObjectConstResultChild.h"
+
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/ValueObjectList.h"
+
+#include "lldb/Symbol/ClangASTContext.h"
+
+using namespace lldb_private;
+
+ValueObjectConstResultChild::ValueObjectConstResultChild
+(
+ ValueObject &parent,
+ clang::ASTContext *clang_ast,
+ void *clang_type,
+ const ConstString &name,
+ uint32_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
+) :
+ ValueObjectChild (parent,
+ clang_ast,
+ clang_type,
+ name,
+ byte_size,
+ byte_offset,
+ bitfield_bit_size,
+ bitfield_bit_offset,
+ is_base_class,
+ is_deref_of_parent,
+ eAddressTypeLoad),
+ m_impl(this)
+{
+ m_name = name;
+}
+
+ValueObjectConstResultChild::~ValueObjectConstResultChild()
+{
+}
+
+lldb::ValueObjectSP
+ValueObjectConstResultChild::Dereference (Error &error)
+{
+ return m_impl.Dereference(error);
+}
+
+lldb::ValueObjectSP
+ValueObjectConstResultChild::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
+{
+ return m_impl.GetSyntheticChildAtOffset(offset, type, can_create);
+}
+
+lldb::ValueObjectSP
+ValueObjectConstResultChild::AddressOf (Error &error)
+{
+ return m_impl.AddressOf(error);
+}
+
+ValueObject *
+ValueObjectConstResultChild::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
+{
+ return m_impl.CreateChildAtIndex(idx, synthetic_array_member, synthetic_index);
+}
+
+size_t
+ValueObjectConstResultChild::GetPointeeData (DataExtractor& data,
+ uint32_t item_idx,
+ uint32_t item_count)
+{
+ return m_impl.GetPointeeData(data, item_idx, item_count);
+}
diff --git a/lldb/source/Core/ValueObjectConstResultImpl.cpp b/lldb/source/Core/ValueObjectConstResultImpl.cpp
new file mode 100644
index 00000000000..119ba015590
--- /dev/null
+++ b/lldb/source/Core/ValueObjectConstResultImpl.cpp
@@ -0,0 +1,221 @@
+//===-- ValueObjectConstResultImpl.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/ValueObjectConstResultImpl.h"
+
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/ValueObjectConstResultChild.h"
+#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectList.h"
+
+#include "lldb/Symbol/ClangASTType.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;
+using namespace lldb_private;
+
+// this macro enables a simpler implementation for some method calls in this object that relies only upon
+// ValueObject knowning how to set the address type of its children correctly. the alternative implementation
+// relies on being able to create a target copy of the frozen object, which makes it less bug-prone but less
+// efficient as well. once we are confident the faster implementation is bug-free, this macro (and the slower
+// implementations) can go
+#define TRIVIAL_IMPL 1
+
+ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
+ lldb::addr_t live_address) :
+ m_impl_backend(valobj),
+ m_live_address(live_address),
+ m_load_addr_backend(),
+ m_address_of_backend()
+{
+}
+
+lldb::ValueObjectSP
+ValueObjectConstResultImpl::DerefOnTarget()
+{
+ if (m_load_addr_backend.get() == NULL)
+ {
+ lldb::addr_t tgt_address = m_impl_backend->GetPointerValue();
+ m_load_addr_backend = ValueObjectConstResult::Create (m_impl_backend->GetExecutionContextScope(),
+ m_impl_backend->GetClangAST(),
+ m_impl_backend->GetClangType(),
+ m_impl_backend->GetName(),
+ tgt_address,
+ eAddressTypeLoad,
+ m_impl_backend->GetUpdatePoint().GetProcessSP()->GetAddressByteSize());
+ }
+ return m_load_addr_backend;
+}
+
+lldb::ValueObjectSP
+ValueObjectConstResultImpl::Dereference (Error &error)
+{
+ if (m_impl_backend == NULL)
+ return lldb::ValueObjectSP();
+
+#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
+ return m_impl_backend->ValueObject::Dereference(error);
+#else
+ m_impl_backend->UpdateValueIfNeeded(false);
+
+ if (NeedsDerefOnTarget())
+ return DerefOnTarget()->Dereference(error);
+ else
+ return m_impl_backend->ValueObject::Dereference(error);
+#endif
+}
+
+ValueObject *
+ValueObjectConstResultImpl::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
+{
+ if (m_impl_backend == NULL)
+ return NULL;
+
+ m_impl_backend->UpdateValueIfNeeded(false);
+
+ ValueObjectConstResultChild *valobj = NULL;
+
+ bool omit_empty_base_classes = true;
+ bool ignore_array_bounds = synthetic_array_member;
+ std::string child_name_str;
+ uint32_t child_byte_size = 0;
+ int32_t child_byte_offset = 0;
+ uint32_t child_bitfield_bit_size = 0;
+ uint32_t child_bitfield_bit_offset = 0;
+ bool child_is_base_class = false;
+ bool child_is_deref_of_parent = false;
+
+ const bool transparent_pointers = synthetic_array_member == false;
+ clang::ASTContext *clang_ast = m_impl_backend->GetClangAST();
+ lldb::clang_type_t clang_type = m_impl_backend->GetClangType();
+ lldb::clang_type_t child_clang_type;
+
+ ExecutionContext exe_ctx;
+ m_impl_backend->GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
+
+ child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
+ clang_ast,
+ m_impl_backend->GetName().GetCString(),
+ clang_type,
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name_str,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent);
+ if (child_clang_type && child_byte_size)
+ {
+ if (synthetic_index)
+ child_byte_offset += child_byte_size * synthetic_index;
+
+ ConstString child_name;
+ if (!child_name_str.empty())
+ child_name.SetCString (child_name_str.c_str());
+
+ valobj = new ValueObjectConstResultChild (*m_impl_backend,
+ clang_ast,
+ child_clang_type,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent);
+ valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset);
+ }
+
+ return valobj;
+}
+
+lldb::ValueObjectSP
+ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create)
+{
+ if (m_impl_backend == NULL)
+ return lldb::ValueObjectSP();
+
+#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
+ return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
+#else
+ m_impl_backend->UpdateValueIfNeeded(false);
+
+ if (NeedsDerefOnTarget())
+ return DerefOnTarget()->GetSyntheticChildAtOffset(offset, type, can_create);
+ else
+ return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
+#endif
+}
+
+lldb::ValueObjectSP
+ValueObjectConstResultImpl::AddressOf (Error &error)
+{
+ if (m_address_of_backend.get() != NULL)
+ return m_address_of_backend;
+
+ if (m_impl_backend == NULL)
+ return lldb::ValueObjectSP();
+ if (m_live_address != LLDB_INVALID_ADDRESS)
+ {
+ ClangASTType type(m_impl_backend->GetClangAST(), m_impl_backend->GetClangType());
+
+ lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t)));
+
+ std::string new_name("&");
+ new_name.append(m_impl_backend->GetName().AsCString(""));
+
+ m_address_of_backend = ValueObjectConstResult::Create(m_impl_backend->GetUpdatePoint().GetExecutionContextScope(),
+ type.GetASTContext(),
+ type.GetPointerType(),
+ ConstString(new_name.c_str()),
+ buffer,
+ lldb::endian::InlHostByteOrder(),
+ m_impl_backend->GetExecutionContextScope()->CalculateProcess()->GetAddressByteSize());
+
+ m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
+ m_address_of_backend->GetValue().GetScalar() = m_live_address;
+
+ return m_address_of_backend;
+ }
+ else
+ return lldb::ValueObjectSP();
+}
+
+size_t
+ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
+ uint32_t item_idx,
+ uint32_t item_count)
+{
+ if (m_impl_backend == NULL)
+ return 0;
+#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
+ return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
+#else
+ m_impl_backend->UpdateValueIfNeeded(false);
+
+ if (NeedsDerefOnTarget() && m_impl_backend->IsPointerType())
+ return DerefOnTarget()->GetPointeeData(data, item_idx, item_count);
+ else
+ return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
+#endif
+}
diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp
index 2b381d7cb6b..5717406ba20 100644
--- a/lldb/source/Core/ValueObjectVariable.cpp
+++ b/lldb/source/Core/ValueObjectVariable.cpp
@@ -145,6 +145,23 @@ ValueObjectVariable::UpdateValue ()
m_value.SetContext(Value::eContextTypeVariable, variable);
Value::ValueType value_type = m_value.GetValueType();
+
+ switch (value_type)
+ {
+ case Value::eValueTypeFileAddress:
+ SetAddressTypeOfChildren(eAddressTypeFile);
+ break;
+ case Value::eValueTypeHostAddress:
+ SetAddressTypeOfChildren(eAddressTypeHost);
+ break;
+ case Value::eValueTypeLoadAddress:
+ SetAddressTypeOfChildren(eAddressTypeLoad);
+ break;
+ case Value::eValueTypeScalar:
+ // TODO: is this the right thing to do?
+ SetAddressTypeOfChildren(eAddressTypeInvalid);
+ break;
+ }
switch (value_type)
{
@@ -250,4 +267,10 @@ ValueObjectVariable::GetModule()
return NULL;
}
-
+SymbolContextScope *
+ValueObjectVariable::GetSymbolContextScope()
+{
+ if (m_variable_sp)
+ return m_variable_sp->GetSymbolContextScope();
+ return NULL;
+}
OpenPOWER on IntegriCloud