[Lldb-commits] [lldb] r108485 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h source/Commands/CommandObjectExpression.cpp source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRForTarget.cpp

Sean Callanan scallanan at apple.com
Thu Jul 15 17:09:47 PDT 2010


Author: spyffe
Date: Thu Jul 15 19:09:46 2010
New Revision: 108485

URL: http://llvm.org/viewvc/llvm-project?rev=108485&view=rev
Log:
Wrote the code that looks at a context to see
if the variables in that context allow a particular
JIT compiled expression to run in that context.

Modified:
    lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Expression/IRForTarget.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=108485&r1=108484&r2=108485&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Thu Jul 15 19:09:46 2010
@@ -25,6 +25,7 @@
 namespace clang {
     class DeclarationName;
     class DeclContext;
+    class QualType;
 }
 
 namespace llvm {
@@ -33,6 +34,7 @@
 
 namespace lldb_private {
 
+class Error;
 class Function;
 class NameSearchContext;
 class Variable;
@@ -50,6 +52,8 @@
     // Interface for IRForTarget
     bool AddValueToStruct (llvm::Value *value,
                            const clang::NamedDecl *decl,
+                           std::string &name,
+                           void *type,
                            size_t size,
                            off_t alignment);
     bool DoStructLayout ();
@@ -64,6 +68,10 @@
     // Interface for DwarfExpression
     Value *GetValueForIndex (uint32_t index);
     
+    // Interface for CommandObjectExpression
+    lldb::addr_t Materialize(ExecutionContext *exe_ctx,
+                             Error &error);
+    
     // Interface for ClangASTSource
     void GetDecls (NameSearchContext &context,
                    const char *name);
@@ -72,13 +80,17 @@
     struct Tuple
     {
         const clang::NamedDecl  *m_decl;
+        clang::ASTContext       *m_ast_context;
+        void                    *m_orig_type;
         Value                   *m_value; /* owned by ClangExpressionDeclMap */
     };
     
     struct StructMember
     {
-        const clang::NamedDecl  *m_decl;
-        llvm::Value             *m_value;
+        const clang::NamedDecl *m_decl;
+        llvm::Value            *m_value;
+        std::string             m_name;
+        void                   *m_type;
         off_t                   m_offset;
         size_t                  m_size;
         off_t                   m_alignment;
@@ -97,9 +109,17 @@
     off_t               m_struct_alignment;
     size_t              m_struct_size;
     bool                m_struct_laid_out;
-    
+    lldb::addr_t        m_materialized_location;
+        
     void AddOneVariable(NameSearchContext &context, Variable *var);
     void AddOneFunction(NameSearchContext &context, Function *fun);
+    
+    bool MaterializeOneVariable(ExecutionContext &exe_ctx,
+                                const SymbolContext &sym_ctx,
+                                const char *name,
+                                void *type,
+                                clang::ASTContext *ast_context,
+                                lldb::addr_t addr);
 };
     
 } // namespace lldb_private

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=108485&r1=108484&r2=108485&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Thu Jul 15 19:09:46 2010
@@ -304,8 +304,22 @@
                 return false;
             }
             
-            log->Printf("Function is at 0x%llx", (uint64_t)function_address);
+            Error err;
+                        
+            lldb::addr_t struct_address = expr_decl_map.Materialize(&m_exe_ctx, err);
+            
+            if (struct_address == LLDB_INVALID_ADDRESS)
+            {
+                error_stream.Printf ("Couldn't materialize struct: %s\n", err.AsCString("unknown error"));
+                return false;
+            }
+            
+            log->Printf("Function address  : 0x%llx", (uint64_t)function_address);
+            log->Printf("Structure address : 0x%llx", (uint64_t)struct_address);
         }
