[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