summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBModule.cpp35
-rw-r--r--lldb/source/API/SBTarget.cpp47
-rw-r--r--lldb/source/API/SBValueList.cpp44
-rw-r--r--lldb/source/Core/Value.cpp78
-rw-r--r--lldb/source/Core/ValueObject.cpp190
-rw-r--r--lldb/source/Core/ValueObjectList.cpp10
-rw-r--r--lldb/source/Core/ValueObjectVariable.cpp2
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp144
8 files changed, 418 insertions, 132 deletions
diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp
index 0c4eba43e56..53172f349ca 100644
--- a/lldb/source/API/SBModule.cpp
+++ b/lldb/source/API/SBModule.cpp
@@ -15,6 +15,10 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
@@ -307,3 +311,34 @@ SBModule::FindFunctions (const char *name,
return 0;
}
+
+SBValueList
+SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
+{
+ SBValueList sb_value_list;
+ if (m_opaque_sp)
+ {
+ VariableList variable_list;
+ const uint32_t match_count = m_opaque_sp->FindGlobalVariables (ConstString (name),
+ false,
+ max_matches,
+ variable_list);
+
+ if (match_count > 0)
+ {
+ ValueObjectList &value_object_list = sb_value_list.ref();
+ for (uint32_t i=0; i<match_count; ++i)
+ {
+ lldb::ValueObjectSP valobj_sp;
+ if (target.IsValid())
+ valobj_sp = ValueObjectVariable::Create (target.get(), variable_list.GetVariableAtIndex(i));
+ else
+ valobj_sp = ValueObjectVariable::Create (NULL, variable_list.GetVariableAtIndex(i));
+ if (valobj_sp)
+ value_object_list.Append(valobj_sp);
+ }
+ }
+ }
+
+ return sb_value_list;
+}
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 7098604b0ef..6a17bb4cc69 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -11,8 +11,12 @@
#include "lldb/lldb-public.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBListener.h"
#include "lldb/API/SBModule.h"
+#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBSymbolContextList.h"
#include "lldb/Breakpoint/BreakpointID.h"
@@ -22,16 +26,19 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressResolver.h"
#include "lldb/Core/AddressResolverName.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Core/STLUtils.h"
+#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
@@ -39,10 +46,6 @@
#include "lldb/Interpreter/CommandReturnObject.h"
#include "../source/Commands/CommandObjectBreakpoint.h"
-#include "lldb/API/SBDebugger.h"
-#include "lldb/API/SBProcess.h"
-#include "lldb/API/SBListener.h"
-#include "lldb/API/SBBreakpoint.h"
using namespace lldb;
using namespace lldb_private;
@@ -872,3 +875,35 @@ SBTarget::FindFunctions (const char *name,
return 0;
}
+SBValueList
+SBTarget::FindGlobalVariables (const char *name, uint32_t max_matches)
+{
+ SBValueList sb_value_list;
+
+ if (m_opaque_sp)
+ {
+ VariableList variable_list;
+ const bool append = true;
+ const uint32_t match_count = m_opaque_sp->GetImages().FindGlobalVariables (ConstString (name),
+ append,
+ max_matches,
+ variable_list);
+
+ if (match_count > 0)
+ {
+ ExecutionContextScope *exe_scope = m_opaque_sp->GetProcessSP().get();
+ if (exe_scope == NULL)
+ exe_scope = m_opaque_sp.get();
+ ValueObjectList &value_object_list = sb_value_list.ref();
+ for (uint32_t i=0; i<match_count; ++i)
+ {
+ lldb::ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_scope, variable_list.GetVariableAtIndex(i)));
+ if (valobj_sp)
+ value_object_list.Append(valobj_sp);
+ }
+ }
+ }
+
+ return sb_value_list;
+}
+
diff --git a/lldb/source/API/SBValueList.cpp b/lldb/source/API/SBValueList.cpp
index bcddedfaf83..4e0fea5688c 100644
--- a/lldb/source/API/SBValueList.cpp
+++ b/lldb/source/API/SBValueList.cpp
@@ -25,10 +25,10 @@ SBValueList::SBValueList () :
SBValueList::SBValueList (const SBValueList &rhs) :
m_opaque_ap ()
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (rhs.IsValid())
- m_opaque_ap.reset (new lldb_private::ValueObjectList (*rhs));
+ m_opaque_ap.reset (new ValueObjectList (*rhs));
if (log)
{
@@ -38,13 +38,13 @@ SBValueList::SBValueList (const SBValueList &rhs) :
}
}
-SBValueList::SBValueList (const lldb_private::ValueObjectList *lldb_object_ptr) :
+SBValueList::SBValueList (const ValueObjectList *lldb_object_ptr) :
m_opaque_ap ()
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (lldb_object_ptr)
- m_opaque_ap.reset (new lldb_private::ValueObjectList (*lldb_object_ptr));
+ m_opaque_ap.reset (new ValueObjectList (*lldb_object_ptr));
if (log)
{
@@ -70,32 +70,32 @@ SBValueList::operator = (const SBValueList &rhs)
if (this != &rhs)
{
if (rhs.IsValid())
- m_opaque_ap.reset (new lldb_private::ValueObjectList (*rhs));
+ m_opaque_ap.reset (new ValueObjectList (*rhs));
else
m_opaque_ap.reset ();
}
return *this;
}
-lldb_private::ValueObjectList *
+ValueObjectList *
SBValueList::operator->()
{
return m_opaque_ap.get();
}
-lldb_private::ValueObjectList &
+ValueObjectList &
SBValueList::operator*()
{
return *m_opaque_ap;
}
-const lldb_private::ValueObjectList *
+const ValueObjectList *
SBValueList::operator->() const
{
return m_opaque_ap.get();
}
-const lldb_private::ValueObjectList &
+const ValueObjectList &
SBValueList::operator*() const
{
return *m_opaque_ap;
@@ -121,11 +121,21 @@ SBValueList::Append (lldb::ValueObjectSP& val_obj_sp)
}
}
+void
+SBValueList::Append (const lldb::SBValueList& value_list)
+{
+ if (value_list.IsValid())
+ {
+ CreateIfNeeded ();
+ m_opaque_ap->Append (*value_list);
+ }
+}
+
SBValue
SBValueList::GetValueAtIndex (uint32_t idx) const
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
//if (log)
// log->Printf ("SBValueList::GetValueAtIndex (uint32_t idx) idx = %d", idx);
@@ -148,7 +158,7 @@ SBValueList::GetValueAtIndex (uint32_t idx) const
uint32_t
SBValueList::GetSize () const
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
//if (log)
// log->Printf ("SBValueList::GetSize ()");
@@ -180,9 +190,17 @@ SBValueList::FindValueObjectByUID (lldb::user_id_t uid)
return sb_value;
}
-lldb_private::ValueObjectList *
+ValueObjectList *
SBValueList::get ()
{
return m_opaque_ap.get();
}
+ValueObjectList &
+SBValueList::ref ()
+{
+ CreateIfNeeded();
+ return *m_opaque_ap.get();
+}
+
+
diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp
index 2d8ac9147ce..2ba490ebb0a 100644
--- a/lldb/source/Core/Value.cpp
+++ b/lldb/source/Core/Value.cpp
@@ -516,6 +516,7 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
Error error;
lldb::addr_t address = LLDB_INVALID_ADDRESS;
AddressType address_type = eAddressTypeFile;
+ Address file_so_addr;
switch (m_value_type)
{
default:
@@ -541,11 +542,11 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
case eValueTypeLoadAddress:
if (exe_ctx == NULL)
{
- error.SetErrorString ("can't read memory (no execution context)");
+ error.SetErrorString ("can't read load address (no execution context)");
}
else if (exe_ctx->process == NULL)
{
- error.SetErrorString ("can't read memory (invalid process)");
+ error.SetErrorString ("can't read load address (invalid process)");
}
else
{
@@ -557,6 +558,15 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
break;
case eValueTypeFileAddress:
+ if (exe_ctx == NULL)
+ {
+ error.SetErrorString ("can't read file address (no execution context)");
+ }
+ else if (exe_ctx->target == NULL)
+ {
+ error.SetErrorString ("can't read file address (invalid target)");
+ }
+ else
{
// The only thing we can currently lock down to a module so that
// we can resolve a file address, is a variable.
@@ -564,9 +574,10 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
if (GetVariable())
{
- lldb::addr_t file_addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
- if (file_addr != LLDB_INVALID_ADDRESS)
+ address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ if (address != LLDB_INVALID_ADDRESS)
{
+ bool resolved = false;
SymbolContext var_sc;
variable->CalculateSymbolContext(&var_sc);
if (var_sc.module_sp)
@@ -574,31 +585,46 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
if (objfile)
{
- Address so_addr(file_addr, objfile->GetSectionList());
- address = so_addr.GetLoadAddress (exe_ctx->target);
- if (address != LLDB_INVALID_ADDRESS)
+ Address so_addr(address, objfile->GetSectionList());
+ addr_t load_address = so_addr.GetLoadAddress (exe_ctx->target);
+ if (load_address != LLDB_INVALID_ADDRESS)
{
+ resolved = true;
+ address = load_address;
address_type = eAddressTypeLoad;
data.SetByteOrder(exe_ctx->target->GetArchitecture().GetByteOrder());
data.SetAddressByteSize(exe_ctx->target->GetArchitecture().GetAddressByteSize());
}
else
{
- data.SetByteOrder(objfile->GetByteOrder());
- data.SetAddressByteSize(objfile->GetAddressByteSize());
+ if (so_addr.IsSectionOffset())
+ {
+ resolved = true;
+ file_so_addr = so_addr;
+ data.SetByteOrder(objfile->GetByteOrder());
+ data.SetAddressByteSize(objfile->GetAddressByteSize());
+ }
}
}
- if (address_type == eAddressTypeFile)
- error.SetErrorStringWithFormat ("%s is not loaded.\n", var_sc.module_sp->GetFileSpec().GetFilename().AsCString());
}
- else
+ if (!resolved)
{
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'", file_addr, variable->GetName().AsCString(""));
+ if (var_sc.module_sp)
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s' in %s%s%s",
+ address,
+ variable->GetName().AsCString(""),
+ var_sc.module_sp->GetFileSpec().GetDirectory().GetCString(),
+ var_sc.module_sp->GetFileSpec().GetDirectory() ? "/" : "",
+ var_sc.module_sp->GetFileSpec().GetFilename().GetCString());
+ else
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'",
+ address,
+ variable->GetName().AsCString(""));
}
}
else
{
- error.SetErrorString ("Invalid file address.");
+ error.SetErrorString ("invalid file address");
}
}
else
@@ -651,14 +677,28 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
// The address is an address in this process, so just copy it
memcpy (dst, (uint8_t*)NULL + address, byte_size);
}
- else if (address_type == eAddressTypeLoad)
+ else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile))
{
- if (exe_ctx->process->ReadMemory(address, dst, byte_size, error) != byte_size)
+ if (file_so_addr.IsValid())
{
- if (error.Success())
- error.SetErrorStringWithFormat("read %u bytes of memory from 0x%llx failed", (uint64_t)address, byte_size);
- else
+ // We have a file address that we were able to translate into a
+ // section offset address so we might be able to read this from
+ // the object files if we don't have a live process. Lets always
+ // try and read from the process if we have one though since we
+ // want to read the actual value by setting "prefer_file_cache"
+ // to false.
+ const bool prefer_file_cache = false;
+ if (exe_ctx->target->ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size)
+ {
+ error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address);
+ }
+ }
+ else
+ {
+ if (exe_ctx->process->ReadMemory(address, dst, byte_size, error) != byte_size)
+ {
error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address);
+ }
}
}
else
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 6471972ad99..c4bfc3c126c 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -285,21 +285,21 @@ ValueObjectSP
ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
{
ValueObjectSP child_sp;
- if (UpdateValueIfNeeded())
+ // We may need to update our value if we are dynamic
+ if (IsPossibleDynamicType ())
+ UpdateValueIfNeeded();
+ if (idx < GetNumChildren())
{
- if (idx < GetNumChildren())
+ // Check if we have already made the child value object?
+ if (can_create && m_children[idx] == NULL)
{
- // Check if we have already made the child value object?
- if (can_create && m_children[idx] == NULL)
- {
- // No we haven't created the child at this index, so lets have our
- // subclass do it and cache the result for quick future access.
- m_children[idx] = CreateChildAtIndex (idx, false, 0);
- }
-
- if (m_children[idx] != NULL)
- return m_children[idx]->GetSP();
+ // No we haven't created the child at this index, so lets have our
+ // subclass do it and cache the result for quick future access.
+ m_children[idx] = CreateChildAtIndex (idx, false, 0);
}
+
+ if (m_children[idx] != NULL)
+ return m_children[idx]->GetSP();
}
return child_sp;
}
@@ -322,36 +322,37 @@ ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
// need a vector of indexes that can get us down to the correct child
ValueObjectSP child_sp;
- if (UpdateValueIfNeeded())
+ // We may need to update our value if we are dynamic
+ if (IsPossibleDynamicType ())
+ UpdateValueIfNeeded();
+
+ std::vector<uint32_t> child_indexes;
+ clang::ASTContext *clang_ast = GetClangAST();
+ void *clang_type = GetClangType();
+ bool omit_empty_base_classes = true;
+ const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
+ clang_type,
+ name.GetCString(),
+ omit_empty_base_classes,
+ child_indexes);
+ if (num_child_indexes > 0)
{
- std::vector<uint32_t> child_indexes;
- clang::ASTContext *clang_ast = GetClangAST();
- void *clang_type = GetClangType();
- bool omit_empty_base_classes = true;
- const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
- clang_type,
- name.GetCString(),
- omit_empty_base_classes,
- child_indexes);
- if (num_child_indexes > 0)
- {
- std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
- std::vector<uint32_t>::const_iterator end = child_indexes.end ();
+ std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
+ std::vector<uint32_t>::const_iterator end = child_indexes.end ();
- child_sp = GetChildAtIndex(*pos, can_create);
- for (++pos; pos != end; ++pos)
+ child_sp = GetChildAtIndex(*pos, can_create);
+ for (++pos; pos != end; ++pos)
+ {
+ if (child_sp)
{
- if (child_sp)
- {
- ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
- child_sp = new_child_sp;
- }
- else
- {
- child_sp.reset();
- }
-
+ ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
+ child_sp = new_child_sp;
}
+ else
+ {
+ child_sp.reset();
+ }
+
}
}
return child_sp;
@@ -391,62 +392,59 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3
{
ValueObject *valobj = NULL;
- if (UpdateValueIfNeeded())
- {
- bool omit_empty_base_classes = true;
-
- 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 = GetClangAST();
- clang_type_t clang_type = GetClangType();
- clang_type_t child_clang_type;
-
- ExecutionContext exe_ctx;
- GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
-
- child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
- clang_ast,
- GetName().GetCString(),
- clang_type,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- 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());
+ bool omit_empty_base_classes = true;
- valobj = new ValueObjectChild (*this,
- 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);
- if (m_pointers_point_to_load_addrs)
- valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
- }
+ 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 = GetClangAST();
+ clang_type_t clang_type = GetClangType();
+ clang_type_t child_clang_type;
+
+ ExecutionContext exe_ctx;
+ GetExecutionContextScope()->CalculateExecutionContext (exe_ctx);
+
+ child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
+ clang_ast,
+ GetName().GetCString(),
+ clang_type,
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ 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 ValueObjectChild (*this,
+ 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);
+ if (m_pointers_point_to_load_addrs)
+ valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs);
}
return valobj;
@@ -994,6 +992,12 @@ ValueObject::IsPossibleCPlusPlusDynamicType ()
return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
}
+bool
+ValueObject::IsPossibleDynamicType ()
+{
+ return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
+}
+
ValueObjectSP
ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
{
diff --git a/lldb/source/Core/ValueObjectList.cpp b/lldb/source/Core/ValueObjectList.cpp
index 8913d4da18d..f732a698ee5 100644
--- a/lldb/source/Core/ValueObjectList.cpp
+++ b/lldb/source/Core/ValueObjectList.cpp
@@ -51,6 +51,16 @@ ValueObjectList::Append (const ValueObjectSP &val_obj_sp)
m_value_objects.push_back(val_obj_sp);
}
+void
+ValueObjectList::Append (const ValueObjectList &valobj_list)
+{
+ std::copy(valobj_list.m_value_objects.begin(), // source begin
+ valobj_list.m_value_objects.end(), // source end
+ back_inserter(m_value_objects)); // destination
+
+}
+
+
uint32_t
ValueObjectList::GetSize() const
{
diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp
index e2a281b7f95..79692a023a8 100644
--- a/lldb/source/Core/ValueObjectVariable.cpp
+++ b/lldb/source/Core/ValueObjectVariable.cpp
@@ -169,7 +169,7 @@ ValueObjectVariable::UpdateValue ()
// Make sure this type has a value before we try and read it
// If we have a file address, convert it to a load address if we can.
- if (value_type == Value::eValueTypeFileAddress && exe_ctx.process)
+ if (value_type == Value::eValueTypeFileAddress && exe_ctx.process && exe_ctx.process->IsAlive())
{
lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
if (file_addr != LLDB_INVALID_ADDRESS)
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index b692ae507c5..fb55a51344f 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -4046,6 +4046,150 @@ ClangASTContext::GetPointerBitSize ()
}
bool
+ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
+{
+ QualType pointee_qual_type;
+ if (clang_type)
+ {
+ QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ bool success = false;
+ switch (type_class)
+ {
+ case clang::Type::Builtin:
+ if (cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId)
+ {
+ if (dynamic_pointee_type)
+ *dynamic_pointee_type = clang_type;
+ return true;
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (dynamic_pointee_type)
+ *dynamic_pointee_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
+ return true;
+
+ case clang::Type::Pointer:
+ pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
+ success = true;
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
+ success = true;
+ break;
+
+ case clang::Type::Typedef:
+ return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
+
+ default:
+ break;
+ }
+
+ if (success)
+ {
+ // Check to make sure what we are pointing too is a possible dynamic C++ type
+ // We currently accept any "void *" (in case we have a class that has been
+ // watered down to an opaque pointer) and virtual C++ classes.
+ const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
+ switch (pointee_type_class)
+ {
+ case clang::Type::Builtin:
+ switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
+ {
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::Void:
+ if (dynamic_pointee_type)
+ *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
+ return true;
+
+ case clang::BuiltinType::NullPtr:
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ case clang::BuiltinType::Dependent:
+ case clang::BuiltinType::Overload:
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCSel:
+ case clang::BuiltinType::BoundMember:
+ break;
+ }
+ break;
+
+ case clang::Type::Record:
+ {
+ CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ if (GetCompleteQualType (ast, pointee_qual_type))
+ {
+ success = cxx_record_decl->isDynamicClass();
+ }
+ else
+ {
+ // We failed to get the complete type, so we have to
+ // treat this as a void * which we might possibly be
+ // able to complete
+ success = true;
+ }
+ if (success)
+ {
+ if (dynamic_pointee_type)
+ *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
+ return true;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ {
+ const clang::ObjCObjectType *objc_class_type = pointee_qual_type->getAsObjCQualifiedInterfaceType();
+ if (objc_class_type)
+ {
+ GetCompleteQualType (ast, pointee_qual_type);
+ if (dynamic_pointee_type)
+ *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
+ return true;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ if (dynamic_pointee_type)
+ *dynamic_pointee_type = NULL;
+ return false;
+}
+
+
+bool
ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
{
QualType pointee_qual_type;
OpenPOWER on IntegriCloud