+        
+        return true;
+        
     }
     else
     {

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=108485&r1=108484&r2=108485&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Thu Jul 15 19:09:46 2010
@@ -15,6 +15,7 @@
 // Project includes
 #include "lldb/lldb-private.h"
 #include "lldb/Core/Address.h"
+#include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Expression/ClangASTSource.h"
@@ -27,19 +28,17 @@
 #include "lldb/Symbol/TypeList.h"
 #include "lldb/Symbol/Variable.h"
 #include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/Process.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/ExecutionContext.h"
 
-#define DEBUG_PRINTF(...)           \
-    if (log)                        \
-        log->Printf(__VA_ARGS__)
-
 using namespace lldb_private;
 using namespace clang;
 
 ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
     m_exe_ctx(exe_ctx),
-    m_struct_laid_out(false)
+    m_struct_laid_out(false),
+    m_materialized_location(0)
 {
     if (exe_ctx && exe_ctx->frame)
         m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
@@ -83,6 +82,8 @@
 bool 
 ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value,
                                           const clang::NamedDecl *decl,
+                                          std::string &name,
+                                          void *type,
                                           size_t size,
                                           off_t alignment)
 {
@@ -102,6 +103,8 @@
     
     member.m_value      = value;
     member.m_decl       = decl;
+    member.m_name       = name;
+    member.m_type       = type;
     member.m_offset     = 0;
     member.m_size       = size;
     member.m_alignment  = alignment;
@@ -187,6 +190,136 @@
     return m_tuples[index].m_value;
 }
 
+// Interface for CommandObjectExpression
+lldb::addr_t 
+ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx, Error &err)
+{
+    if (!m_struct_laid_out)
+    {
+        err.SetErrorString("Structure hasn't been laid out yet");
+        return LLDB_INVALID_ADDRESS;
+    }
+    
+    if (m_materialized_location)
+    {
+        exe_ctx->process->DeallocateMemory(m_materialized_location);
+        m_materialized_location = 0;
+    }
+    
+    if (!exe_ctx)
+    {
+        err.SetErrorString("Received null execution context");
+        return LLDB_INVALID_ADDRESS;
+    }
+    
+    const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
+    
+    StructMemberIterator iter;
+        
+    lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size, 
+                                                        lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+                                                        err);
+    
+    if (mem == LLDB_INVALID_ADDRESS)
+        return LLDB_INVALID_ADDRESS;
+    
+    m_materialized_location = mem;
+    
+    lldb::addr_t aligned_mem = mem;
+    
+    if (aligned_mem % m_struct_alignment)
+    {
+        aligned_mem += (m_struct_alignment - (aligned_mem % m_struct_alignment));
+    }
+    
+    for (iter = m_members.begin();
+         iter != m_members.end();
+         ++iter)
+    {
+        uint32_t tuple_index;
+        
+        if (!GetIndexForDecl(tuple_index, iter->m_decl))
+            continue;
+        
+        Tuple &tuple(m_tuples[tuple_index]);
+        
+        MaterializeOneVariable(*exe_ctx, sym_ctx, iter->m_name.c_str(), tuple.m_orig_type, tuple.m_ast_context, aligned_mem + iter->m_offset);
+    }
+    
+    return aligned_mem;
+}
+
+bool 
+ClangExpressionDeclMap::MaterializeOneVariable(ExecutionContext &exe_ctx,
+                                               const SymbolContext &sym_ctx,
+                                               const char *name,
+                                               void *type,
+                                               clang::ASTContext *ast_context,
+                                               lldb::addr_t addr)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+
+    Function *function(m_sym_ctx->function);
+    Block *block(m_sym_ctx->block);
+    
+    if (!function || !block)
+    {
+        if (log)
+            log->Printf("function = %p, block = %p", function, block);
+        return false;
+    }
+    
+    BlockList& blocks(function->GetBlocks(true));
+    
+    lldb::user_id_t current_block_id;
+    
+    for (current_block_id = block->GetID();
+         current_block_id != Block::InvalidID;
+         current_block_id = blocks.GetParent(current_block_id))
+    {
+        Block *current_block(blocks.GetBlockByID(current_block_id));
+        
+        lldb::VariableListSP var_list = current_block->GetVariableList(false, true);
+        
+        if (!var_list)
+            continue;
+        
+        lldb::VariableSP var = var_list->FindVariable(ConstString(name));
+        
+        if (!var)
+            continue;
+        
+        // var->GetType()->GetClangAST() is the program's AST context and holds
+        // var->GetType()->GetOpaqueClangQualType().
+        
+        // type is m_type for one of the struct members, which was added by 
+        // AddValueToStruct.  That type was extracted from the AST context of
+        // the compiler in IRForTarget.  The original for the type was copied
+        // out of the program's AST context by AddOneVariable.
+        
+        // The key here is: we know when we copied a type, and for what Decl we
+        // did it.  So we need for each struct Tuple to keep the type that we
+        // found, and which AST context we found it in. Then we can look up
+        // m_decl in m_tuples.
+        
+        if (ast_context == var->GetType()->GetClangAST())
+        {
+            if (!ClangASTContext::AreTypesSame(ast_context, type, var->GetType()->GetOpaqueClangQualType()))
+                continue;
+        }
+        else
+        {
+            if (log)
+                log->PutCString("Skipping a candidate variable because of different AST contexts");
+            continue;
+        }
+        
+        
+    }
+    
+    return true;
+}
+
 // Interface for ClangASTSource
 void 
 ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
