[Lldb-commits] [lldb] r120778 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h source/Expression/ClangASTSource.cpp source/Expression/ClangExpressionDeclMap.cpp source/Expression/ClangUserExpression.cpp source/Expression/ClangUtilityFunction.cpp

Sean Callanan scallanan at apple.com
Thu Dec 2 17:38:59 PST 2010


Author: spyffe
Date: Thu Dec  2 19:38:59 2010
New Revision: 120778

URL: http://llvm.org/viewvc/llvm-project?rev=120778&view=rev
Log:
Fixed object lifetimes in ClangExpressionDeclMap
so that it is not referring to potentially stale
state during IR execution.

This was done by introducing modular state (like
ClangExpressionVariable) where groups of state
variables have well-defined lifetimes:

- m_parser_vars are specific to parsing, and only
  exist between calls to WillParse() and DidParse().

- m_struct_vars survive for the entire execution
  of the ClangExpressionDeclMap because they
  provide the template for a materialized set of
  expression variables.

- m_material_vars are specific to a single
  instance of materialization, and only exist
  between calls to Materialize() and
  Dematerialize().

I also removed unnecessary references to long-
lived state that really didn't need to be referred
to at all, and also introduced several assert()s
that helped me diagnose a few bugs (fixed too).

Modified:
    lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
    lldb/trunk/source/Expression/ClangASTSource.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Expression/ClangUtilityFunction.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=120778&r1=120777&r2=120778&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Thu Dec  2 19:38:59 2010
@@ -71,17 +71,27 @@
     /// Constructor
     ///
     /// Initializes class variabes.
+    //------------------------------------------------------------------
+    ClangExpressionDeclMap();
+    
+    //------------------------------------------------------------------
+    /// Destructor
+    //------------------------------------------------------------------
+    ~ClangExpressionDeclMap();
+    
+    //------------------------------------------------------------------
+    /// Enable the state needed for parsing and IR transformation.
     ///
     /// @param[in] exe_ctx
     ///     The execution context to use when finding types for variables.
     ///     Also used to find a "scratch" AST context to store result types.
     //------------------------------------------------------------------
-    ClangExpressionDeclMap(ExecutionContext *exe_ctx);
+    void WillParse(ExecutionContext &exe_ctx);
     
     //------------------------------------------------------------------
-    /// Destructor
+    /// Disable the state needed for parsing and IR transformation.
     //------------------------------------------------------------------
-    ~ClangExpressionDeclMap();
+    void DidParse();
     
     //------------------------------------------------------------------
     /// [Used by IRForTarget] Get a new result variable name of the form
@@ -270,7 +280,7 @@
     /// @return
     ///     True on success; false otherwise.
     //------------------------------------------------------------------
