diff options
author | Sean Callanan <scallanan@apple.com> | 2010-07-16 00:09:46 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2010-07-16 00:09:46 +0000 |
commit | ea22d4288a5310894a9f9dbb7b918aa560554bf9 (patch) | |
tree | e14e8b050940d8e1595162f31f4db90d24fe2610 /lldb/source/Expression/ClangExpressionDeclMap.cpp | |
parent | bfd4fd7bb751632bdd3154e79af6095765cbf714 (diff) | |
download | bcm5719-llvm-ea22d4288a5310894a9f9dbb7b918aa560554bf9.tar.gz bcm5719-llvm-ea22d4288a5310894a9f9dbb7b918aa560554bf9.zip |
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.
llvm-svn: 108485
Diffstat (limited to 'lldb/source/Expression/ClangExpressionDeclMap.cpp')
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 198 |
1 files changed, 175 insertions, 23 deletions
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index b83cf4a330e..b0f1cf275e0 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -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 @@ ClangExpressionDeclMap::GetIndexForDecl (uint32_t &index, 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 @@ ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value, 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 @@ Value 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 @@ ClangExpressionDeclMap::GetDecls(NameSearchContext &context, { 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 @@ ClangExpressionDeclMap::GetDecls(NameSearchContext &context, 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 @@ ClangExpressionDeclMap::GetDecls(NameSearchContext &context, if (!compile_unit) { - DEBUG_PRINTF("compile_unit = %p", compile_unit); + if (log) + log->Printf("compile_unit = %p", compile_unit); return; } @@ -276,7 +412,8 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 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 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 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 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 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 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 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 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 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 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 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 @@ ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, 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 @@ ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, 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 @@ ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, 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"); } |