[Lldb-commits] [lldb] r134102 - in /lldb/trunk: include/lldb/API/SBDefines.h include/lldb/API/SBModule.h include/lldb/API/SBTarget.h include/lldb/API/SBValueList.h include/lldb/Core/ValueObject.h include/lldb/Core/ValueObjectList.h include/lldb/Symbol/ClangASTContext.h source/API/SBModule.cpp source/API/SBTarget.cpp source/API/SBValueList.cpp source/Core/Value.cpp source/Core/ValueObject.cpp source/Core/ValueObjectList.cpp source/Core/ValueObjectVariable.cpp source/Symbol/ClangASTContext.cpp

Greg Clayton gclayton at apple.com
Wed Jun 29 15:09:02 PDT 2011


Author: gclayton
Date: Wed Jun 29 17:09:02 2011
New Revision: 134102

URL: http://llvm.org/viewvc/llvm-project?rev=134102&view=rev
Log:
Added support for finding and global variables in the SBTarget and SBModule
level in the public API. 

Also modified the ValueObject values to be able to display global variables
without having a valid running process. The globals will read themselves from
the object file section data if there is no process, and from the process if
there is one.

Also fixed an issue where modifications for dynamic types could cause child
values of ValueObjects to not show up if the value was unable to evaluate
itself (children of NULL pointer objects).


Modified:
    lldb/trunk/include/lldb/API/SBDefines.h
    lldb/trunk/include/lldb/API/SBModule.h
    lldb/trunk/include/lldb/API/SBTarget.h
    lldb/trunk/include/lldb/API/SBValueList.h
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Core/ValueObjectList.h
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/source/API/SBModule.cpp
    lldb/trunk/source/API/SBTarget.cpp
    lldb/trunk/source/API/SBValueList.cpp
    lldb/trunk/source/Core/Value.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Core/ValueObjectList.cpp
    lldb/trunk/source/Core/ValueObjectVariable.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp

Modified: lldb/trunk/include/lldb/API/SBDefines.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDefines.h?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDefines.h (original)
+++ lldb/trunk/include/lldb/API/SBDefines.h Wed Jun 29 17:09:02 2011
@@ -57,6 +57,7 @@
 class SBTarget;
 class SBThread;
 class SBValue;
+class SBValueList;
 
 }
 

Modified: lldb/trunk/include/lldb/API/SBModule.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBModule.h?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBModule.h (original)
+++ lldb/trunk/include/lldb/API/SBModule.h Wed Jun 29 17:09:02 2011
@@ -12,6 +12,7 @@
 
 #include "lldb/API/SBDefines.h"
 #include "lldb/API/SBSymbolContext.h"
+#include "lldb/API/SBValueList.h"
 
 namespace lldb {
 
@@ -80,6 +81,12 @@
                    bool append, 
                    lldb::SBSymbolContextList& sc_list);
 
+    lldb::SBValueList
+    FindGlobalVariables (lldb::SBTarget &target, 
+                         const char *name, 
+                         uint32_t max_matches);
+    
+
 private:
     friend class SBAddress;
     friend class SBFrame;

Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Wed Jun 29 17:09:02 2011
@@ -189,6 +189,10 @@
                    bool append, 
                    lldb::SBSymbolContextList& sc_list);
 
+    lldb::SBValueList
+    FindGlobalVariables (const char *name, 
+                         uint32_t max_matches);
+
     void
     Clear ();
 
@@ -260,6 +264,7 @@
     friend class SBFunction;
     friend class SBProcess;
     friend class SBSymbol;
+    friend class SBModule;
 
     //------------------------------------------------------------------
     // Constructors are private, use static Target::Create function to

Modified: lldb/trunk/include/lldb/API/SBValueList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValueList.h?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBValueList.h (original)
+++ lldb/trunk/include/lldb/API/SBValueList.h Wed Jun 29 17:09:02 2011
@@ -30,6 +30,9 @@
     void
     Append (const lldb::SBValue &val_obj);
 
+    void
+    Append (const lldb::SBValueList& value_list);
+
     uint32_t
     GetSize() const;
 