@@ -194,7 +327,8 @@
 {
     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
     
-    DEBUG_PRINTF("Hunting for a definition for %s", name);
+    if (log)
+        log->Printf("Hunting for a definition for %s", name);
     
     // Back out in all cases where we're not fully initialized
     if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
@@ -205,7 +339,8 @@
     
     if (!function || !block)
     {
-        DEBUG_PRINTF("function = %p, block = %p", function, block);
+        if (log)
+            log->Printf("function = %p, block = %p", function, block);
         return;
     }
     
@@ -247,7 +382,8 @@
         
         if (!compile_unit)
         {
-            DEBUG_PRINTF("compile_unit = %p", compile_unit);
+            if (log)
+                log->Printf("compile_unit = %p", compile_unit);
             return;
         }
         
@@ -276,7 +412,8 @@
     
     if (!var_type) 
     {
-        DEBUG_PRINTF("Skipped a definition because it has no type");
+        if (log)
+            log->PutCString("Skipped a definition because it has no type");
         return;
     }
     
@@ -284,7 +421,8 @@
     
     if (!var_opaque_type)
     {
-        DEBUG_PRINTF("Skipped a definition because it has no Clang type");
+        if (log)
+            log->PutCString("Skipped a definition because it has no Clang type");
         return;
     }
     
@@ -294,7 +432,8 @@
     
     if (!type_list)
     {
-        DEBUG_PRINTF("Skipped a definition because the type has no associated type list");
+        if (log)
+            log->PutCString("Skipped a definition because the type has no associated type list");
         return;
     }
     
@@ -302,7 +441,8 @@
     
     if (!exe_ast_ctx)
     {
-        DEBUG_PRINTF("There is no AST context for the current execution context");
+        if (log)
+            log->PutCString("There is no AST context for the current execution context");
         return;
     }
     
@@ -312,11 +452,14 @@
     
     if (!var_location_expr.Evaluate(m_exe_ctx, exe_ast_ctx, NULL, *var_location.get(), &err))
     {
-        DEBUG_PRINTF("Error evaluating location: %s", err.AsCString());
+        if (log)
+            log->Printf("Error evaluating location: %s", err.AsCString());
         return;
     }
     
-    void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), type_list->GetClangASTContext().getASTContext(), var_opaque_type);
+    clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
+    
+    void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), var_ast_context, var_opaque_type);
     
     if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
         var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type);
@@ -346,12 +489,15 @@
     
     Tuple tuple;
     
-    tuple.m_decl  = var_decl;
-    tuple.m_value = var_location.release();
+    tuple.m_decl        = var_decl;
+    tuple.m_value       = var_location.release();
+    tuple.m_orig_type   = var_opaque_type;
+    tuple.m_ast_context = var_ast_context;
     
     m_tuples.push_back(tuple);
     
-    DEBUG_PRINTF("Found variable");    
+    if (log)
+        log->PutCString("Found variable");    
 }
 
 void
@@ -364,7 +510,8 @@
     
     if (!fun_type) 
     {
-        DEBUG_PRINTF("Skipped a function because it has no type");
+        if (log)
+            log->PutCString("Skipped a function because it has no type");
         return;
     }
     
@@ -372,7 +519,8 @@
     
     if (!fun_opaque_type)
     {
-        DEBUG_PRINTF("Skipped a function because it has no Clang type");
+        if (log)
+            log->PutCString("Skipped a function because it has no Clang type");
         return;
     }
     
@@ -384,16 +532,20 @@
     fun_location->GetScalar() = load_addr;
     
     TypeList *type_list = fun_type->GetTypeList();
-    void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), type_list->GetClangASTContext().getASTContext(), fun_opaque_type);
+    clang::ASTContext *fun_ast_context = type_list->GetClangASTContext().getASTContext();
+    void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
     
     NamedDecl *fun_decl = context.AddFunDecl(copied_type);
     
     Tuple tuple;
     
-    tuple.m_decl  = fun_decl;
-    tuple.m_value = fun_location.release();
+    tuple.m_decl        = fun_decl;
+    tuple.m_value       = fun_location.release();
+    tuple.m_orig_type   = fun_opaque_type;
+    tuple.m_ast_context = fun_ast_context;
     
     m_tuples.push_back(tuple);
     
-    DEBUG_PRINTF("Found function");    
+    if (log)
+        log->PutCString("Found function");    
 }

Modified: lldb/trunk/source/Expression/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=108485&r1=108484&r2=108485&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRForTarget.cpp (original)
+++ lldb/trunk/source/Expression/IRForTarget.cpp Thu Jul 15 19:09:46 2010
@@ -90,12 +90,26 @@
     {        
         clang::NamedDecl *named_decl = DeclForGlobalValue(M, global_variable);
         
+        std::string name = named_decl->getName().str();
+        
+        void *qual_type = NULL;
+        
+        if (clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl))
+            qual_type = value_decl->getType().getAsOpaquePtr();
+        else
+            return false;
+        
         const llvm::Type *value_type = global_variable->getType();
         
         size_t value_size = m_target_data->getTypeStoreSize(value_type);
         off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type);
         
-        if (named_decl && !DM->AddValueToStruct(V, named_decl, value_size, value_alignment))
+        if (named_decl && !DM->AddValueToStruct(V, 
+                                                named_decl,
+                                                name,
+                                                qual_type,
+                                                value_size, 
+                                                value_alignment))
             return false;
     }
     





More information about the lldb-commits mailing list