-    bool Materialize(ExecutionContext *exe_ctx,
+    bool Materialize(ExecutionContext &exe_ctx,
                      lldb::addr_t &struct_address,
                      Error &error);
     
@@ -292,7 +302,7 @@
     ///     True on success; false otherwise.
     //------------------------------------------------------------------
     bool GetObjectPointer(lldb::addr_t &object_ptr,
-                          ExecutionContext *exe_ctx,
+                          ExecutionContext &exe_ctx,
                           Error &error);
     
     //------------------------------------------------------------------
@@ -313,7 +323,7 @@
     /// @return
     ///     True on success; false otherwise.
     //------------------------------------------------------------------
-    bool DumpMaterializedStruct(ExecutionContext *exe_ctx,
+    bool DumpMaterializedStruct(ExecutionContext &exe_ctx,
                                 Stream &s,
                                 Error &error);
     
@@ -334,7 +344,7 @@
     /// @return
     ///     True on success; false otherwise.
     //------------------------------------------------------------------
-    bool Dematerialize(ExecutionContext *exe_ctx,
+    bool Dematerialize(ExecutionContext &exe_ctx,
                        ClangExpressionVariable *&result,
                        Error &error);
     
@@ -356,37 +366,153 @@
     //------------------------------------------------------------------
     void GetDecls (NameSearchContext &context,
                    const ConstString &name);
-                   
+    
+    //------------------------------------------------------------------
+    /// [Used by ClangASTSource] Report whether a $__lldb variable has
+    /// been searched for yet.  This is the trigger for beginning to 
+    /// actually look for externally-defined names.  (Names that come
+    /// before this are typically the names of built-ins that don't need
+    /// to be looked up.)
+    ///
+    /// @return
+    ///     True if a $__lldb variable has been found.
+    //------------------------------------------------------------------
     bool
     GetLookupsEnabled ()
     {
-        return m_enable_lookups;
+        assert(m_parser_vars.get());
+        return m_parser_vars->m_enable_lookups;
     }
     
+    //------------------------------------------------------------------
+    /// [Used by ClangASTSource] Indicate that a $__lldb variable has
+    /// been found.
+    //------------------------------------------------------------------
     void
-    SetLookupsEnabled (bool b)
+    SetLookupsEnabled ()
     {
-        m_enable_lookups = b;
+        assert(m_parser_vars.get());
+        m_parser_vars->m_enable_lookups = true;
     }
 
 private:
-    ClangExpressionVariableStore    m_found_entities;       ///< All entities that were looked up for the parser.
-    ClangExpressionVariableList     m_struct_members;       ///< All entities that need to be placed in the struct.
+    ClangExpressionVariableStore    m_found_entities;           ///< All entities that were looked up for the parser.
+    ClangExpressionVariableList     m_struct_members;           ///< All entities that need to be placed in the struct.
     
-    ExecutionContext            m_exe_ctx;                  ///< The execution context where this expression was first defined.  It determines types for all the external variables, even if the expression is re-used.
-    SymbolContext               m_sym_ctx;                  ///< [owned by ClangExpressionDeclMap] The symbol context where this expression was first defined.
-    ClangPersistentVariables   *m_persistent_vars;          ///< The list of persistent variables to use when resolving symbols in the expression and when creating new ones (like the result).
-    off_t                       m_struct_alignment;         ///< The alignment of the struct in bytes.
-    size_t                      m_struct_size;              ///< The size of the struct in bytes.
-    bool                        m_struct_laid_out;          ///< True if the struct has been laid out and the layout is valid (that is, no new fields have been added since).
-    bool                        m_enable_lookups;           ///< Set to true during expression evaluation if we have found the first "$__lldb" name.
-    lldb::addr_t                m_allocated_area;           ///< The base of the memory allocated for the struct.  Starts on a potentially unaligned address and may therefore be larger than the struct.
-    lldb::addr_t                m_materialized_location;    ///< The address at which the struct is placed.  Falls inside the allocated area.
-    ConstString                 m_result_name;              ///< The name of the result variable ($1, for example)
-    TypeFromUser                m_object_pointer_type;      ///< The type of the "this" variable, if one exists.
+    //----------------------------------------------------------------------
+    /// The following values should not live beyond parsing
+    //----------------------------------------------------------------------
+    struct ParserVars {
+        ParserVars() :
+            m_exe_ctx(NULL),
+            m_sym_ctx(),
+            m_persistent_vars(NULL),
+            m_enable_lookups(false),
+            m_ignore_lookups(false)
+        {
+        }
+        
+        ExecutionContext           *m_exe_ctx;          ///< The execution context to use when parsing.
+        SymbolContext               m_sym_ctx;          ///< The symbol context to use in finding variables and types.
+        ClangPersistentVariables   *m_persistent_vars;  ///< The persistent variables for the process.
+        bool                        m_enable_lookups;   ///< Set to true during parsing if we have found the first "$__lldb" name.
+        bool                        m_ignore_lookups;   ///< True during an import when we should be ignoring type lookups.
+    };
+    
+    std::auto_ptr<ParserVars> m_parser_vars;
+    
+    //----------------------------------------------------------------------
+    /// Activate parser-specific variables
+    //----------------------------------------------------------------------
+    void EnableParserVars()
+    {
+        if (!m_parser_vars.get())
+            m_parser_vars.reset(new struct ParserVars);
+    }
+    
+    //----------------------------------------------------------------------
+    /// Deallocate parser-specific variables
+    //----------------------------------------------------------------------
+    void DisableParserVars()
+    {
+        m_parser_vars.reset();
+    }
+    
+    //----------------------------------------------------------------------
+    /// The following values contain layout information for the materialized
+    /// struct, but are not specific to a single materialization
+    //----------------------------------------------------------------------
+    struct StructVars {
+        StructVars() :
+            m_struct_alignment(0),
+            m_struct_size(0),
+            m_struct_laid_out(false),
+            m_result_name(),
+            m_object_pointer_type(NULL, NULL)
+        {
+        }
+        
+        off_t                       m_struct_alignment;         ///< The alignment of the struct in bytes.
+        size_t                      m_struct_size;              ///< The size of the struct in bytes.
+        bool                        m_struct_laid_out;          ///< True if the struct has been laid out and the layout is valid (that is, no new fields have been added since).
+        ConstString                 m_result_name;              ///< The name of the result variable ($1, for example)
+        TypeFromUser                m_object_pointer_type;      ///< The type of the "this" variable, if one exists
+    };
+    
+    std::auto_ptr<StructVars> m_struct_vars;
+    
+    //----------------------------------------------------------------------
+    /// Activate struct variables
+    //----------------------------------------------------------------------
+    void EnableStructVars()
+    {
+        if (!m_struct_vars.get())
+            m_struct_vars.reset(new struct StructVars);
+    }
+    
+    //----------------------------------------------------------------------
+    /// Deallocate struct variables
+    //----------------------------------------------------------------------
+    void DisableStructVars()
+    {
+        m_struct_vars.reset();
+    }
+    
+    //----------------------------------------------------------------------
+    /// The following values refer to a specific materialization of the
+    /// structure in a process
+    //----------------------------------------------------------------------
+    struct MaterialVars {
+        MaterialVars() :
+            m_allocated_area(NULL),
+            m_materialized_location(NULL)
+        {
+        }
+        
+        Process                    *m_process;                  ///< The process that the struct is materialized into.
+        lldb::addr_t                m_allocated_area;           ///< The base of the memory allocated for the struct.  Starts on a potentially unaligned address and may therefore be larger than the struct.
+        lldb::addr_t                m_materialized_location;    ///< The address at which the struct is placed.  Falls inside the allocated area.
+    };
+    
+    std::auto_ptr<MaterialVars> m_material_vars;
+    
+    //----------------------------------------------------------------------
+    /// Activate materialization-specific variables
+    //----------------------------------------------------------------------
+    void EnableMaterialVars()
+    {
+        if (!m_material_vars.get())
+            m_material_vars.reset(new struct MaterialVars);
+    }
+    
+    //----------------------------------------------------------------------
+    /// Deallocate materialization-specific variables
+    //----------------------------------------------------------------------
+    void DisableMaterialVars()
+    {
+        m_material_vars.reset();
+    }
     
-    bool                        m_ignore_lookups;           ///< True during an import when we should be ignoring type lookups.
-      
     //------------------------------------------------------------------
     /// Given a stack frame, find a variable that matches the given name and 
     /// type.  We need this for expression re-use; we may not always get the
@@ -544,9 +670,14 @@
     ///     True on success; false otherwise.
     //------------------------------------------------------------------
     bool DoMaterialize (bool dematerialize,
-                        ExecutionContext *exe_ctx,
+                        ExecutionContext &exe_ctx,
                         ClangExpressionVariable **result,
                         Error &err);
+    
+    //------------------------------------------------------------------
+    /// Clean up the state required to dematerialize the variable.
+    //------------------------------------------------------------------
+    void DidDematerialize ();
 
     //------------------------------------------------------------------
     /// Actually do the task of materializing or dematerializing a persistent

Modified: lldb/trunk/source/Expression/ClangASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangASTSource.cpp?rev=120778&r1=120777&r2=120778&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Expression/ClangASTSource.cpp Thu Dec  2 19:38:59 2010
@@ -83,7 +83,7 @@
         // any lookups so we can avoid lookup up all of the builtin types.
         if (!decl_name.empty() && decl_name[0] == '$')
         {
-            m_decl_map.SetLookupsEnabled (true);
+            m_decl_map.SetLookupsEnabled ();
         }
         else
         {               

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=120778&r1=120777&r2=120778&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Thu Dec  2 19:38:59 2010
@@ -43,62 +43,58 @@
 using namespace lldb_private;
 using namespace clang;
 
-ClangExpressionDeclMap::ClangExpressionDeclMap (ExecutionContext *exe_ctx) :
+ClangExpressionDeclMap::ClangExpressionDeclMap () :
     m_found_entities (),
     m_struct_members (),
-    m_exe_ctx (),
-    m_sym_ctx (),
-    m_persistent_vars (NULL),
-    m_struct_alignment (0),
-    m_struct_size (0),
-    m_struct_laid_out (false),
-    m_enable_lookups (false),
-    m_allocated_area (0),
-    m_materialized_location (0),
-    m_result_name (),
-    m_object_pointer_type (),
-    m_ignore_lookups (false)
-{
-    if (exe_ctx)
-    {
-        m_exe_ctx = *exe_ctx;
-        if (exe_ctx->frame)
-            m_sym_ctx = exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything);
-        if (exe_ctx->process)
-            m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
-    }
+    m_parser_vars (),
+    m_struct_vars ()
+{
+    EnableStructVars();
 }
 
 ClangExpressionDeclMap::~ClangExpressionDeclMap()
+{
+    DidDematerialize();
+    DisableStructVars();
+}
+
+void ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx)
 {    
-    for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
-         entity_index < num_entities;
-         ++entity_index)
-    {
-        ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
-        if (entity.m_parser_vars.get() &&
-            entity.m_parser_vars->m_lldb_value)
-            delete entity.m_parser_vars->m_lldb_value;
-        
-        entity.DisableParserVars();
-    }
+    EnableParserVars();
+    m_parser_vars->m_exe_ctx = &exe_ctx;
     
-    for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size();
-         pvar_index < num_pvars;
-         ++pvar_index)
-    {
-        ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index));
-        pvar.DisableParserVars();
-    }
+    if (exe_ctx.frame)
+        m_parser_vars->m_sym_ctx = exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything);
     