@@ -58,7 +61,10 @@
     
     lldb_private::ValueObjectList *
     get ();
-    
+
+    lldb_private::ValueObjectList &
+    ref ();
+
 #endif
 
 private:

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Wed Jun 29 17:09:02 2011
@@ -239,6 +239,9 @@
     
     virtual bool
     IsPossibleCPlusPlusDynamicType ();
+    
+    virtual bool
+    IsPossibleDynamicType ();
 
     virtual bool
     IsBaseClass ()

Modified: lldb/trunk/include/lldb/Core/ValueObjectList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectList.h?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectList.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectList.h Wed Jun 29 17:09:02 2011
@@ -44,6 +44,9 @@
     void
     Append (const lldb::ValueObjectSP &val_obj_sp);
 
+    void
+    Append (const ValueObjectList &valobj_list);
+
     lldb::ValueObjectSP
     FindValueObjectByPointer (ValueObject *valobj);
 

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Wed Jun 29 17:09:02 2011
@@ -635,6 +635,11 @@
                                     lldb::clang_type_t *target_type = NULL);
 
     static bool
+    IsPossibleDynamicType (clang::ASTContext *ast, 
+                           lldb::clang_type_t clang_type, 
+                           lldb::clang_type_t *dynamic_pointee_type = NULL);
+
+    static bool
     IsCStringType (lldb::clang_type_t clang_type, uint32_t &length);
 
     static bool

Modified: lldb/trunk/source/API/SBModule.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBModule.cpp?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/source/API/SBModule.cpp (original)
+++ lldb/trunk/source/API/SBModule.cpp Wed Jun 29 17:09:02 2011
@@ -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 @@
     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;
+}

Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Wed Jun 29 17:09:02 2011
@@ -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 @@
     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;
+}
+

Modified: lldb/trunk/source/API/SBValueList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValueList.cpp?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/source/API/SBValueList.cpp (original)
+++ lldb/trunk/source/API/SBValueList.cpp Wed Jun 29 17:09:02 2011
@@ -25,10 +25,10 @@
 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 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 @@
     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 @@
     }
 }
 
+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 @@
 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 @@
     return sb_value;
 }
 
-lldb_private::ValueObjectList *
+ValueObjectList *
 SBValueList::get ()
 {
     return m_opaque_ap.get();
 }
 
+ValueObjectList &
+SBValueList::ref ()
+{
+    CreateIfNeeded();
+    return *m_opaque_ap.get();
+}
+
+

Modified: lldb/trunk/source/Core/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Value.cpp?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/source/Core/Value.cpp (original)
+++ lldb/trunk/source/Core/Value.cpp Wed Jun 29 17:09:02 2011
@@ -516,6 +516,7 @@
     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 @@
     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 @@
         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 @@
 
             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 @@
                         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 @@
             // 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

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Wed Jun 29 17:09:02 2011
@@ -285,21 +285,21 @@
 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 @@
     // need a vector of indexes that can get us down to the correct child
     ValueObjectSP child_sp;
 
-    if (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>::const_iterator pos = child_indexes.begin ();
-            std::vector<uint32_t>::const_iterator end = child_indexes.end ();
+    // 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>::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 *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 @@
     return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
 }
 
+bool
+ValueObject::IsPossibleDynamicType ()
+{
+    return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
+}
+
 ValueObjectSP
 ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
 {

Modified: lldb/trunk/source/Core/ValueObjectList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectList.cpp?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectList.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectList.cpp Wed Jun 29 17:09:02 2011
@@ -51,6 +51,16 @@
     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
 {

Modified: lldb/trunk/source/Core/ValueObjectVariable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectVariable.cpp?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectVariable.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectVariable.cpp Wed Jun 29 17:09:02 2011
@@ -169,7 +169,7 @@
                 // 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)

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=134102&r1=134101&r2=134102&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Wed Jun 29 17:09:02 2011
@@ -4046,6 +4046,150 @@
 }
 
 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;





More information about the lldb-commits mailing list