diff options
-rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionDeclMap.h | 189 | ||||
-rw-r--r-- | lldb/source/Expression/ClangASTSource.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 356 | ||||
-rw-r--r-- | lldb/source/Expression/ClangUserExpression.cpp | 19 | ||||
-rw-r--r-- | lldb/source/Expression/ClangUtilityFunction.cpp | 6 |
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()) |