-    if (m_materialized_location)
-    {        
-//#define SINGLE_STEP_EXPRESSIONS
+    if (exe_ctx.process)
+        m_parser_vars->m_persistent_vars = &exe_ctx.process->GetPersistentVariables();
+}
 
-#ifndef SINGLE_STEP_EXPRESSIONS
-        m_exe_ctx.process->DeallocateMemory(m_materialized_location);
-#endif
-        m_materialized_location = 0;
+void ClangExpressionDeclMap::DidParse()
+{
+    if (m_parser_vars.get())
+    {
+        for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
+             entity_index < num_entities;
+             ++entity_index)
+        {
+            ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
+            if (entity.m_parser_vars.get() &&
+                entity.m_parser_vars->m_lldb_value)
+                delete entity.m_parser_vars->m_lldb_value;
+            
+            entity.DisableParserVars();
+        }
+        
+        for (uint64_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->Size();
+             pvar_index < num_pvars;
+             ++pvar_index)
+        {
+            ClangExpressionVariable &pvar(m_parser_vars->m_persistent_vars->VariableAtIndex(pvar_index));
+            pvar.DisableParserVars();
+        }
+        
+        DisableParserVars();
     }
 }
 
@@ -107,9 +103,13 @@
 const ConstString &
 ClangExpressionDeclMap::GetPersistentResultName ()
 {
-    if (!m_result_name)
-        m_persistent_vars->GetNextResultName(m_result_name);    
-    return m_result_name;
+    assert (m_struct_vars.get());
+    assert (m_parser_vars.get());
+    
+    if (!m_struct_vars->m_result_name)
+        m_parser_vars->m_persistent_vars->GetNextResultName(m_struct_vars->m_result_name);
+    
+    return m_struct_vars->m_result_name;
 }
 
 bool 
