summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Expression/ClangExpressionDeclMap.h189
-rw-r--r--lldb/source/Expression/ClangASTSource.cpp2
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp356
-rw-r--r--lldb/source/Expression/ClangUserExpression.cpp19
-rw-r--r--lldb/source/Expression/ClangUtilityFunction.cpp6
5 files changed, 383 insertions, 189 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
index 2c4d0c5ce45..e089ab4c68d 100644
--- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
+++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
@@ -71,17 +71,27 @@ public:
/// 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 @@ public:
/// @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 @@ public:
/// True on success; false otherwise.
//------------------------------------------------------------------
bool GetObjectPointer(lldb::addr_t &object_ptr,
- ExecutionContext *exe_ctx,
+ ExecutionContext &exe_ctx,
Error &error);
//------------------------------------------------------------------
@@ -313,7 +323,7 @@ public:
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
- bool DumpMaterializedStruct(ExecutionContext *exe_ctx,
+ bool DumpMaterializedStruct(ExecutionContext &exe_ctx,
Stream &s,
Error &error);
@@ -334,7 +344,7 @@ public:
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
- bool Dematerialize(ExecutionContext *exe_ctx,
+ bool Dematerialize(ExecutionContext &exe_ctx,
ClangExpressionVariable *&result,
Error &error);
@@ -356,37 +366,153 @@ public:
//------------------------------------------------------------------
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.
-
- 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.
-
- bool m_ignore_lookups; ///< True during an import when we should be ignoring type lookups.
-
+ 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.
+
+ //----------------------------------------------------------------------
+ /// 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();
+ }
+
//------------------------------------------------------------------
/// 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 @@ private:
/// 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
diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp
index 95a35b9b098..09d6ed08032 100644
--- a/lldb/source/Expression/ClangASTSource.cpp
+++ b/lldb/source/Expression/ClangASTSource.cpp
@@ -83,7 +83,7 @@ DeclContext::lookup_result ClangASTSource::FindExternalVisibleDeclsByName
// 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
{
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index 00e33bef10b..bd68b7b0439 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -43,62 +43,58 @@ using namespace lldb;
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)
+ m_parser_vars (),
+ m_struct_vars ()
{
- 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();
- }
+ 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 @@ ClangExpressionDeclMap::~ClangExpressionDeclMap()
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 @@ ClangExpressionDeclMap::AddPersistentVariable
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 @@ ClangExpressionDeclMap::AddValueToStruct
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 @@ ClangExpressionDeclMap::AddValueToStruct
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 @@ ClangExpressionDeclMap::AddValueToStruct
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 @@ ClangExpressionDeclMap::DoStructLayout ()
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 @@ ClangExpressionDeclMap::DoStructLayout ()
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 @@ bool ClangExpressionDeclMap::GetStructInfo
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 @@ ClangExpressionDeclMap::GetStructElement
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 @@ ClangExpressionDeclMap::GetFunctionAddress
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 @@ ClangExpressionDeclMap::GetFunctionAddress
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 @@ ClangExpressionDeclMap::GetFunctionAddress
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 @@ bool
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 @@ ClangExpressionDeclMap::GetObjectPointer
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 @@ ClangExpressionDeclMap::GetObjectPointer
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 @@ ClangExpressionDeclMap::GetObjectPointer
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 @@ ClangExpressionDeclMap::GetObjectPointer
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 @@ ClangExpressionDeclMap::DumpMaterializedStruct
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 @@ bool
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 @@ ClangExpressionDeclMap::DoMaterialize
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 @@ ClangExpressionDeclMap::DoMaterialize
{
// 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 @@ ClangExpressionDeclMap::DoMaterialize
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 @@ ClangExpressionDeclMap::DoMaterialize
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 @@ ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
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 @@ ClangExpressionDeclMap::DoMaterializeOneVariable
std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
var,
- type.GetASTContext()));
+ NULL));
if (!location_value.get())
{
@@ -1006,7 +1047,7 @@ ClangExpressionDeclMap::FindVariableInScope
const ConstString &name,
TypeFromUser *type
)
-{
+{
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
VariableList *var_list = frame.GetVariableList(true);
@@ -1021,7 +1062,7 @@ ClangExpressionDeclMap::FindVariableInScope
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 @@ ClangExpressionDeclMap::FindVariableInScope
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 @@ ClangExpressionDeclMap::FindVariableInScope
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 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString
// 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 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString
}
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 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString
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 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString
{
// 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 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString
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 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString
return;
}
- ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
+ ClangExpressionVariable *pvar(m_parser_vars->m_persistent_vars->GetVariable(name));
if (pvar)
{
@@ -1210,16 +1254,16 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString
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 @@ ClangExpressionDeclMap::GetVariableValue
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 @@ void
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 @@ ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
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 @@ ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
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 @@ ClangExpressionDeclMap::GuardedCopyType (ASTContext *dest_context,
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;
}
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp
index 7e5b40da7d7..6a980db293b 100644
--- a/lldb/source/Expression/ClangUserExpression.cpp
+++ b/lldb/source/Expression/ClangUserExpression.cpp
@@ -225,7 +225,9 @@ ClangUserExpression::Parse (Stream &error_stream,
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 @@ ClangUserExpression::Parse (Stream &error_stream,
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 @@ ClangUserExpression::Parse (Stream &error_stream,
if (log)
log->Printf("Code can be interpreted.");
+ m_expr_decl_map->DidParse();
+
return true;
}
@@ -267,6 +274,8 @@ ClangUserExpression::Parse (Stream &error_stream,
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 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
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 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
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 @@ ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
{
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;
diff --git a/lldb/source/Expression/ClangUtilityFunction.cpp b/lldb/source/Expression/ClangUtilityFunction.cpp
index 0080347543b..0c9d90a2b57 100644
--- a/lldb/source/Expression/ClangUtilityFunction.cpp
+++ b/lldb/source/Expression/ClangUtilityFunction.cpp
@@ -99,7 +99,9 @@ ClangUtilityFunction::Install (Stream &error_stream,
// 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 @@ ClangUtilityFunction::Install (Stream &error_stream,
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())
OpenPOWER on IntegriCloud