summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBCommandInterpreter.cpp2
-rw-r--r--lldb/source/API/SBData.cpp489
-rw-r--r--lldb/source/API/SBValue.cpp167
-rw-r--r--lldb/source/Commands/CommandObjectCommands.cpp2
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp3
-rw-r--r--lldb/source/Commands/CommandObjectType.cpp8
-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
-rw-r--r--lldb/source/Interpreter/CommandObject.cpp44
-rw-r--r--lldb/source/Interpreter/ScriptInterpreterPython.cpp245
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp2
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp10
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp25
-rw-r--r--lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp10
-rw-r--r--lldb/source/Symbol/ClangASTType.cpp47
-rw-r--r--lldb/source/Target/Target.cpp60
24 files changed, 1679 insertions, 552 deletions
diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp
index 5b3371b62bc..95e1cbc2ad2 100644
--- a/lldb/source/API/SBCommandInterpreter.cpp
+++ b/lldb/source/API/SBCommandInterpreter.cpp
@@ -334,7 +334,7 @@ LLDBSwigPythonCreateSyntheticProvider
extern "C" uint32_t LLDBSwigPython_CalculateNumChildren (void *implementor);
extern "C" void* LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx);
extern "C" int LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name);
-extern "C" lldb::SBValue* LLDBSWIGPython_CastPyObjectToSBValue (void* data);
+extern "C" void* LLDBSWIGPython_CastPyObjectToSBValue (void* data);
extern "C" void LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
extern "C" bool LLDBSwigPythonCallCommand
diff --git a/lldb/source/API/SBData.cpp b/lldb/source/API/SBData.cpp
new file mode 100644
index 00000000000..cee63164859
--- /dev/null
+++ b/lldb/source/API/SBData.cpp
@@ -0,0 +1,489 @@
+//===-- SBData.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/API/SBData.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBStream.h"
+
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Log.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBData::SBData ()
+{
+}
+
+SBData::SBData (const lldb::DataExtractorSP& data_sp) :
+ m_opaque_sp (data_sp)
+{
+}
+
+SBData::SBData(const SBData &rhs) :
+ m_opaque_sp (rhs.m_opaque_sp)
+{
+}
+
+const SBData &
+SBData::operator = (const SBData &rhs)
+{
+ if (this != &rhs)
+ m_opaque_sp = rhs.m_opaque_sp;
+ return *this;
+}
+
+SBData::~SBData ()
+{
+}
+
+void
+SBData::SetOpaque (const lldb::DataExtractorSP &data_sp)
+{
+ m_opaque_sp = data_sp;
+}
+
+lldb_private::DataExtractor *
+SBData::get() const
+{
+ return m_opaque_sp.get();
+}
+
+lldb_private::DataExtractor *
+SBData::operator->() const
+{
+ return m_opaque_sp.operator->();
+}
+
+lldb::DataExtractorSP &
+SBData::operator*()
+{
+ return m_opaque_sp;
+}
+
+const lldb::DataExtractorSP &
+SBData::operator*() const
+{
+ return m_opaque_sp;
+}
+
+bool
+SBData::IsValid()
+{
+ return m_opaque_sp.get() != NULL;
+}
+
+uint8_t
+SBData::GetAddressByteSize ()
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ uint8_t value = 0;
+ if (m_opaque_sp.get())
+ value = m_opaque_sp->GetAddressByteSize();
+ if (log)
+ log->Printf ("SBData::GetAddressByteSize () => "
+ "(%i)", value);
+ return value;
+}
+
+void
+SBData::Clear ()
+{
+ if (m_opaque_sp.get())
+ m_opaque_sp->Clear();
+}
+
+size_t
+SBData::GetByteSize ()
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ size_t value = 0;
+ if (m_opaque_sp.get())
+ value = m_opaque_sp->GetByteSize();
+ if (log)
+ log->Printf ("SBData::GetByteSize () => "
+ "(%i)", value);
+ return value;
+}
+
+lldb::ByteOrder
+SBData::GetByteOrder ()
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ lldb::ByteOrder value = eByteOrderInvalid;
+ if (m_opaque_sp.get())
+ value = m_opaque_sp->GetByteOrder();
+ if (log)
+ log->Printf ("SBData::GetByteOrder () => "
+ "(%i)", value);
+ return value;
+}
+
+float
+SBData::GetFloat (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ float value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = m_opaque_sp->GetFloat(&offset);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetFloat (error=%p,offset=%d) => "
+ "(%f)", error.get(), offset, value);
+ return value;
+}
+
+double
+SBData::GetDouble (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ double value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = m_opaque_sp->GetDouble(&offset);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetDouble (error=%p,offset=%d) => "
+ "(%f)", error.get(), offset, value);
+ return value;
+}
+
+long double
+SBData::GetLongDouble (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ long double value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = m_opaque_sp->GetLongDouble(&offset);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetLongDouble (error=%p,offset=%d) => "
+ "(%lf)", error.get(), offset, value);
+ return value;
+}
+
+lldb::addr_t
+SBData::GetAddress (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ lldb::addr_t value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = m_opaque_sp->GetAddress(&offset);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetAddress (error=%p,offset=%d) => "
+ "(%p)", error.get(), offset, (void*)value);
+ return value;
+}
+
+uint8_t
+SBData::GetUnsignedInt8 (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ uint8_t value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = m_opaque_sp->GetU8(&offset);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetUnsignedInt8 (error=%p,offset=%d) => "
+ "(%c)", error.get(), offset, value);
+ return value;
+}
+
+uint16_t
+SBData::GetUnsignedInt16 (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ uint16_t value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = m_opaque_sp->GetU16(&offset);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetUnsignedInt16 (error=%p,offset=%d) => "
+ "(%hd)", error.get(), offset, value);
+ return value;
+}
+
+uint32_t
+SBData::GetUnsignedInt32 (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ uint32_t value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = m_opaque_sp->GetU32(&offset);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetUnsignedInt32 (error=%p,offset=%d) => "
+ "(%d)", error.get(), offset, value);
+ return value;
+}
+
+uint64_t
+SBData::GetUnsignedInt64 (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ uint64_t value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = m_opaque_sp->GetU64(&offset);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetUnsignedInt64 (error=%p,offset=%d) => "
+ "(%q)", error.get(), offset, value);
+ return value;
+}
+
+int8_t
+SBData::GetSignedInt8 (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ int8_t value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = (int8_t)m_opaque_sp->GetMaxS64(&offset, 1);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetSignedInt8 (error=%p,offset=%d) => "
+ "(%c)", error.get(), offset, value);
+ return value;
+}
+
+int16_t
+SBData::GetSignedInt16 (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ int16_t value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = (int16_t)m_opaque_sp->GetMaxS64(&offset, 2);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetSignedInt16 (error=%p,offset=%d) => "
+ "(%hd)", error.get(), offset, value);
+ return value;
+}
+
+int32_t
+SBData::GetSignedInt32 (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ int32_t value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = (int32_t)m_opaque_sp->GetMaxS64(&offset, 4);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetSignedInt32 (error=%p,offset=%d) => "
+ "(%d)", error.get(), offset, value);
+ return value;
+}
+
+int64_t
+SBData::GetSignedInt64 (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ int64_t value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = (int64_t)m_opaque_sp->GetMaxS64(&offset, 8);
+ if (offset == old_offset)
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetSignedInt64 (error=%p,offset=%d) => "
+ "(%q)", error.get(), offset, value);
+ return value;
+}
+
+const char*
+SBData::GetString (lldb::SBError& error, uint32_t offset)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ const char* value = 0;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ value = m_opaque_sp->GetCStr(&offset);
+ if (offset == old_offset || (value == NULL))
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::GetString (error=%p,offset=%d) => "
+ "(%p)", error.get(), offset, value);
+ return value;
+}
+
+bool
+SBData::GetDescription (lldb::SBStream &description)
+{
+ if (m_opaque_sp)
+ {
+ description.ref();
+ m_opaque_sp->Dump(description.get(),
+ 0,
+ lldb::eFormatBytesWithASCII,
+ 1,
+ m_opaque_sp->GetByteSize(),
+ 16,
+ LLDB_INVALID_ADDRESS,
+ 0,
+ 0);
+ }
+ else
+ description.Printf ("No Value");
+
+ return true;
+}
+
+size_t
+SBData::ReadRawData (lldb::SBError& error,
+ uint32_t offset,
+ void *buf,
+ size_t size)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ void* ok = NULL;
+ if (!m_opaque_sp.get())
+ {
+ error.SetErrorString("no value to read from");
+ }
+ else
+ {
+ uint32_t old_offset = offset;
+ ok = m_opaque_sp->GetU8(&offset, buf, size);
+ if ((offset == old_offset) || (ok == NULL))
+ error.SetErrorString("unable to read data");
+ }
+ if (log)
+ log->Printf ("SBData::ReadRawData (error=%p,offset=%d,buf=%p,size=%d) => "
+ "(%p)", error.get(), offset, buf, size, ok);
+ return ok ? size : 0;
+}
+
+void
+SBData::SetData(lldb::SBError& error,
+ const void *buf,
+ size_t size,
+ lldb::ByteOrder endian,
+ uint8_t addr_size)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (!m_opaque_sp.get())
+ m_opaque_sp.reset(new DataExtractor(buf, size, endian, addr_size));
+ else
+ m_opaque_sp->SetData(buf, size, endian);
+ if (log)
+ log->Printf ("SBData::SetData (error=%p,buf=%p,size=%d,endian=%d,addr_size=%c) => "
+ "(%p)", error.get(), buf, size, endian, addr_size, m_opaque_sp.get());
+}
+
+bool
+SBData::Append(const SBData& rhs)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ bool value = false;
+ if (m_opaque_sp.get() && rhs.m_opaque_sp.get())
+ value = m_opaque_sp.get()->Append(*rhs.m_opaque_sp);
+ if (log)
+ log->Printf ("SBData::Append (rhs=%p) => "
+ "(%s)", rhs.get(), value ? "true" : "false");
+ return value;
+} \ No newline at end of file
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index a58957b9a9b..ea7ebf8c13e 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -479,6 +479,38 @@ SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, const SB
return result;
}
+lldb::SBValue
+SBValue::CreateValueFromData (const char* name,
+ const SBData& data,
+ const SBType& type)
+{
+ SBValue result;
+
+ AddressType addr_of_children_priv = eAddressTypeLoad;
+
+ if (m_opaque_sp)
+ {
+ ValueObjectSP valobj_sp;
+ valobj_sp = ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(),
+ type.m_opaque_sp->GetASTContext() ,
+ type.m_opaque_sp->GetOpaqueQualType(),
+ ConstString(name),
+ *data.m_opaque_sp,
+ LLDB_INVALID_ADDRESS);
+ valobj_sp->SetAddressTypeOfChildren(addr_of_children_priv);
+ result = SBValue(valobj_sp);
+ }
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ {
+ if (result.IsValid())
+ log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp.get());
+ else
+ log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get());
+ }
+ return result;
+}
+
SBValue
SBValue::GetChildAtIndex (uint32_t idx)
{
@@ -812,9 +844,10 @@ SBValue::GetProcess()
SBProcess result;
if (m_opaque_sp)
{
- if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
+ Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
+ if (target)
{
- result = SBProcess(lldb::ProcessSP(m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetProcessSP()));
+ result = SBProcess(lldb::ProcessSP(target->GetProcessSP()));
}
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -967,10 +1000,10 @@ SBValue::AddressOf()
SBValue sb_value;
if (m_opaque_sp)
{
- if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
+ Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
+ if (target)
{
- Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
-
+ Mutex::Locker api_locker (target->GetAPIMutex());
Error error;
sb_value = m_opaque_sp->AddressOf (error);
}
@@ -981,3 +1014,127 @@ SBValue::AddressOf()
return sb_value;
}
+
+lldb::addr_t
+SBValue::GetLoadAddress()
+{
+ lldb::addr_t value = LLDB_INVALID_ADDRESS;
+ if (m_opaque_sp)
+ {
+ Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
+ if (target)
+ {
+ Mutex::Locker api_locker (target->GetAPIMutex());
+ const bool scalar_is_load_address = true;
+ AddressType addr_type;
+ value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type);
+ if (addr_type == eAddressTypeFile)
+ {
+ Module* module = m_opaque_sp->GetModule();
+ if (!module)
+ value = LLDB_INVALID_ADDRESS;
+ else
+ {
+ Address addr;
+ module->ResolveFileAddress(value, addr);
+ value = addr.GetLoadAddress(m_opaque_sp->GetUpdatePoint().GetTargetSP().get());
+ }
+ }
+ else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeInvalid)
+ value = LLDB_INVALID_ADDRESS;
+ }
+ }
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ log->Printf ("SBValue(%p)::GetLoadAddress () => (%llu)", m_opaque_sp.get(), value);
+
+ return value;
+}
+
+lldb::SBAddress
+SBValue::GetAddress()
+{
+ Address addr;
+ if (m_opaque_sp)
+ {
+ Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
+ if (target)
+ {
+ lldb::addr_t value = LLDB_INVALID_ADDRESS;
+ Mutex::Locker api_locker (target->GetAPIMutex());
+ const bool scalar_is_load_address = true;
+ AddressType addr_type;
+ value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type);
+ if (addr_type == eAddressTypeFile)
+ {
+ Module* module = m_opaque_sp->GetModule();
+ if (module)
+ module->ResolveFileAddress(value, addr);
+ }
+ else if (addr_type == eAddressTypeLoad)
+ {
+ // no need to check the return value on this.. if it can actually do the resolve
+ // addr will be in the form (section,offset), otherwise it will simply be returned
+ // as (NULL, value)
+ addr.SetLoadAddress(value, target);
+ }
+ }
+ }
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", m_opaque_sp.get(), (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), addr.GetOffset());
+ return SBAddress(new Address(addr));
+}
+
+lldb::SBData
+SBValue::GetPointeeData (uint32_t item_idx,
+ uint32_t item_count)
+{
+ lldb::SBData sb_data;
+ if (m_opaque_sp)
+ {
+ Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
+ if (target)
+ {
+ DataExtractorSP data_sp(new DataExtractor());
+ Mutex::Locker api_locker (target->GetAPIMutex());
+ m_opaque_sp->GetPointeeData(*data_sp, item_idx, item_count);
+ if (data_sp->GetByteSize() > 0)
+ *sb_data = data_sp;
+ }
+ }
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)",
+ m_opaque_sp.get(),
+ item_idx,
+ item_count,
+ sb_data.get());
+
+ return sb_data;
+}
+
+lldb::SBData
+SBValue::GetData ()
+{
+ lldb::SBData sb_data;
+ if (m_opaque_sp)
+ {
+ Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
+ if (target)
+ {
+ DataExtractorSP data_sp(new DataExtractor());
+ Mutex::Locker api_locker (target->GetAPIMutex());
+ m_opaque_sp->GetData(*data_sp);
+ if (data_sp->GetByteSize() > 0)
+ *sb_data = data_sp;
+ }
+ }
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ log->Printf ("SBValue(%p)::GetData () => SBData(%p)",
+ m_opaque_sp.get(),
+ sb_data.get());
+
+ return sb_data;
+}
diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp
index 8f63bf29009..da0af986247 100644
--- a/lldb/source/Commands/CommandObjectCommands.cpp
+++ b/lldb/source/Commands/CommandObjectCommands.cpp
@@ -1514,7 +1514,7 @@ public:
OptionDefinition
CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypeName, "Name of a Python function to use."},
+ { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 694c904391e..4be9b8de3ad 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -321,9 +321,6 @@ CommandObjectExpression::EvaluateExpression
{
if (result_valobj_sp->GetError().Success())
{
-
- result_valobj_sp.get()->SetIsExpressionResult(true);
-
if (m_options.format != eFormatDefault)
result_valobj_sp->SetFormat (m_options.format);
diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp
index e12427a50c8..2e82df060c6 100644
--- a/lldb/source/Commands/CommandObjectType.cpp
+++ b/lldb/source/Commands/CommandObjectType.cpp
@@ -1082,8 +1082,8 @@ CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
{ LLDB_OPT_SET_1 , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeNone, "If true, inline all child values into summary string."},
{ LLDB_OPT_SET_2 , true, "summary-string", 's', required_argument, NULL, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."},
- { LLDB_OPT_SET_3, false, "python-script", 'o', required_argument, NULL, 0, eArgTypeName, "Give a one-liner Python script as part of the command."},
- { LLDB_OPT_SET_3, false, "python-function", 'F', required_argument, NULL, 0, eArgTypeName, "Give the name of a Python function to use for this type."},
+ { LLDB_OPT_SET_3, false, "python-script", 'o', required_argument, NULL, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."},
+ { LLDB_OPT_SET_3, false, "python-function", 'F', required_argument, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."},
{ LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."},
{ LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', no_argument, NULL, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines."},
{ LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, 0, eArgTypeName, "A name for this summary string."},
@@ -3262,7 +3262,7 @@ CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypeName, "Use this Python class to produce synthetic children."},
+ { LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."},
{ LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."},
{ LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
@@ -3548,7 +3548,7 @@ CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_ALL, false, "child", 'c', required_argument, NULL, 0, eArgTypeName, "Include this expression path in the synthetic view."},
+ { LLDB_OPT_SET_ALL, false, "child", 'c', required_argument, NULL, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."},
{ LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
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;
+}
diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp
index 1607d8e11c2..b1eafd5e30f 100644
--- a/lldb/source/Interpreter/CommandObject.cpp
+++ b/lldb/source/Interpreter/CommandObject.cpp
@@ -697,8 +697,8 @@ SummaryStringHelpTextCallback()
"A variable is expanded by giving it a value other than its textual representation, and the way this is done depends on what comes after the ${ marker.\n"
"The most common sequence if ${var followed by an expression path, which is the text one would type to access a member of an aggregate types, given a variable of that type"
" (e.g. if type T has a member named x, which has a member named y, and if t is of type T, the expression path would be .x.y and the way to fit that into a summary string would be"
- " ${var.x.y}). In expression paths you can use either . or -> without any difference in meaning. You can also use ${*var followed by an expression path and in that case"
- " the object referred by the path will be dereferenced before being displayed. If the object is not a pointer, doing so will cause an error.\n"
+ " ${var.x.y}). You can also use ${*var followed by an expression path and in that case the object referred by the path will be dereferenced before being displayed."
+ " If the object is not a pointer, doing so will cause an error. For additional details on expression paths, you can type 'help expr-path'. \n"
"By default, summary strings attempt to display the summary for any variable they reference, and if that fails the value. If neither can be shown, nothing is displayed."
"In a summary string, you can also use an array index [n], or a slice-like range [n-m]. This can have two different meanings depending on what kind of object the expression"
" path refers to:\n"
@@ -706,7 +706,41 @@ SummaryStringHelpTextCallback()
" and displayed as an individual variable\n"
" - if it is an array or pointer the array items indicated by the indexing operator are shown as the result of the variable. if the expression is an array, real array items are"
" printed; if it is a pointer, the pointer-as-array syntax is used to obtain the values (this means, the latter case can have no range checking)\n"
- "If you are trying to display an array for which the size is known, you can also use [] instead of giving an exact range. This has the effect of showing items 0 thru size - 1.";
+ "If you are trying to display an array for which the size is known, you can also use [] instead of giving an exact range. This has the effect of showing items 0 thru size - 1.\n"
+ "Additionally, a variable can contain an (optional) format code, as in ${var.x.y%code}, where code can be any of the valid formats described in 'help format', or one of the"
+ " special symbols only allowed as part of a variable:\n"
+ " %V: show the value of the object by default\n"
+ " %S: show the summary of the object by default\n"
+ " %@: show the runtime-provided object description (for Objective-C, it calls NSPrintForDebugger; for C/C++ it does nothing)\n"
+ " %L: show the location of the object (memory address or a register name)\n"
+ " %#: show the number of children of the object\n"
+ " %T: show the type of the object\n"
+ "Another variable that you can use in summary strings is ${svar . This sequence works exactly like ${var, including the fact that ${*svar is an allowed sequence, but uses"
+ " the object's synthetic children provider instead of the actual objects. For instance, if you are using STL synthetic children providers, the following summary string would"
+ " count the number of actual elements stored in an std::list:\n"
+ "type summary add -s \"${svar%#}\" -x \"std::list<\"";
+}
+
+static const char *
+ExprPathHelpTextCallback()
+{
+ return
+ "An expression path is the sequence of symbols that is used in C/C++ to access a member variable of an aggregate object (class).\n"
+ "For instance, given a class:\n"
+ " class foo {\n"
+ " int a;\n"
+ " int b; .\n"
+ " foo* next;\n"
+ " };\n"
+ "the expression to read item b in the item pointed to by next for foo aFoo would be aFoo.next->b.\n"
+ "Given that aFoo could just be any object of type foo, the string '.next->b' is the expression path, because it can be attached to any foo instance to achieve the effect.\n"
+ "Expression paths in LLDB include dot (.) and arrow (->) operators, and most commands using expression paths have ways to also accept the star (*) operator.\n"
+ "The meaning of these operators is the same as the usual one given to them by the C/C++ standards.\n"
+ "LLDB also has support for indexing ([ ]) in expression paths, and extends the traditional meaning of the square brackets operator to allow bitfield extraction:\n"
+ "for objects of native types (int, float, char, ...) saying '[n-m]' as an expression path (where n and m are any positive integers, e.g. [3-5]) causes LLDB to extract"
+ " bits n thru m from the value of the variable. If n == m, [n] is also allowed as a shortcut syntax. For arrays and pointers, expression paths can only contain one index"
+ " and the meaning of the operation is the same as the one defined by C/C++ (item extraction). Some commands extend bitfield-like syntax for arrays and pointers with the"
+ " meaning of array slicing (taking elements n thru m inside the array or pointed-to memory).";
}
const char *
@@ -742,6 +776,7 @@ CommandObject::g_arguments_data[] =
{ eArgTypeCount, "count", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
{ eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
{ eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
+ { eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, NULL },
{ eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, { NULL, false }, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" },
{ eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, { NULL, false }, "The name of a file (can include path)." },
{ eArgTypeFormat, "format", CommandCompletions::eNoCompletion, { FormatHelpTextCallback, true }, NULL },
@@ -764,6 +799,9 @@ CommandObject::g_arguments_data[] =
{ eArgTypePid, "pid", CommandCompletions::eNoCompletion, { NULL, false }, "The process ID number." },
{ eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
{ eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of the process." },
+ { eArgTypePythonClass, "python-class", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a Python class." },
+ { eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a Python function." },
+ { eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { NULL, false }, "Source code written in Python." },
{ eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of the thread queue." },
{ eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { NULL, false }, "A register name." },
{ eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { NULL, false }, "A regular expression." },
diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
index 0f508de7c5d..bbaa8b9ad06 100644
--- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
@@ -18,9 +18,7 @@
#include <string>
-#include "lldb/API/SBFrame.h"
-#include "lldb/API/SBBreakpointLocation.h"
-#include "lldb/API/SBCommandReturnObject.h"
+#include "lldb/API/SBValue.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Timer.h"
@@ -90,6 +88,36 @@ ReleasePythonLock ()
PythonMutexPredicate().SetValue (LLDB_INVALID_THREAD_ID, eBroadcastAlways);
}
+ScriptInterpreterPython::Locker::Locker (ScriptInterpreterPython *pi,
+ FILE* tmp_fh,
+ bool ns) :
+ m_need_session(ns),
+ m_release_lock(false),
+ m_python_interpreter(pi),
+ m_tmp_fh(tmp_fh)
+{
+ // if Enter/LeaveSession() must be called, then m_python_interpreter must be != NULL
+ assert(m_need_session && m_python_interpreter);
+ if (!CurrentThreadHasPythonLock())
+ {
+ while (!GetPythonLock (1))
+ if (tmp_fh)
+ fprintf (tmp_fh,
+ "Python interpreter locked on another thread; waiting to acquire lock...\n");
+ m_release_lock = true;
+ }
+ if (m_need_session)
+ m_python_interpreter->EnterSession ();
+}
+
+ScriptInterpreterPython::Locker::~Locker()
+{
+ if (m_need_session)
+ m_python_interpreter->LeaveSession ();
+ if (m_release_lock)
+ ReleasePythonLock ();
+}
+
ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) :
ScriptInterpreter (interpreter, eScriptLanguagePython),
m_embedded_python_pty (),
@@ -226,21 +254,10 @@ ScriptInterpreterPython::ResetOutputFileHandle (FILE *fh)
m_dbg_stdout = fh;
FILE *tmp_fh = (m_dbg_stdout ? m_dbg_stdout : stdout);
- if (!CurrentThreadHasPythonLock ())
- {
- while (!GetPythonLock (1))
- fprintf (tmp_fh, "Python interpreter locked on another thread; waiting to acquire lock...\n");
- EnterSession ();
- m_new_sysout = PyFile_FromFile (m_dbg_stdout, (char *) "", (char *) "w", _check_and_flush);
- LeaveSession ();
- ReleasePythonLock ();
- }
- else
- {
- EnterSession ();
- m_new_sysout = PyFile_FromFile (m_dbg_stdout, (char *) "", (char *) "w", _check_and_flush);
- LeaveSession ();
- }
+
+ Locker py_lock(this, tmp_fh);
+
+ m_new_sysout = PyFile_FromFile (m_dbg_stdout, (char *) "", (char *) "w", _check_and_flush);
}
void
@@ -1400,25 +1417,12 @@ ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name
void* ret_val;
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
- if (CurrentThreadHasPythonLock())
+
{
- python_interpreter->EnterSession ();
+ Locker py_lock(this, tmp_fh);
ret_val = g_swig_synthetic_script (class_name,
python_interpreter->m_dictionary_name.c_str(),
valobj);
- python_interpreter->LeaveSession ();
- }
- else
- {
- while (!GetPythonLock (1))
- fprintf (tmp_fh,
- "Python interpreter locked on another thread; waiting to acquire lock...\n");
- python_interpreter->EnterSession ();
- ret_val = g_swig_synthetic_script (class_name,
- python_interpreter->m_dictionary_name.c_str(),
- valobj);
- python_interpreter->LeaveSession ();
- ReleasePythonLock ();
}
return ret_val;
@@ -1526,25 +1530,12 @@ ScriptInterpreterPython::CallPythonScriptFunction (const char *python_function_n
&& *python_function_name)
{
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
- if (CurrentThreadHasPythonLock())
+
{
- python_interpreter->EnterSession ();
+ Locker py_lock(python_interpreter, tmp_fh);
ret_val = g_swig_typescript_callback (python_function_name,
python_interpreter->m_dictionary_name.c_str(),
valobj);
- python_interpreter->LeaveSession ();
- }
- else
- {
- while (!GetPythonLock (1))
- fprintf (tmp_fh,
- "Python interpreter locked on another thread; waiting to acquire lock...\n");
- python_interpreter->EnterSession ();
- ret_val = g_swig_typescript_callback (python_function_name,
- python_interpreter->m_dictionary_name.c_str(),
- valobj);
- python_interpreter->LeaveSession ();
- ReleasePythonLock ();
}
}
else
@@ -1595,27 +1586,13 @@ ScriptInterpreterPython::BreakpointCallbackFunction
{
bool ret_val = true;
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
- if (CurrentThreadHasPythonLock())
- {
- python_interpreter->EnterSession ();
- ret_val = g_swig_breakpoint_callback (python_function_name,
- python_interpreter->m_dictionary_name.c_str(),
- stop_frame_sp,
- bp_loc_sp);
- python_interpreter->LeaveSession ();
- }
- else
+
{
- while (!GetPythonLock (1))
- fprintf (tmp_fh,
- "Python interpreter locked on another thread; waiting to acquire lock...\n");
- python_interpreter->EnterSession ();
+ Locker py_lock(python_interpreter, tmp_fh);
ret_val = g_swig_breakpoint_callback (python_function_name,
python_interpreter->m_dictionary_name.c_str(),
stop_frame_sp,
bp_loc_sp);
- python_interpreter->LeaveSession ();
- ReleasePythonLock ();
}
return ret_val;
}
@@ -1758,55 +1735,47 @@ ScriptInterpreterPython::CalculateNumChildren (void *implementor)
uint32_t ret_val = 0;
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
- if (CurrentThreadHasPythonLock())
- {
- python_interpreter->EnterSession ();
- ret_val = g_swig_calc_children (implementor);
- python_interpreter->LeaveSession ();
- }
- else
+
{
- while (!GetPythonLock (1))
- fprintf (tmp_fh,
- "Python interpreter locked on another thread; waiting to acquire lock...\n");
- python_interpreter->EnterSession ();
+ Locker py_lock(python_interpreter, tmp_fh);
ret_val = g_swig_calc_children (implementor);
- python_interpreter->LeaveSession ();
- ReleasePythonLock ();
}
return ret_val;
}
-void*
+lldb::ValueObjectSP
ScriptInterpreterPython::GetChildAtIndex (void *implementor, uint32_t idx)
{
if (!implementor)
- return 0;
+ return lldb::ValueObjectSP();
- if (!g_swig_get_child_index)
- return 0;
+ if (!g_swig_get_child_index || !g_swig_cast_to_sbvalue)
+ return lldb::ValueObjectSP();
ScriptInterpreterPython *python_interpreter = this;
- void* ret_val = NULL;
+ void* child_ptr = NULL;
+ lldb::SBValue* value_sb = NULL;
+ lldb::ValueObjectSP ret_val;
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
- if (CurrentThreadHasPythonLock())
- {
- python_interpreter->EnterSession ();
- ret_val = g_swig_get_child_index (implementor,idx);
- python_interpreter->LeaveSession ();
- }
- else
+
{
- while (!GetPythonLock (1))
- fprintf (tmp_fh,
- "Python interpreter locked on another thread; waiting to acquire lock...\n");
- python_interpreter->EnterSession ();
- ret_val = g_swig_get_child_index (implementor,idx);
- python_interpreter->LeaveSession ();
- ReleasePythonLock ();
+ Locker py_lock(python_interpreter, tmp_fh);
+ child_ptr = g_swig_get_child_index (implementor,idx);
+ if (child_ptr != NULL && child_ptr != Py_None)
+ {
+ value_sb = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
+ if (value_sb == NULL)
+ Py_XDECREF(child_ptr);
+ else
+ ret_val = value_sb->get_sp();
+ }
+ else
+ {
+ Py_XDECREF(child_ptr);
+ }
}
return ret_val;
@@ -1826,21 +1795,10 @@ ScriptInterpreterPython::GetIndexOfChildWithName (void *implementor, const char*
int ret_val = UINT32_MAX;
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
- if (CurrentThreadHasPythonLock())
- {
- python_interpreter->EnterSession ();
- ret_val = g_swig_get_index_child (implementor, child_name);
- python_interpreter->LeaveSession ();
- }
- else
+
{
- while (!GetPythonLock (1))
- fprintf (tmp_fh,
- "Python interpreter locked on another thread; waiting to acquire lock...\n");
- python_interpreter->EnterSession ();
+ Locker py_lock(python_interpreter, tmp_fh);
ret_val = g_swig_get_index_child (implementor, child_name);
- python_interpreter->LeaveSession ();
- ReleasePythonLock ();
}
return ret_val;
@@ -1858,60 +1816,15 @@ ScriptInterpreterPython::UpdateSynthProviderInstance (void* implementor)
ScriptInterpreterPython *python_interpreter = this;
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
- if (CurrentThreadHasPythonLock())
- {
- python_interpreter->EnterSession ();
- g_swig_update_provider (implementor);
- python_interpreter->LeaveSession ();
- }
- else
+
{
- while (!GetPythonLock (1))
- fprintf (tmp_fh,
- "Python interpreter locked on another thread; waiting to acquire lock...\n");
- python_interpreter->EnterSession ();
+ Locker py_lock(python_interpreter, tmp_fh);
g_swig_update_provider (implementor);
- python_interpreter->LeaveSession ();
- ReleasePythonLock ();
}
return;
}
-lldb::SBValue*
-ScriptInterpreterPython::CastPyObjectToSBValue (void* data)
-{
- if (!data)
- return NULL;
-
- if (!g_swig_cast_to_sbvalue)
- return NULL;
-
- ScriptInterpreterPython *python_interpreter = this;
-
- lldb::SBValue* ret_val = NULL;
-
- FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
- if (CurrentThreadHasPythonLock())
- {
- python_interpreter->EnterSession ();
- ret_val = g_swig_cast_to_sbvalue (data);
- python_interpreter->LeaveSession ();
- }
- else
- {
- while (!GetPythonLock (1))
- fprintf (tmp_fh,
- "Python interpreter locked on another thread; waiting to acquire lock...\n");
- python_interpreter->EnterSession ();
- ret_val = g_swig_cast_to_sbvalue (data);
- python_interpreter->LeaveSession ();
- ReleasePythonLock ();
- }
-
- return ret_val;
-}
-
bool
ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
const char* args,
@@ -1939,31 +1852,15 @@ ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
std::string err_msg;
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
- if (CurrentThreadHasPythonLock())
- {
- python_interpreter->EnterSession ();
- ret_val = g_swig_call_command (impl_function,
- python_interpreter->m_dictionary_name.c_str(),
- debugger_sp,
- args,
- err_msg,
- cmd_retobj);
- python_interpreter->LeaveSession ();
- }
- else
+
{
- while (!GetPythonLock (1))
- fprintf (tmp_fh,
- "Python interpreter locked on another thread; waiting to acquire lock...\n");
- python_interpreter->EnterSession ();
+ Locker py_lock(python_interpreter, tmp_fh);
ret_val = g_swig_call_command (impl_function,
python_interpreter->m_dictionary_name.c_str(),
debugger_sp,
args,
err_msg,
cmd_retobj);
- python_interpreter->LeaveSession ();
- ReleasePythonLock ();
}
if (!ret_val)
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 52e07ce4fe7..90b17d1c084 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -62,7 +62,7 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
// First job, pull out the address at 0 offset from the object.
AddressType address_type;
- lldb::addr_t original_ptr = in_value.GetPointerValue(address_type, true);
+ lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
if (original_ptr == LLDB_INVALID_ADDRESS)
return false;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 5c84f710b72..1dfb3645473 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -49,17 +49,11 @@ AppleObjCRuntime::GetObjectDescription (Stream &str, ValueObject &object)
return NULL;
// Make the argument list: we pass one arg, the address of our pointer, to the print function.
- Scalar scalar;
+ Value val;
- if (!ClangASTType::GetValueAsScalar (object.GetClangAST(),
- object.GetClangType(),
- object.GetDataExtractor(),
- 0,
- object.GetByteSize(),
- scalar))
+ if (!object.ResolveValue(val.GetScalar()))
return NULL;
- Value val(scalar);
return GetObjectDescription(str, val, object.GetExecutionContextScope());
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 9e97f3b9923..4d4d4fbebf5 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -245,7 +245,7 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value,
{
// First job, pull out the address at 0 offset from the object That will be the ISA pointer.
AddressType address_type;
- lldb::addr_t original_ptr = in_value.GetPointerValue(address_type, true);
+ lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
// ObjC only has single inheritance, so the objects all start at the same pointer value.
address.SetSection (NULL);
@@ -584,26 +584,6 @@ AppleObjCRuntimeV2::IsTaggedPointer(lldb::addr_t ptr)
lldb_private::ObjCLanguageRuntime::ObjCISA
AppleObjCRuntimeV2::GetISA(ValueObject& valobj)
{
-
- if (valobj.GetIsExpressionResult() &&
- valobj.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 this code reads memory without
- // taking the debug-info-provided object layout, we need to hand it the target version
- // of the expression output
- lldb::addr_t tgt_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- ValueObjectSP target_object = ValueObjectConstResult::Create (valobj.GetExecutionContextScope(),
- valobj.GetClangAST(),
- valobj.GetClangType(),
- valobj.GetName(),
- tgt_address,
- eAddressTypeLoad,
- valobj.GetUpdatePoint().GetProcessSP()->GetAddressByteSize());
- return GetISA(*target_object);
- }
-
if (ClangASTType::GetMinimumLanguage(valobj.GetClangAST(),valobj.GetClangType()) != lldb::eLanguageTypeObjC)
return 0;
@@ -613,8 +593,7 @@ AppleObjCRuntimeV2::GetISA(ValueObject& valobj)
if (valobj.GetValue().GetContextType() == Value::eContextTypeInvalid)
return 0;
- uint32_t offset = 0;
- uint64_t isa_pointer = valobj.GetDataExtractor().GetPointer(&offset);
+ lldb::addr_t isa_pointer = valobj.GetPointerValue();
// tagged pointer
if (IsTaggedPointer(isa_pointer))
diff --git a/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp b/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp
index 2fdd3b099b3..c5f3e40bd34 100644
--- a/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp
+++ b/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp
@@ -156,9 +156,9 @@ OperatingSystemDarwinKernel::GetDynamicRegisterInfo ()
ValueObjectSP gpr_valobj_sp (m_thread_list_valobj_sp->GetChildMemberWithName(GetThreadGPRMemberName (), can_create));
if (gpr_valobj_sp->IsPointerType ())
- base_addr = gpr_valobj_sp->GetPointerValue (addr_type, true);
+ base_addr = gpr_valobj_sp->GetPointerValue (&addr_type);
else
- base_addr = gpr_valobj_sp->GetAddressOf (addr_type, true);
+ base_addr = gpr_valobj_sp->GetAddressOf (true, &addr_type);
ValueObjectSP child_valobj_sp;
if (gpr_valobj_sp)
@@ -188,7 +188,7 @@ OperatingSystemDarwinKernel::GetDynamicRegisterInfo ()
{
// Adjust the byte size and the offset to match the layout of registers in our struct
reg_info.byte_size = child_valobj_sp->GetByteSize();
- reg_info.byte_offset = child_valobj_sp->GetAddressOf(addr_type, true) - base_addr;
+ reg_info.byte_offset = child_valobj_sp->GetAddressOf(true, &addr_type) - base_addr;
reg_info.kinds[eRegisterKindLLDB] = reg_num++;
m_register_info_ap->AddRegister (reg_info, reg_name, empty_name, gpr_name);
}
@@ -290,9 +290,9 @@ OperatingSystemDarwinKernel::CreateRegisterContextForThread (Thread *thread)
if (gpr_valobj_sp)
{
if (gpr_valobj_sp->IsPointerType ())
- base_addr = gpr_valobj_sp->GetPointerValue (addr_type, true);
+ base_addr = gpr_valobj_sp->GetPointerValue (&addr_type);
else
- base_addr = gpr_valobj_sp->GetAddressOf (addr_type, true);
+ base_addr = gpr_valobj_sp->GetAddressOf (true, &addr_type);
reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), base_addr));
}
}
diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp
index b94692bf004..931bd5e7273 100644
--- a/lldb/source/Symbol/ClangASTType.cpp
+++ b/lldb/source/Symbol/ClangASTType.cpp
@@ -154,6 +154,53 @@ ClangASTType::GetPointeeType (clang_type_t clang_type)
return NULL;
}
+lldb::clang_type_t
+ClangASTType::GetArrayElementType (uint32_t& stride)
+{
+ return GetArrayElementType(m_ast, m_type, stride);
+}
+
+lldb::clang_type_t
+ClangASTType::GetArrayElementType (clang::ASTContext* ast,
+ lldb::clang_type_t opaque_clang_qual_type,
+ uint32_t& stride)
+{
+ if (opaque_clang_qual_type)
+ {
+ clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
+
+ lldb::clang_type_t ret_type = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified().getAsOpaquePtr();
+
+ // TODO: the real stride will be >= this value.. find the real one!
+ stride = GetTypeByteSize(ast, ret_type);
+
+ return ret_type;
+
+ }
+ return NULL;
+
+}
+
+lldb::clang_type_t
+ClangASTType::GetPointerType ()
+{
+ return GetPointerType (m_ast,
+ m_type);
+}
+
+lldb::clang_type_t
+ClangASTType::GetPointerType (clang::ASTContext *ast_context,
+ lldb::clang_type_t opaque_clang_qual_type)
+{
+ if (opaque_clang_qual_type)
+ {
+ clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
+
+ return ast_context->getPointerType(qual_type).getAsOpaquePtr();
+ }
+ return NULL;
+}
+
lldb::Encoding
ClangASTType::GetEncoding (uint32_t &count)
{
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 25d37435ff6..812d906dbf4 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -623,10 +623,20 @@ Target::ReadMemoryFromFileCache (const Address& addr, void *dst, size_t dst_len,
}
size_t
-Target::ReadMemory (const Address& addr, bool prefer_file_cache, void *dst, size_t dst_len, Error &error)
+Target::ReadMemory (const Address& addr,
+ bool prefer_file_cache,
+ void *dst,
+ size_t dst_len,
+ Error &error,
+ lldb::addr_t *load_addr_ptr)
{
error.Clear();
+ // if we end up reading this from process memory, we will fill this
+ // with the actual load address
+ if (load_addr_ptr)
+ *load_addr_ptr = LLDB_INVALID_ADDRESS;
+
bool process_is_valid = m_process_sp && m_process_sp->IsAlive();
size_t bytes_read = 0;
@@ -692,7 +702,11 @@ Target::ReadMemory (const Address& addr, bool prefer_file_cache, void *dst, size
}
}
if (bytes_read)
+ {
+ if (load_addr_ptr)
+ *load_addr_ptr = load_addr;
return bytes_read;
+ }
// If the address is not section offset we have an address that
// doesn't resolve to any address in any currently loaded shared
// libaries and we failed to read memory so there isn't anything
@@ -1579,6 +1593,7 @@ Target::SettingsController::CreateInstanceSettings (const char *instance_name)
#define TSC_SKIP_PROLOGUE "skip-prologue"
#define TSC_SOURCE_MAP "source-map"
#define TSC_MAX_CHILDREN "max-children-count"
+#define TSC_MAX_STRLENSUMMARY "max-string-summary-length"
static const ConstString &
@@ -1623,6 +1638,12 @@ GetSettingNameForMaxChildren ()
return g_const_string;
}
+static const ConstString &
+GetSettingNameForMaxStringSummaryLength ()
+{
+ static ConstString g_const_string (TSC_MAX_STRLENSUMMARY);
+ return g_const_string;
+}
bool
Target::SettingsController::SetGlobalVariable (const ConstString &var_name,
@@ -1676,7 +1697,8 @@ TargetInstanceSettings::TargetInstanceSettings
m_prefer_dynamic_value (2),
m_skip_prologue (true, true),
m_source_map (NULL, NULL),
- m_max_children_display(256)
+ m_max_children_display(256),
+ m_max_strlen_length(1024)
{
// CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
// until the vtables for TargetInstanceSettings are properly set up, i.e. AFTER all the initializers.
@@ -1703,7 +1725,8 @@ TargetInstanceSettings::TargetInstanceSettings (const TargetInstanceSettings &rh
m_prefer_dynamic_value (rhs.m_prefer_dynamic_value),
m_skip_prologue (rhs.m_skip_prologue),
m_source_map (rhs.m_source_map),
- m_max_children_display(rhs.m_max_children_display)
+ m_max_children_display(rhs.m_max_children_display),
+ m_max_strlen_length(rhs.m_max_strlen_length)
{
if (m_instance_name != InstanceSettings::GetDefaultName())
{
@@ -1787,6 +1810,13 @@ TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_n
if (ok)
m_max_children_display = new_value;
}
+ else if (var_name == GetSettingNameForMaxStringSummaryLength())
+ {
+ bool ok;
+ uint32_t new_value = Args::StringToUInt32(value, 0, 10, &ok);
+ if (ok)
+ m_max_strlen_length = new_value;
+ }
else if (var_name == GetSettingNameForSourcePathMap ())
{
switch (op)
@@ -1858,6 +1888,7 @@ TargetInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &ne
m_prefer_dynamic_value = new_settings_ptr->m_prefer_dynamic_value;
m_skip_prologue = new_settings_ptr->m_skip_prologue;
m_max_children_display = new_settings_ptr->m_max_children_display;
+ m_max_strlen_length = new_settings_ptr->m_max_strlen_length;
}
bool
@@ -1893,6 +1924,12 @@ TargetInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
count_str.Printf ("%d", m_max_children_display);
value.AppendString (count_str.GetData());
}
+ else if (var_name == GetSettingNameForMaxStringSummaryLength())
+ {
+ StreamString count_str;
+ count_str.Printf ("%d", m_max_strlen_length);
+ value.AppendString (count_str.GetData());
+ }
else
{
if (err)
@@ -1940,12 +1977,13 @@ Target::SettingsController::global_settings_table[] =
SettingEntry
Target::SettingsController::instance_settings_table[] =
{
- // var-name var-type default enum init'd hidden help-text
- // ================= ================== =============== ======================= ====== ====== =========================================================================
- { TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." },
- { TSC_PREFER_DYNAMIC, eSetVarTypeEnum , NULL , g_dynamic_value_types, false, false, "Should printed values be shown as their dynamic value." },
- { TSC_SKIP_PROLOGUE , eSetVarTypeBoolean, "true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." },
- { TSC_SOURCE_MAP , eSetVarTypeArray , NULL , NULL, false, false, "Source path remappings to use when locating source files from debug information." },
- { TSC_MAX_CHILDREN , eSetVarTypeInt , "256" , NULL, true, false, "Maximum number of children to expand in any level of depth." },
- { NULL , eSetVarTypeNone , NULL , NULL, false, false, NULL }
+ // var-name var-type default enum init'd hidden help-text
+ // ================= ================== =============== ======================= ====== ====== =========================================================================
+ { TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." },
+ { TSC_PREFER_DYNAMIC , eSetVarTypeEnum , NULL , g_dynamic_value_types, false, false, "Should printed values be shown as their dynamic value." },
+ { TSC_SKIP_PROLOGUE , eSetVarTypeBoolean, "true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." },
+ { TSC_SOURCE_MAP , eSetVarTypeArray , NULL , NULL, false, false, "Source path remappings to use when locating source files from debug information." },
+ { TSC_MAX_CHILDREN , eSetVarTypeInt , "256" , NULL, true, false, "Maximum number of children to expand in any level of depth." },
+ { TSC_MAX_STRLENSUMMARY , eSetVarTypeInt , "1024" , NULL, true, false, "Maximum number of characters to show when using %s in summary strings." },
+ { NULL , eSetVarTypeNone , NULL , NULL, false, false, NULL }
};
OpenPOWER on IntegriCloud