@@ -120,17 +120,19 @@
     TypeFromParser parser_type
 )
 {
-    clang::ASTContext *context(m_exe_ctx.target->GetScratchClangASTContext()->getASTContext());
+    assert (m_parser_vars.get());
+    
+    clang::ASTContext *context(m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
     
     TypeFromUser user_type(ClangASTContext::CopyType(context, 
                                                      parser_type.GetASTContext(),
                                                      parser_type.GetOpaqueQualType()),
                             context);
     
-    if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
+    if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (name, user_type))
         return false;
     
-    ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
+    ClangExpressionVariable *var = m_parser_vars->m_persistent_vars->GetVariable(name);
     
     if (!var)
         return false;
@@ -153,9 +155,12 @@
     off_t alignment
 )
 {
+    assert (m_struct_vars.get());
+    assert (m_parser_vars.get());
+    
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
-    m_struct_laid_out = false;
+    m_struct_vars->m_struct_laid_out = false;
     
     if (m_struct_members.GetVariable(decl))
         return true;
@@ -163,7 +168,7 @@
     ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
     
     if (!var)
-        var = m_persistent_vars->GetVariable(decl);
+        var = m_parser_vars->m_persistent_vars->GetVariable(decl);
     
     if (!var)
         return false;
@@ -190,13 +195,15 @@
 bool
 ClangExpressionDeclMap::DoStructLayout ()
 {
-    if (m_struct_laid_out)
+    assert (m_struct_vars.get());
+    
+    if (m_struct_vars->m_struct_laid_out)
         return true;
     
     off_t cursor = 0;
     
-    m_struct_alignment = 0;
-    m_struct_size = 0;
+    m_struct_vars->m_struct_alignment = 0;
+    m_struct_vars->m_struct_size = 0;
     
     for (uint64_t member_index = 0, num_members = m_struct_members.Size();
          member_index < num_members;
@@ -208,7 +215,7 @@
             return false;
         
         if (member_index == 0)
-            m_struct_alignment = member.m_jit_vars->m_alignment;
+            m_struct_vars->m_struct_alignment = member.m_jit_vars->m_alignment;
         
         if (cursor % member.m_jit_vars->m_alignment)
             cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
@@ -217,9 +224,9 @@
         cursor += member.m_jit_vars->m_size;
     }
     
-    m_struct_size = cursor;
+    m_struct_vars->m_struct_size = cursor;
     
-    m_struct_laid_out = true;
+    m_struct_vars->m_struct_laid_out = true;
     return true;
 }
 
@@ -230,12 +237,14 @@
     off_t &alignment
 )
 {
-    if (!m_struct_laid_out)
+    assert (m_struct_vars.get());
+    
+    if (!m_struct_vars->m_struct_laid_out)
         return false;
     
     num_elements = m_struct_members.Size();
-    size = m_struct_size;
-    alignment = m_struct_alignment;
+    size = m_struct_vars->m_struct_size;
+    alignment = m_struct_vars->m_struct_alignment;
     
     return true;
 }
@@ -250,7 +259,9 @@
     uint32_t index
 )
 {
-    if (!m_struct_laid_out)
+    assert (m_struct_vars.get());
+    
+    if (!m_struct_vars->m_struct_laid_out)
         return false;
     
     if (index >= m_struct_members.Size())
@@ -299,13 +310,15 @@
     uint64_t &ptr
 )
 {
+    assert (m_parser_vars.get());
+    
     // Back out in all cases where we're not fully initialized
-    if (m_exe_ctx.frame == NULL)
+    if (m_parser_vars->m_exe_ctx->frame == NULL)
         return false;
 
     SymbolContextList sc_list;
     
-    m_sym_ctx.FindFunctionsByName(name, false, sc_list);
+    m_parser_vars->m_sym_ctx.FindFunctionsByName(name, false, sc_list);
     
     if (!sc_list.GetSize())
         return false;
@@ -322,7 +335,7 @@
     else
         return false;
     
-    ptr = fun_address->GetLoadAddress (m_exe_ctx.target);
+    ptr = fun_address->GetLoadAddress (m_parser_vars->m_exe_ctx->target);
     
     return true;
 }
@@ -332,15 +345,19 @@
 bool 
 ClangExpressionDeclMap::Materialize 
 (
-    ExecutionContext *exe_ctx, 
+    ExecutionContext &exe_ctx, 
     lldb::addr_t &struct_address,
     Error &err
 )
 {
+    EnableMaterialVars();
+    
+    m_material_vars->m_process = exe_ctx.process;
+    
     bool result = DoMaterialize(false, exe_ctx, NULL, err);
     
     if (result)
-        struct_address = m_materialized_location;
+        struct_address = m_material_vars->m_materialized_location;
     
     return result;
 }
