Added functionality to dematerialize values that were
used by the JIT compiled expression, including the
result of the expression.
Also added a new class, ASTType, which encapsulates an
opaque Clang type and its associated AST context.
Refactored ClangExpressionDeclMap to use ASTTypes,
significantly reducing the possibility of mixups of
types from different AST contexts.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@108965 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index dd50c53..5a6b674 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -28,9 +28,10 @@
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Target.h"
using namespace lldb_private;
using namespace clang;
@@ -83,7 +84,8 @@
ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value,
const clang::NamedDecl *decl,
std::string &name,
- void *type,
+ void *parser_type,
+ clang::ASTContext *parser_ast_context,
size_t size,
off_t alignment)
{
@@ -101,13 +103,13 @@
StructMember member;
- 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;
+ member.m_value = value;
+ member.m_decl = decl;
+ member.m_name = name;
+ member.m_parser_type = TypeFromParser(parser_type, parser_ast_context);
+ member.m_offset = 0;
+ member.m_size = size;
+ member.m_alignment = alignment;
m_members.push_back(member);
@@ -181,7 +183,7 @@
}
// Interface for DwarfExpression
-Value
+lldb_private::Value
*ClangExpressionDeclMap::GetValueForIndex (uint32_t index)
{
if (index >= m_tuples.size ())
@@ -191,8 +193,33 @@
}
// Interface for CommandObjectExpression
-lldb::addr_t
-ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx, Error &err)
+
+bool
+ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx,
+ lldb::addr_t &struct_address,
+ Error &err)
+{
+ bool result = DoMaterialize(false, exe_ctx, NULL, err);
+
+ if (result)
+ struct_address = m_materialized_location;
+
+ return result;
+}
+
+bool
+ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
+ lldb_private::Value &result_value,
+ Error &err)
+{
+ return DoMaterialize(true, exe_ctx, &result_value, err);
+}
+
+bool
+ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
+ ExecutionContext *exe_ctx,
+ lldb_private::Value *result_value,
+ Error &err)
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
@@ -202,12 +229,6 @@
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");
@@ -216,24 +237,33 @@
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)
+ if (!dematerialize)
{
- aligned_mem += (m_struct_alignment - (aligned_mem % m_struct_alignment));
+ if (m_materialized_location)
+ {
+ exe_ctx->process->DeallocateMemory(m_materialized_location);
+ m_materialized_location = 0;
+ }
+
+ 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 false;
+
+ m_allocated_area = mem;
}
+ m_materialized_location = m_allocated_area;
+
+ if (m_materialized_location % m_struct_alignment)
+ {
+ m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
+ }
+
+ StructMemberIterator iter;
+
for (iter = m_members.begin();
iter != m_members.end();
++iter)
@@ -251,23 +281,122 @@
if (log)
log->Printf("Found special result variable %s", iter->m_name.c_str());
+ if (dematerialize)
+ {
+ clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext());
+
+ if (!context)
+ {
+ err.SetErrorString("Couldn't find a scratch AST context to put the result type into");
+ }
+
+ TypeFromUser copied_type(ClangASTContext::CopyType(context,
+ iter->m_parser_type.GetASTContext(),
+ iter->m_parser_type.GetType()),
+ context);
+
+ result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetType());
+ }
+
continue;
}
Tuple &tuple(m_tuples[tuple_index]);
- if (!MaterializeOneVariable(*exe_ctx, sym_ctx, iter->m_name.c_str(), tuple.m_orig_type, tuple.m_ast_context, aligned_mem + iter->m_offset, err))
+ if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, iter->m_name.c_str(), tuple.m_user_type, m_materialized_location + iter->m_offset, err))
return false;
}
- return aligned_mem;
+ return true;
+}
+
+bool
+ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
+ ExecutionContext &exe_ctx,
+ const SymbolContext &sym_ctx,
+ const char *name,
+ TypeFromUser type,
+ lldb::addr_t addr,
+ Error &err)
+{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+
+ Variable *var = FindVariableInScope(sym_ctx, name, &type);
+
+ if (!var)
+ {
+ err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
+ return false;
+ }
+
+ log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetType());
+
+ std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
+ var,
+ type.GetASTContext()));
+
+ if (!location_value.get())
+ {
+ err.SetErrorStringWithFormat("Couldn't get value for %s", name);
+ return false;
+ }
+
+ if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
+ {
+ lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
+
+ size_t bit_size = ClangASTContext::GetTypeBitSize(type.GetASTContext(), type.GetType());
+ size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
+
+ DataBufferHeap data;
+ data.SetByteSize(byte_size);
+
+ lldb::addr_t src_addr;
+ lldb::addr_t dest_addr;
+
+ if (dematerialize)
+ {
+ src_addr = addr;
+ dest_addr = value_addr;
+ }
+ else
+ {
+ src_addr = value_addr;
+ dest_addr = addr;
+ }
+
+ Error error;
+ if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
+ {
+ err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
+ return false;
+ }
+
+ if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), byte_size, error) != byte_size)
+ {
+ err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
+ return false;
+ }
+
+ if (log)
+ log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
+ }
+ else
+ {
+ StreamString ss;
+
+ location_value->Dump(&ss);
+
+ err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
+ }
+
+ return true;
}
Variable*
ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
const char *name,
- void *type,
- clang::ASTContext *ast_context)
+ TypeFromUser *type)
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
@@ -319,9 +448,9 @@
if (!type)
return var.get();
- if (ast_context == var->GetType()->GetClangAST())
+ if (type->GetASTContext() == var->GetType()->GetClangAST())
{
- if (!ClangASTContext::AreTypesSame(ast_context, type, var->GetType()->GetOpaqueClangQualType()))
+ if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type, var->GetType()->GetOpaqueClangQualType()))
continue;
}
else
@@ -357,9 +486,9 @@
if (!type)
return var.get();
- if (ast_context == var->GetType()->GetClangAST())
+ if (type->GetASTContext() == var->GetType()->GetClangAST())
{
- if (!ClangASTContext::AreTypesSame(ast_context, type, var->GetType()->GetOpaqueClangQualType()))
+ if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetType(), var->GetType()->GetOpaqueClangQualType()))
return NULL;
}
else
@@ -375,75 +504,6 @@
return NULL;
}
-bool
-ClangExpressionDeclMap::MaterializeOneVariable(ExecutionContext &exe_ctx,
- const SymbolContext &sym_ctx,
- const char *name,
- void *type,
- clang::ASTContext *ast_context,
- lldb::addr_t addr,
- Error &err)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
-
- Variable *var = FindVariableInScope(sym_ctx, name, type, ast_context);
-
- if (!var)
- {
- err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
- return false;
- }
-
- log->Printf("Materializing %s with type %p", name, type);
-
- std::auto_ptr<Value> location_value(GetVariableValue(exe_ctx,
- var,
- ast_context));
-
- if (!location_value.get())
- {
- err.SetErrorStringWithFormat("Couldn't get value for %s", name);
- return false;
- }
-
- if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
- {
- lldb::addr_t src_addr = location_value->GetScalar().ULongLong();
-
- size_t bit_size = ClangASTContext::GetTypeBitSize(ast_context, type);
- size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
-
- DataBufferHeap data;
- data.SetByteSize(byte_size);
-
- Error error;
- if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
- {
- err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
- return false;
- }
-
- if (exe_ctx.process->WriteMemory (addr, data.GetBytes(), byte_size, error) != byte_size)
- {
- err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
- return false;
- }
-
- if (log)
- log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
- }
- else
- {
- StreamString ss;
-
- location_value->Dump(&ss);
-
- err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
- }
-
- return true;
-}
-
// Interface for ClangASTSource
void
ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
@@ -483,9 +543,9 @@
Value *
ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
Variable *var,
- clang::ASTContext *target_ast_context,
- void **opaque_type,
- clang::ASTContext **found_ast_context)
+ clang::ASTContext *parser_ast_context,
+ TypeFromUser *user_type,
+ TypeFromParser *parser_type)
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
@@ -542,8 +602,13 @@
void *type_to_use;
- if (target_ast_context)
- type_to_use = ClangASTContext::CopyType(target_ast_context, var_ast_context, var_opaque_type);
+ if (parser_ast_context)
+ {
+ type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
+
+ if (parser_type)
+ *parser_type = TypeFromParser(type_to_use, parser_ast_context);
+ }
else
type_to_use = var_opaque_type;
@@ -571,11 +636,8 @@
var_location->SetValueType(Value::eValueTypeLoadAddress);
}
- if (opaque_type)
- *opaque_type = var_opaque_type;
-
- if (found_ast_context)
- *found_ast_context = var_ast_context;
+ if (user_type)
+ *user_type = TypeFromUser(var_opaque_type, var_ast_context);
return var_location.release();
}
@@ -586,23 +648,23 @@
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
- void *var_opaque_type = NULL;
- clang::ASTContext *var_ast_context = NULL;
+ TypeFromUser ut;
+ TypeFromParser pt;
Value *var_location = GetVariableValue(*m_exe_ctx,
var,
context.GetASTContext(),
- &var_opaque_type,
- &var_ast_context);
+ &ut,
+ &pt);
- NamedDecl *var_decl = context.AddVarDecl(var_opaque_type);
+ NamedDecl *var_decl = context.AddVarDecl(pt.GetType());
Tuple tuple;
tuple.m_decl = var_decl;
tuple.m_value = var_location;
- tuple.m_orig_type = var_opaque_type;
- tuple.m_ast_context = var_ast_context;
+ tuple.m_user_type = ut;
+ tuple.m_parser_type = pt;
m_tuples.push_back(tuple);
@@ -651,8 +713,7 @@
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;
+ tuple.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);
m_tuples.push_back(tuple);