From 979f74d1ddcff4c406668912ec6568bb69e4f222 Mon Sep 17 00:00:00 2001 From: Sean Callanan Date: Fri, 3 Dec 2010 01:38:59 +0000 Subject: [PATCH] Fixed object lifetimes in ClangExpressionDeclMap so that it is not referring to potentially stale state during IR execution. This was done by introducing modular state (like ClangExpressionVariable) where groups of state variables have well-defined lifetimes: - m_parser_vars are specific to parsing, and only exist between calls to WillParse() and DidParse(). - m_struct_vars survive for the entire execution of the ClangExpressionDeclMap because they provide the template for a materialized set of expression variables. - m_material_vars are specific to a single instance of materialization, and only exist between calls to Materialize() and Dematerialize(). I also removed unnecessary references to long- lived state that really didn't need to be referred to at all, and also introduced several assert()s that helped me diagnose a few bugs (fixed too). llvm-svn: 120778 --- .../lldb/Expression/ClangExpressionDeclMap.h | 189 +++++++-- lldb/source/Expression/ClangASTSource.cpp | 2 +- .../Expression/ClangExpressionDeclMap.cpp | 362 ++++++++++-------- .../source/Expression/ClangUserExpression.cpp | 19 +- .../Expression/ClangUtilityFunction.cpp | 6 +- 5 files changed, 386 insertions(+), 192 deletions(-) diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index 2c4d0c5ce458..e089ab4c68dc 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -71,18 +71,28 @@ public: /// Constructor /// /// Initializes class variabes. - /// - /// @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); + 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. + //------------------------------------------------------------------ + void WillParse(ExecutionContext &exe_ctx); + + //------------------------------------------------------------------ + /// Disable the state needed for parsing and IR transformation. + //------------------------------------------------------------------ + void DidParse(); + //------------------------------------------------------------------ /// [Used by IRForTarget] Get a new result variable name of the form /// $n, where n is a natural number starting with 0. @@ -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. + 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. + //---------------------------------------------------------------------- + /// 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 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 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 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(); + } - bool m_ignore_lookups; ///< True during an import when we should be ignoring type lookups. - //------------------------------------------------------------------ /// 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 95a35b9b098a..09d6ed080327 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 00e33bef10b0..bd68b7b0439b 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() -{ - 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_persistent_vars->Size(); - pvar_index < num_pvars; - ++pvar_index) - { - ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index)); - pvar.DisableParserVars(); - } - - if (m_materialized_location) - { -//#define SINGLE_STEP_EXPRESSIONS +{ + DidDematerialize(); + DisableStructVars(); +} -#ifndef SINGLE_STEP_EXPRESSIONS - m_exe_ctx.process->DeallocateMemory(m_materialized_location); -#endif - m_materialized_location = 0; +void ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx) +{ + EnableParserVars(); + m_parser_vars->m_exe_ctx = &exe_ctx; + + if (exe_ctx.frame) + m_parser_vars->m_sym_ctx = exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything); + + if (exe_ctx.process) + m_parser_vars->m_persistent_vars = &exe_ctx.process->GetPersistentVariables(); +} + +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 location_value(GetVariableValue(*exe_ctx, + std::auto_ptr 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 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 7e5b40da7d79..6a980db293b1 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 0080347543b2..0c9d90a2b579 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())