@@ -349,24 +366,26 @@
 ClangExpressionDeclMap::GetObjectPointer
 (
     lldb::addr_t &object_ptr,
-    ExecutionContext *exe_ctx,
+    ExecutionContext &exe_ctx,
     Error &err
 )
 {
-    if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process)
+    assert (m_struct_vars.get());
+    
+    if (!exe_ctx.frame || !exe_ctx.target || !exe_ctx.process)
     {
         err.SetErrorString("Couldn't load 'this' because the context is incomplete");
         return false;
     }
     
-    if (!m_object_pointer_type.GetOpaqueQualType())
+    if (!m_struct_vars->m_object_pointer_type.GetOpaqueQualType())
     {
         err.SetErrorString("Couldn't load 'this' because its type is unknown");
         return false;
     }
     
     static ConstString g_this_const_str ("this");
-    Variable *object_ptr_var = FindVariableInScope (*exe_ctx->frame, g_this_const_str, &m_object_pointer_type);
+    Variable *object_ptr_var = FindVariableInScope (*exe_ctx.frame, g_this_const_str, &m_struct_vars->m_object_pointer_type);
     
     if (!object_ptr_var)
     {
@@ -374,9 +393,9 @@
         return false;
     }
     
-    std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx,
+    std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
                                                                        object_ptr_var,
-                                                                       m_object_pointer_type.GetASTContext()));
+                                                                       NULL));
     
     if (!location_value.get())
     {
@@ -387,10 +406,11 @@
     if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
     {
         lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
-        uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize();
-        lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder();
+        uint32_t address_byte_size = exe_ctx.target->GetArchitecture().GetAddressByteSize();
+        lldb::ByteOrder address_byte_order = exe_ctx.process->GetByteOrder();
         
-        if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
+        if (ClangASTType::GetClangTypeBitWidth(m_struct_vars->m_object_pointer_type.GetASTContext(), 
+                                               m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
         {
             err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
             return false;
@@ -400,7 +420,7 @@
         data.SetByteSize(address_byte_size);
         Error read_error;
         
-        if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
+        if (exe_ctx.process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
         {
             err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
             return false;
@@ -424,57 +444,74 @@
 bool 
 ClangExpressionDeclMap::Dematerialize 
 (
-    ExecutionContext *exe_ctx,
+    ExecutionContext &exe_ctx,
     ClangExpressionVariable *&result,
     Error &err
 )
 {
     return DoMaterialize(true, exe_ctx, &result, err);
+    
+    DidDematerialize();
+}
+
+void
+ClangExpressionDeclMap::DidDematerialize()
+{
+    if (m_material_vars.get())
+    {
+        if (m_material_vars->m_materialized_location)
+        {        
+            //#define SINGLE_STEP_EXPRESSIONS
+            
+#ifndef SINGLE_STEP_EXPRESSIONS
+            m_material_vars->m_process->DeallocateMemory(m_material_vars->m_materialized_location);
+#endif
+            m_material_vars->m_materialized_location = 0;
+        }
+        
+        DisableMaterialVars();
+    }
 }
 
 bool
 ClangExpressionDeclMap::DumpMaterializedStruct
 (
-    ExecutionContext *exe_ctx, 
+    ExecutionContext &exe_ctx, 
     Stream &s,
     Error &err
 )
 {
-    if (!m_struct_laid_out)
+    assert (m_struct_vars.get());
+    assert (m_material_vars.get());
+    
+    if (!m_struct_vars->m_struct_laid_out)
     {
         err.SetErrorString("Structure hasn't been laid out yet");
         return false;
     }
     
-    if (!exe_ctx)
-    {
-        err.SetErrorString("Received null execution context");
-        return false;
-    }
-    
-    
-    if (!exe_ctx->process)
+    if (!exe_ctx.process)
     {
         err.SetErrorString("Couldn't find the process");
         return false;
     }
     
-    if (!exe_ctx->target)
+    if (!exe_ctx.target)
     {
         err.SetErrorString("Couldn't find the target");
         return false;
     }
     
-    lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));    
+    lldb::DataBufferSP data(new DataBufferHeap(m_struct_vars->m_struct_size, 0));    
     
     Error error;
-    if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
+    if (exe_ctx.process->ReadMemory (m_material_vars->m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
     {
         err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
         return false;
     }
     
-    DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
+    DataExtractor extractor(data, exe_ctx.process->GetByteOrder(), exe_ctx.target->GetArchitecture().GetAddressByteSize());
     
     for (uint64_t member_index = 0, num_members = m_struct_members.Size();
          member_index < num_members;
@@ -487,15 +524,15 @@
         if (!member.m_jit_vars.get())
             return false;
         
-        extractor.Dump(&s,                                                      // stream
-                       member.m_jit_vars->m_offset,                             // offset
-                       lldb::eFormatBytesWithASCII,                             // format
-                       1,                                                       // byte size of individual entries
-                       member.m_jit_vars->m_size,                               // number of entries
-                       16,                                                      // entries per line
-                       m_materialized_location + member.m_jit_vars->m_offset,   // address to print
-                       0,                                                       // bit size (bitfields only; 0 means ignore)
-                       0);                                                      // bit alignment (bitfields only; 0 means ignore)
+        extractor.Dump(&s,                                                                      // stream
+                       member.m_jit_vars->m_offset,                                             // offset
+                       lldb::eFormatBytesWithASCII,                                             // format
+                       1,                                                                       // byte size of individual entries
+                       member.m_jit_vars->m_size,                                               // number of entries
+                       16,                                                                      // entries per line
+                       m_material_vars->m_materialized_location + member.m_jit_vars->m_offset,  // address to print
+                       0,                                                                       // bit size (bitfields only; 0 means ignore)
+                       0);                                                                      // bit alignment (bitfields only; 0 means ignore)
         
         s.PutChar('\n');
     }
@@ -507,68 +544,66 @@
 ClangExpressionDeclMap::DoMaterialize 
 (
     bool dematerialize,
-    ExecutionContext *exe_ctx,
+    ExecutionContext &exe_ctx,
     ClangExpressionVariable **result,
     Error &err
 )
 {
+    assert (m_struct_vars.get());
+    
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
-    if (!m_struct_laid_out)
+    if (!m_struct_vars->m_struct_laid_out)
     {
         err.SetErrorString("Structure hasn't been laid out yet");
         return LLDB_INVALID_ADDRESS;
     }
     
-    if (!exe_ctx)
-    {
-        err.SetErrorString("Received null execution context");
-        return LLDB_INVALID_ADDRESS;
-    }
-    
-    if (!exe_ctx->frame)
+    if (!exe_ctx.frame)
     {
         err.SetErrorString("Received null execution frame");
         return LLDB_INVALID_ADDRESS;
     }
     
-    if (!m_struct_size)
+    ClangPersistentVariables &persistent_vars = exe_ctx.process->GetPersistentVariables();
+        
+    if (!m_struct_vars->m_struct_size)
     {
         if (log)
             log->PutCString("Not bothering to allocate a struct because no arguments are needed");
         
-        m_allocated_area = NULL;
+        m_material_vars->m_allocated_area = NULL;
         
         return true;
     }
     
-    const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
+    const SymbolContext &sym_ctx(exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything));
     
     if (!dematerialize)
     {
-        if (m_materialized_location)
+        if (m_material_vars->m_materialized_location)
         {
-            exe_ctx->process->DeallocateMemory(m_materialized_location);
-            m_materialized_location = 0;
+            exe_ctx.process->DeallocateMemory(m_material_vars->m_materialized_location);
+            m_material_vars->m_materialized_location = 0;
         }
         
         if (log)
             log->PutCString("Allocating memory for materialized argument struct");
         
-        lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size, 
-                                                            lldb::ePermissionsReadable | lldb::ePermissionsWritable,
-                                                            err);
+        lldb::addr_t mem = exe_ctx.process->AllocateMemory(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size, 
+                                                           lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+                                                           err);
         
         if (mem == LLDB_INVALID_ADDRESS)
             return false;
         
-        m_allocated_area = mem;
+        m_material_vars->m_allocated_area = mem;
     }
     
-    m_materialized_location = m_allocated_area;
+    m_material_vars->m_materialized_location = m_material_vars->m_allocated_area;
     
-    if (m_materialized_location % m_struct_alignment)
-        m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
+    if (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment)
+        m_material_vars->m_materialized_location += (m_struct_vars->m_struct_alignment - (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment));
     
     for (uint64_t member_index = 0, num_members = m_struct_members.Size();
          member_index < num_members;
@@ -578,10 +613,14 @@
         
         ClangExpressionVariable *entity = NULL;
         
+        /*
         if (member.m_parser_vars.get())
             entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
+        */
         
-        ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name);
+        entity = m_found_entities.GetVariable(member.m_name);
+         
+        ClangExpressionVariable *persistent_variable = persistent_vars.GetVariable(member.m_name);
         
         if (entity)
         {
@@ -589,12 +628,12 @@
             {
                 // This is a register variable
                 
-                RegisterContext *reg_ctx = exe_ctx->GetRegisterContext();
+                RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
                 
                 if (!reg_ctx)
                     return false;
                 
-                if (!DoMaterializeOneRegister(dematerialize, *exe_ctx, *reg_ctx, *entity->m_register_info, m_materialized_location + member.m_jit_vars->m_offset, err))
+                if (!DoMaterializeOneRegister(dematerialize, exe_ctx, *reg_ctx, *entity->m_register_info, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err))
                     return false;
             }
             else
@@ -602,13 +641,13 @@
                 if (!member.m_jit_vars.get())
                     return false;
                 
-                if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, member.m_name, member.m_user_type, m_materialized_location + member.m_jit_vars->m_offset, err))
+                if (!DoMaterializeOneVariable(dematerialize, exe_ctx, sym_ctx, member.m_name, member.m_user_type, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err))
                     return false;
             }
         }
         else if (persistent_variable)
         {
-            if (member.m_name == m_result_name)
+            if (member.m_name == m_struct_vars->m_result_name)
             {
                 if (!dematerialize)
                     continue;
@@ -622,7 +661,7 @@
             if (log)
                 log->Printf("Searched for persistent variable %s and found %s", member.m_name.GetCString(), persistent_variable->m_name.GetCString());
             
-            if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name, m_materialized_location + member.m_jit_vars->m_offset, err))
+            if (!DoMaterializeOnePersistentVariable(dematerialize, exe_ctx, persistent_variable->m_name, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err))
                 return false;
         }
         else
@@ -644,8 +683,10 @@
     lldb::addr_t addr,
     Error &err
 )
-{    
-    ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
+{
+    ClangPersistentVariables &persistent_vars = exe_ctx.process->GetPersistentVariables();
+    
+    ClangExpressionVariable *pvar(persistent_vars.GetVariable(name));
     
     if (!pvar)
     {
@@ -711,7 +752,7 @@
     
     std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
                                                                        var,
-                                                                       type.GetASTContext()));
+                                                                       NULL));
     
     if (!location_value.get())
     {
@@ -1006,7 +1047,7 @@
     const ConstString &name,
     TypeFromUser *type
 )
-{
+{    
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     VariableList *var_list = frame.GetVariableList(true);
@@ -1021,7 +1062,7 @@
     if (!var_sp)
     {
         // Look for globals elsewhere in the module for the frame
-        ModuleSP module_sp (m_exe_ctx.frame->GetSymbolContext(eSymbolContextModule).module_sp);
+        ModuleSP module_sp (frame.GetSymbolContext(eSymbolContextModule).module_sp);
         if (module_sp)
         {
             VariableList module_globals;
@@ -1033,7 +1074,7 @@
     if (!var_sp)
     {
         // Look for globals elsewhere in the program (all images)
-        TargetSP target_sp (m_exe_ctx.frame->GetSymbolContext(eSymbolContextTarget).target_sp);
+        TargetSP target_sp (frame.GetSymbolContext(eSymbolContextTarget).target_sp);
         if (target_sp)
         {
             VariableList program_globals;
@@ -1064,16 +1105,19 @@
 void 
 ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString &name)
 {
+    assert (m_struct_vars.get());
+    assert (m_parser_vars.get());
+    
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
         
     if (log)
         log->Printf("Hunting for a definition for '%s'", name.GetCString());
     
     // Back out in all cases where we're not fully initialized
-    if (m_exe_ctx.frame == NULL)
+    if (m_parser_vars->m_exe_ctx->frame == NULL)
         return;
     
-    if (m_ignore_lookups)
+    if (m_parser_vars->m_ignore_lookups)
     {
         if (log)
             log->Printf("Ignoring a query during an import");
@@ -1091,7 +1135,7 @@
     // doesn't start with our phony prefix of '$'
     if (name_unique_cstr[0] != '$')
     {
-        Variable *var = FindVariableInScope(*m_exe_ctx.frame, name);
+        Variable *var = FindVariableInScope(*m_parser_vars->m_exe_ctx->frame, name);
         
         // If we found a variable in scope, no need to pull up function names
         if (var != NULL)
@@ -1100,7 +1144,7 @@
         }
         else
         {
-            m_sym_ctx.FindFunctionsByName (name, false, sc_list);
+            m_parser_vars->m_sym_ctx.FindFunctionsByName (name, false, sc_list);
         
             bool found_specific = false;
             Symbol *generic_symbol = NULL;
@@ -1138,7 +1182,7 @@
                     AddOneFunction(context, NULL, non_extern_symbol);
             }
 
-            ClangNamespaceDecl namespace_decl (m_sym_ctx.FindNamespace(name));
+            ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name));
             if (namespace_decl)
             {
                 clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl);
@@ -1158,7 +1202,7 @@
         {
             // Clang is looking for the type of "this"
             
-            VariableList *vars = m_exe_ctx.frame->GetVariableList(false);
+            VariableList *vars = m_parser_vars->m_exe_ctx->frame->GetVariableList(false);
             
             if (!vars)
                 return;
@@ -1184,7 +1228,7 @@
             TypeFromUser this_user_type(this_type->GetClangType(),
                                         this_type->GetClangAST());
             
-            m_object_pointer_type = this_user_type;
+            m_struct_vars->m_object_pointer_type = this_user_type;
             
             void *pointer_target_type;
             
@@ -1200,7 +1244,7 @@
             return;
         }
         
-        ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
+        ClangExpressionVariable *pvar(m_parser_vars->m_persistent_vars->GetVariable(name));
     
         if (pvar)
         {
@@ -1210,16 +1254,16 @@
         
         const char *reg_name(&name.GetCString()[1]);
         
-        if (m_exe_ctx.GetRegisterContext())
+        if (m_parser_vars->m_exe_ctx->GetRegisterContext())
         {
-            const lldb::RegisterInfo *reg_info(m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(reg_name));
+            const lldb::RegisterInfo *reg_info(m_parser_vars->m_exe_ctx->GetRegisterContext()->GetRegisterInfoByName(reg_name));
             
             if (reg_info)
                 AddOneRegister(context, reg_info);
         }
     }
     
-    lldb::TypeSP type_sp (m_sym_ctx.FindTypeByName (name));
+    lldb::TypeSP type_sp (m_parser_vars->m_sym_ctx.FindTypeByName (name));
         
     if (type_sp)
     {
@@ -1347,7 +1391,7 @@
         
         Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
         
-        lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx.target);
+        lldb::addr_t load_addr = so_addr.GetLoadAddress(exe_ctx.target);
         
         var_location->GetScalar() = load_addr;
         var_location->SetValueType(Value::eValueTypeLoadAddress);
@@ -1363,12 +1407,14 @@
 ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
                                        Variable* var)
 {
+    assert (m_parser_vars.get());
+    
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     TypeFromUser ut;
     TypeFromParser pt;
     
-    Value *var_location = GetVariableValue (m_exe_ctx, 
+    Value *var_location = GetVariableValue (*m_parser_vars->m_exe_ctx, 
                                             var, 
                                             context.GetASTContext(),
                                             &ut,
@@ -1494,6 +1540,8 @@
                                        Function* fun,
                                        Symbol* symbol)
 {
+    assert (m_parser_vars.get());
+    
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     NamedDecl *fun_decl;
@@ -1545,7 +1593,7 @@
         return;
     }
     
-    lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx.target);
+    lldb::addr_t load_addr = fun_address->GetLoadAddress(m_parser_vars->m_exe_ctx->target);
     fun_location->SetValueType(Value::eValueTypeLoadAddress);
     fun_location->GetScalar() = load_addr;
     
@@ -1619,13 +1667,15 @@
                                          ASTContext *source_context,
                                          void *clang_type)
 {
-    m_ignore_lookups = true;
+    assert (m_parser_vars.get());
+    
+    m_parser_vars->m_ignore_lookups = true;
     
     void *ret = ClangASTContext::CopyType (dest_context,
                                            source_context,
                                            clang_type);
     
-    m_ignore_lookups = false;
+    m_parser_vars->m_ignore_lookups = false;
     
     return ret;
 }

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=120778&r1=120777&r2=120778&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Thu Dec  2 19:38:59 2010
@@ -225,7 +225,9 @@
     
     m_desired_type = desired_type;
     
-    m_expr_decl_map.reset(new ClangExpressionDeclMap(&exe_ctx));
+    m_expr_decl_map.reset(new ClangExpressionDeclMap());
+    
+    m_expr_decl_map->WillParse(exe_ctx);
     
     ClangExpressionParser parser(target_triple.GetCString(), *this);
     
@@ -234,6 +236,9 @@
     if (num_errors)
     {
         error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
+        
+        m_expr_decl_map->DidParse();
+        
         return false;
     }
     
@@ -254,6 +259,8 @@
         if (log)
             log->Printf("Code can be interpreted.");
         
+        m_expr_decl_map->DidParse();
+        
         return true;
     }
     
@@ -267,6 +274,8 @@
     
     Error jit_error = parser.MakeJIT (m_jit_addr, jit_end, exe_ctx);
     
+    m_expr_decl_map->DidParse();
+    
     if (jit_error.Success())
     {
         return true;
@@ -292,13 +301,13 @@
         Error materialize_error;
         
         
-        if (m_needs_object_ptr && !(m_expr_decl_map->GetObjectPointer(object_ptr, &exe_ctx, materialize_error)))
+        if (m_needs_object_ptr && !(m_expr_decl_map->GetObjectPointer(object_ptr, exe_ctx, materialize_error)))
         {
             error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
             return false;
         }
                 
-        if (!m_expr_decl_map->Materialize(&exe_ctx, struct_address, materialize_error))
+        if (!m_expr_decl_map->Materialize(exe_ctx, struct_address, materialize_error))
         {
             error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
             return false;
@@ -319,7 +328,7 @@
             
             if (struct_address)
             {
-                if (!m_expr_decl_map->DumpMaterializedStruct(&exe_ctx, args, dump_error))
+                if (!m_expr_decl_map->DumpMaterializedStruct(exe_ctx, args, dump_error))
                 {
                     log->Printf("Couldn't extract variable values : %s", dump_error.AsCString("unknown error"));
                 }
@@ -362,7 +371,7 @@
 {
     Error expr_error;
     
-    if (!m_expr_decl_map->Dematerialize(&exe_ctx, result, expr_error))
+    if (!m_expr_decl_map->Dematerialize(exe_ctx, result, expr_error))
     {
         error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
         return false;

Modified: lldb/trunk/source/Expression/ClangUtilityFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUtilityFunction.cpp?rev=120778&r1=120777&r2=120778&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUtilityFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangUtilityFunction.cpp Thu Dec  2 19:38:59 2010
@@ -99,7 +99,9 @@
     // Parse the expression
     //
     
-    m_expr_decl_map.reset(new ClangExpressionDeclMap(&exe_ctx));
+    m_expr_decl_map.reset(new ClangExpressionDeclMap());
+    
+    m_expr_decl_map->WillParse(exe_ctx);
         
     ClangExpressionParser parser(target_triple.GetCString(), *this);
     
@@ -120,6 +122,8 @@
         
     Error jit_error = parser.MakeJIT (m_jit_begin, m_jit_end, exe_ctx);
     
+    m_expr_decl_map->DidParse();
+    
     m_expr_decl_map.reset();
     
     if (jit_error.Success())





More information about the lldb-commits mailing list