diff options
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionDeclMap.h | 11 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionVariable.h | 326 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/ClangPersistentVariables.h | 177 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectExpression.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 29 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionVariable.cpp | 169 | ||||
-rw-r--r-- | lldb/source/Expression/ClangPersistentVariables.cpp | 132 | ||||
-rw-r--r-- | lldb/source/Expression/DWARFExpression.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Expression/IRForTarget.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Expression/IRToDWARF.cpp | 2 |
10 files changed, 450 insertions, 402 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index f9b018a6160..59111caa696 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -21,6 +21,7 @@ // Project includes #include "lldb/Core/ClangForward.h" #include "lldb/Core/Value.h" +#include "lldb/Expression/ClangExpressionVariable.h" #include "lldb/Symbol/TaggedASTType.h" namespace llvm { @@ -30,7 +31,7 @@ namespace llvm { namespace lldb_private { -class ClangPersistentVariable; +class ClangExpressionVariables; class ClangPersistentVariables; class Error; class Function; @@ -301,7 +302,7 @@ public: /// The execution context from which to read the struct. /// /// @param[out] result - /// A ClangPersistentVariable containing the result of the + /// A ClangExpressionVariable containing the result of the /// expression, for potential re-use. /// /// @param[in] error @@ -312,7 +313,7 @@ public: /// True on success; false otherwise. //------------------------------------------------------------------ bool Dematerialize(ExecutionContext *exe_ctx, - ClangPersistentVariable *&result, + ClangExpressionVariable *&result, Error &error); //------------------------------------------------------------------ @@ -487,7 +488,7 @@ private: /// @param[in] pvar /// The persistent variable that needs a Decl. //------------------------------------------------------------------ - void AddOneVariable(NameSearchContext &context, ClangPersistentVariable *pvar); + void AddOneVariable(NameSearchContext &context, ClangExpressionVariable *pvar); //------------------------------------------------------------------ /// Use the NameSearchContext to generate a Decl for the given @@ -545,7 +546,7 @@ private: //------------------------------------------------------------------ bool DoMaterialize (bool dematerialize, ExecutionContext *exe_ctx, - ClangPersistentVariable **result, + ClangExpressionVariable **result, Error &err); //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Expression/ClangExpressionVariable.h b/lldb/include/lldb/Expression/ClangExpressionVariable.h index 6461932e969..5c3377f80e1 100644 --- a/lldb/include/lldb/Expression/ClangExpressionVariable.h +++ b/lldb/include/lldb/Expression/ClangExpressionVariable.h @@ -15,92 +15,312 @@ #include <stdint.h> // C++ Includes +#include <string> #include <vector> // Other libraries and framework includes // Project includes #include "lldb/Core/ClangForward.h" -#include "lldb/Core/Value.h" +#include "lldb/Symbol/TaggedASTType.h" + +namespace llvm { + class Value; +} namespace lldb_private { + +class DataBufferHeap; +class ExecutionContext; +class Stream; +class Value; //---------------------------------------------------------------------- -/// @class ClangExpressionVariableList ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" -/// @brief Manages local variables that the expression interpreter uses. +/// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" +/// @brief Encapsulates one variable for the expression parser. +/// +/// The expression parser uses variables in three different contexts: +/// +/// First, it stores persistent variables along with the process for use +/// in expressions. These persistent variables contain their own data +/// and are typed. /// -/// The DWARF interpreter, when interpreting expressions, occasionally -/// needs to interact with chunks of memory corresponding to local variable -/// values. These locals are distinct from the externally-defined values -/// handled by ClangExpressionDeclMap, and do not persist between expressions -/// so they are not handled by ClangPersistentVariables. They are kept in a -/// list, which is encapsulated in ClangEpxressionVariableList. +/// Second, in an interpreted expression, it stores the local variables +/// for the expression along with the expression. These variables +/// contain their own data and are typed. +/// +/// Third, in a JIT-compiled expression, it stores the variables that +/// the expression needs to have materialized and dematerialized at each +/// execution. These do not contain their own data but are named and +/// typed. +/// +/// This class supports all of these use cases using simple type +/// polymorphism, and provides necessary support methods. Its interface +/// is RTTI-neutral. //---------------------------------------------------------------------- -class ClangExpressionVariableList +struct ClangExpressionVariable { -public: + ClangExpressionVariable(); + + ClangExpressionVariable(const ClangExpressionVariable &cev); + //---------------------------------------------------------------------- - /// Constructor + /// If the variable contains its own data, make a Value point at it + /// + /// @param[in] value + /// The value to point at the data. + /// + /// @return + /// True on success; false otherwise (in particular, if this variable + /// does not contain its own data). //---------------------------------------------------------------------- - ClangExpressionVariableList(); + bool + PointValueAtData(Value &value); //---------------------------------------------------------------------- - /// Destructor + /// The following values should stay valid for the life of the variable //---------------------------------------------------------------------- - ~ClangExpressionVariableList(); - + std::string m_name; ///< The name of the variable + TypeFromUser m_user_type; ///< The type of the variable according to some LLDB context; NULL if the type hasn't yet been migrated to one + + //---------------------------------------------------------------------- + /// The following values should not live beyond parsing + //---------------------------------------------------------------------- + struct ParserVars { + TypeFromParser m_parser_type; ///< The type of the variable according to the parser + const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable + llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue + }; + std::auto_ptr<ParserVars> m_parser_vars; + + //---------------------------------------------------------------------- + /// Make this variable usable by the parser by allocating space for + /// 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 are valid if the variable is used by JIT code + //---------------------------------------------------------------------- + struct JITVars { + off_t m_alignment; ///< The required alignment of the variable, in bytes + size_t m_size; ///< The space required for the variable, in bytes + off_t m_offset; ///< The offset of the variable in the struct, in bytes + }; + std::auto_ptr<JITVars> m_jit_vars; + + //---------------------------------------------------------------------- + /// Make this variable usable for materializing for the JIT by allocating + /// space for JIT-specific variables + //---------------------------------------------------------------------- + void EnableJITVars() + { + if (!m_jit_vars.get()) + m_jit_vars.reset(new struct JITVars); + } + + //---------------------------------------------------------------------- + /// Deallocate JIT-specific variables + //---------------------------------------------------------------------- + void DisableJITVars() + { + m_jit_vars.reset(); + } + + //---------------------------------------------------------------------- + /// The following values are valid if the value contains its own data + //---------------------------------------------------------------------- + struct DataVars { + lldb_private::DataBufferHeap *m_data; ///< The heap area allocated to contain this variable's data. Responsibility for deleting this falls to whoever uses the variable last + }; + std::auto_ptr<DataVars> m_data_vars; + + //---------------------------------------------------------------------- + /// Make this variable usable for storing its data internally by + /// allocating data-specific variables + //---------------------------------------------------------------------- + void EnableDataVars() + { + if (!m_jit_vars.get()) + m_data_vars.reset(new struct DataVars); + } + + //---------------------------------------------------------------------- + /// Deallocate data-specific variables + //---------------------------------------------------------------------- + void DisableDataVars(); + + //---------------------------------------------------------------------- + /// Return the variable's size in bytes + //---------------------------------------------------------------------- + size_t Size () + { + return (m_user_type.GetClangTypeBitWidth () + 7) / 8; + } + //---------------------------------------------------------------------- - /// Get or create the chunk of data corresponding to a given VarDecl. + /// Pretty-print the variable, assuming it contains its own data /// - /// @param[in] var_decl - /// The Decl for which a chunk of memory is to be allocated. + /// @param[in] output_stream + /// The stream to pretty-print on. /// - /// @param[out] idx - /// The index of the Decl in the list of variables. + /// @param[in] exe_ctx + /// The execution context to use when resolving the contents of the + /// variable. /// - /// @param[in] can_create - /// True if the memory should be created if necessary. + /// @param[in] format + /// The format to print the variable in + /// + /// @param[in] show_types + /// If true, print the type of the variable + /// + /// @param[in] show_summary + /// If true, print a summary of the variable's type + /// + /// @param[in] verbose + /// If true, be verbose in printing the value of the variable /// /// @return - /// A Value for the allocated memory. NULL if the Decl couldn't be - /// found and can_create was false, or if some error occurred during - /// allocation. - //---------------------------------------------------------------------- - Value * - GetVariableForVarDecl (const clang::VarDecl *var_decl, - uint32_t& idx, - bool can_create); + /// An Error describing the result of the operation. If Error::Success() + /// returns true, the pretty printing completed successfully. + //---------------------------------------------------------------------- + Error Print(Stream &output_stream, + ExecutionContext &exe_ctx, + lldb::Format format, + bool show_types, + bool show_summary, + bool verbose); +}; +//---------------------------------------------------------------------- +/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" +/// @brief Manages variables that the expression parser uses. +/// +/// The expression parser uses variable lists in various contexts, as +/// discuessed at ClangExpressionVariable. This abstract class contains +/// the basic functions for managing a list of variables. Its subclasses +/// store pointers to variables or variables, depending on whether they +/// are backing stores or merely transient repositories. +//---------------------------------------------------------------------- +class ClangExpressionVariableListBase +{ +public: + //---------------------------------------------------------------------- + /// Return the number of variables in the list + //---------------------------------------------------------------------- + virtual uint64_t Size() = 0; + //---------------------------------------------------------------------- - /// Get the chunk of data corresponding to a given index into the list. + /// Return the variable at the given index in the list + //---------------------------------------------------------------------- + virtual ClangExpressionVariable &VariableAtIndex(uint64_t index) = 0; + + //---------------------------------------------------------------------- + /// Add a new variable and return its index + //---------------------------------------------------------------------- + virtual uint64_t AddVariable(ClangExpressionVariable& var) = 0; + + //---------------------------------------------------------------------- + /// Finds a variable by name in the list. /// - /// @param[in] idx - /// The index of the Decl in the list of variables. + /// @param[in] name + /// The name of the requested variable. /// /// @return - /// The value at the given index, or NULL if there is none. + /// The variable requested, or NULL if that variable is not in the list. + //---------------------------------------------------------------------- + ClangExpressionVariable *GetVariable (const char *name) + { + for (uint64_t index = 0, size = Size(); index < size; ++index) + { + ClangExpressionVariable &candidate (VariableAtIndex(index)); + if (!candidate.m_name.compare(name)) + return &candidate; + } + return NULL; + } +}; + +//---------------------------------------------------------------------- +/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" +/// @brief A list of variable references. +/// +/// This class stores references to variables stored elsewhere. +//---------------------------------------------------------------------- +class ClangExpressionVariableList : public ClangExpressionVariableListBase +{ +public: //---------------------------------------------------------------------- - Value * - GetVariableAtIndex (uint32_t idx); + /// Implementation of methods in ClangExpressionVariableListBase + //---------------------------------------------------------------------- + uint64_t Size() + { + return m_variables.size(); + } + + ClangExpressionVariable &VariableAtIndex(uint64_t index) + { + return *m_variables[index]; + } + + uint64_t AddVariable(ClangExpressionVariable &var) + { + m_variables.push_back(&var); + return m_variables.size() - 1; + } private: + std::vector <ClangExpressionVariable*> m_variables; +}; + +//---------------------------------------------------------------------- +/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" +/// @brief A list of variable references. +/// +/// This class stores variables internally, acting as the permanent store. +//---------------------------------------------------------------------- +class ClangExpressionVariableStore : public ClangExpressionVariableListBase +{ +public: //---------------------------------------------------------------------- - /// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" - /// @brief Manages one local variable for the expression interpreter. - /// - /// The expression interpreter uses specially-created Values to hold its - /// temporary locals. These Values contain data buffers holding enough - /// space to contain a variable of the appropriate type. The VarDecls - /// are only used while creating the list and generating the DWARF code for - /// an expression; when interpreting the DWARF, the variables are identified - /// only by their index into the list of variables. - //---------------------------------------------------------------------- - struct ClangExpressionVariable + /// Implementation of methods in ClangExpressionVariableListBase + //---------------------------------------------------------------------- + uint64_t Size() { - const clang::VarDecl *m_var_decl; ///< The VarDecl corresponding to the parsed local. - Value *m_value; ///< The LLDB Value containing the data for the local. - }; + return m_variables.size(); + } + + ClangExpressionVariable &VariableAtIndex(uint64_t index) + { + return m_variables[index]; + } - typedef std::vector<ClangExpressionVariable> Variables; - Variables m_variables; ///< The list of variables used by the expression. + uint64_t AddVariable(ClangExpressionVariable &var) + { + m_variables.push_back(var); + return m_variables.size() - 1; + } + + //---------------------------------------------------------------------- + /// Create a new variable in the list and return its index + //---------------------------------------------------------------------- + uint64_t CreateVariable() + { + m_variables.push_back(ClangExpressionVariable()); + return m_variables.size() - 1; + } +private: + std::vector <ClangExpressionVariable> m_variables; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Expression/ClangPersistentVariables.h b/lldb/include/lldb/Expression/ClangPersistentVariables.h index e49790a473a..202517c7af8 100644 --- a/lldb/include/lldb/Expression/ClangPersistentVariables.h +++ b/lldb/include/lldb/Expression/ClangPersistentVariables.h @@ -10,147 +10,12 @@ #ifndef liblldb_ClangPersistentVariables_h_ #define liblldb_ClangPersistentVariables_h_ -#include "lldb/lldb-forward-rtti.h" -#include "lldb/Core/ConstString.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Symbol/TaggedASTType.h" - -#include <map> -#include <string> +#include "lldb/Expression/ClangExpressionVariable.h" namespace lldb_private { //---------------------------------------------------------------------- -/// @class ClangPersistentVariable ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h" -/// @brief Encapsulates a persistent value that need to be preserved between expression invocations. -/// -/// Although expressions can define truly local variables, frequently the user -/// wants to create variables whose values persist between invocations of the -/// expression. These variables are also created each time an expression returns -/// a result. The ClangPersistentVariable class encapsulates such a variable, -/// which contains data and a type. -//---------------------------------------------------------------------- -class ClangPersistentVariable -{ - friend class ClangPersistentVariables; -public: - //---------------------------------------------------------------------- - /// Constructor - //---------------------------------------------------------------------- - ClangPersistentVariable () : - m_name(), - m_user_type(), - m_data() - { - } - - //---------------------------------------------------------------------- - /// Copy constructor - /// - /// @param[in] pv - /// The persistent variable to make a copy of. - //---------------------------------------------------------------------- - ClangPersistentVariable (const ClangPersistentVariable &pv) : - m_name(pv.m_name), - m_user_type(pv.m_user_type), - m_data(pv.m_data) - { - } - - //---------------------------------------------------------------------- - /// Assignment operator - //---------------------------------------------------------------------- - ClangPersistentVariable &operator=(const ClangPersistentVariable &pv) - { - m_name = pv.m_name; - m_user_type = pv.m_user_type; - m_data = pv.m_data; - return *this; - } - - //---------------------------------------------------------------------- - /// Return the number of bytes required to store the variable - //---------------------------------------------------------------------- - size_t Size () - { - return (m_user_type.GetClangTypeBitWidth () + 7) / 8; - } - - //---------------------------------------------------------------------- - /// Return the variable's contents, in local memory but stored according - /// to the target's byte order - //---------------------------------------------------------------------- - uint8_t *Data () - { - return m_data->GetBytes(); - } - - //---------------------------------------------------------------------- - /// Return the variable's contents, in local memory but stored in a form - /// (byte order, etc.) appropriate for copying into the target's memory - //---------------------------------------------------------------------- - TypeFromUser Type () - { - return m_user_type; - } - - //---------------------------------------------------------------------- - /// Pretty-print the variable - /// - /// @param[in] output_stream - /// The stream to pretty-print on. - /// - /// @param[in] exe_ctx - /// The execution context to use when resolving the contents of the - /// variable. - /// - /// @param[in] format - /// The format to print the variable in - /// - /// @param[in] show_types - /// If true, print the type of the variable - /// - /// @param[in] show_summary - /// If true, print a summary of the variable's type - /// - /// @param[in] verbose - /// If true, be verbose in printing the value of the variable - /// - /// @return - /// An Error describing the result of the operation. If Error::Success() - /// returns true, the pretty printing completed successfully. - //---------------------------------------------------------------------- - Error Print(Stream &output_stream, - ExecutionContext &exe_ctx, - lldb::Format format, - bool show_types, - bool show_summary, - bool verbose); -private: - //---------------------------------------------------------------------- - /// Constructor - /// - /// @param[in] name - /// The name of the variable, usually of the form $foo. - /// - /// @param[in] user_type - /// The type of the variable, in an AST context that will survive - /// as long as the variable. - //---------------------------------------------------------------------- - ClangPersistentVariable (ConstString name, TypeFromUser user_type) - { - m_name = name; - m_user_type = user_type; - m_data = lldb::DataBufferSP(new DataBufferHeap(Size(), 0)); - } - - ConstString m_name; ///< The name of the variable, usually $foo. - TypeFromUser m_user_type; ///< The type of the variable. Must be valid as long as the variable exists. - lldb::DataBufferSP m_data; ///< A shared pointer to the variable's data. This is a shared pointer so the variable object can move around without excess copying. -}; - -//---------------------------------------------------------------------- /// @class ClangPersistentVariables ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h" /// @brief Manages persistent values that need to be preserved between expression invocations. /// @@ -158,55 +23,27 @@ private: /// ClangPersistentVariable for more discussion. Also provides an increasing, /// 0-based counter for naming result variables. //---------------------------------------------------------------------- -class ClangPersistentVariables +class ClangPersistentVariables : public ClangExpressionVariableStore { public: //---------------------------------------------------------------------- - /// Create a single named persistent variable - /// - /// @param[in] name - /// The desired name for the newly-created variable. - /// - /// @param[in] user_type - /// The desired type for the variable, in a context that will survive - /// as long as ClangPersistentVariables. - /// - /// @return - /// The newly-created persistent variable or NULL if a variable with the - /// same name already exists. - //---------------------------------------------------------------------- - ClangPersistentVariable *CreateVariable (ConstString name, TypeFromUser user_type); - - //---------------------------------------------------------------------- - /// Finds a persistent variable in the list. - /// - /// @param[in] name - /// The name of the requested variable. - /// - /// @return - /// The variable requested, or NULL if that variable is not in the list. - //---------------------------------------------------------------------- - ClangPersistentVariable *GetVariable (ConstString name); - - //---------------------------------------------------------------------- /// Return the next entry in the sequence of strings "$0", "$1", ... for use /// naming result variables. /// /// @param[in] name /// A string to place the variable name in. //---------------------------------------------------------------------- - void GetNextResultName(std::string &name); + void GetNextResultName (std::string &name); //---------------------------------------------------------------------- /// Constructor //---------------------------------------------------------------------- ClangPersistentVariables (); + + bool CreatePersistentVariable(const char *name, + TypeFromUser user_type); private: - typedef std::map <ConstString, ClangPersistentVariable> PVarMap; - typedef PVarMap::iterator PVarIterator; - - PVarMap m_variables; ///< The backing store for the list of variables. - uint64_t m_result_counter; ///< The counter used by GetNextResultName(). + uint64_t m_result_counter; ///< The counter used by GetNextResultName(). }; } diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index 12e99e26f56..af1041002b6 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -252,7 +252,7 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream bool success; bool canInterpret = false; - ClangPersistentVariable *expr_result = 0; + ClangExpressionVariable *expr_result = 0; Error expr_error; canInterpret = clang_expr.ConvertIRToDWARF (expr_local_vars, dwarf_opcodes); diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 845d1c0d881..8cacc1fae90 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -101,14 +101,7 @@ ClangExpressionDeclMap::AddPersistentVariable (const char *name, TypeFromParser parser_type.GetOpaqueQualType()), context); - ConstString const_name(name); - - ClangPersistentVariable *pvar = m_persistent_vars->CreateVariable(const_name, user_type); - - if (!pvar) - return false; - - return true; + return m_persistent_vars->CreatePersistentVariable (name, user_type); } bool @@ -294,7 +287,7 @@ ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx, bool ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx, - ClangPersistentVariable *&result, + ClangExpressionVariable *&result, Error &err) { return DoMaterialize(true, exe_ctx, &result, err); @@ -368,7 +361,7 @@ ClangExpressionDeclMap::DumpMaterializedStruct(ExecutionContext *exe_ctx, bool ClangExpressionDeclMap::DoMaterialize (bool dematerialize, ExecutionContext *exe_ctx, - ClangPersistentVariable **result, + ClangExpressionVariable **result, Error &err) { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); @@ -451,7 +444,7 @@ ClangExpressionDeclMap::DoMaterialize (bool dematerialize, if (log) log->PutCString("Returning result PVar"); - *result = m_persistent_vars->GetVariable(ConstString(m_result_name.c_str())); + *result = m_persistent_vars->GetVariable(m_result_name.c_str()); if (!*result) { @@ -506,7 +499,7 @@ ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize, if (log) log->Printf("Found persistent variable %s", name); - ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name))); + ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name)); if (!pvar) { @@ -515,7 +508,11 @@ ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize, } size_t pvar_size = pvar->Size(); - uint8_t *pvar_data = pvar->Data(); + + if (!pvar->m_data_vars.get()) + return false; + + uint8_t *pvar_data = pvar->m_data_vars->m_data->GetBytes(); Error error; if (dematerialize) @@ -779,7 +776,7 @@ ClangExpressionDeclMap::GetDecls(NameSearchContext &context, if (var) AddOneVariable(context, var); - ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name))); + ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name)); if (pvar) AddOneVariable(context, pvar); @@ -927,9 +924,9 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, - ClangPersistentVariable *pvar) + ClangExpressionVariable *pvar) { - TypeFromUser user_type = pvar->Type(); + TypeFromUser user_type = pvar->m_user_type; TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(), user_type.GetASTContext(), diff --git a/lldb/source/Expression/ClangExpressionVariable.cpp b/lldb/source/Expression/ClangExpressionVariable.cpp index dce0316983c..d41e6203d3b 100644 --- a/lldb/source/Expression/ClangExpressionVariable.cpp +++ b/lldb/source/Expression/ClangExpressionVariable.cpp @@ -14,74 +14,155 @@ // Other libraries and framework includes // Project includes #include "clang/AST/ASTContext.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/Value.h" using namespace lldb_private; using namespace clang; -ClangExpressionVariableList::ClangExpressionVariableList() : - m_variables() +ClangExpressionVariable::ClangExpressionVariable() { + m_name = ""; + m_user_type = TypeFromUser(NULL, NULL); + m_parser_vars.reset(NULL); + m_jit_vars.reset(NULL); + m_data_vars.reset(NULL); } -ClangExpressionVariableList::~ClangExpressionVariableList() +void ClangExpressionVariable::DisableDataVars() { - uint32_t num_variables = m_variables.size(); - uint32_t var_index; - - for (var_index = 0; var_index < num_variables; ++var_index) - delete m_variables[var_index].m_value; + if (m_data_vars.get() && m_data_vars->m_data) + delete m_data_vars->m_data; + m_data_vars.reset(); } -Value * -ValueForDecl(const VarDecl *var_decl) +Error +ClangExpressionVariable::Print (Stream &output_stream, + ExecutionContext &exe_ctx, + lldb::Format format, + bool show_types, + bool show_summary, + bool verbose) { - Value *ret = new Value; - - ret->SetContext(Value::eContextTypeOpaqueClangQualType, - var_decl->getType().getAsOpaquePtr()); + Error err; + + if (!m_data_vars.get() || !m_data_vars->m_data) + { + err.SetErrorToGenericError(); + err.SetErrorStringWithFormat("Variable doesn't contain a value"); + return err; + } + + Value val; + + clang::ASTContext *ast_context = m_user_type.GetASTContext(); + + val.SetContext (Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType ()); + val.SetValueType (Value::eValueTypeHostAddress); + val.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes (); + + val.ResolveValue (&exe_ctx, ast_context); + + if (val.GetContextType () == Value::eContextTypeInvalid && + val.GetValueType () == Value::eValueTypeScalar && + format == lldb::eFormatDefault) + { + // The expression result is just a scalar with no special formatting + val.GetScalar ().GetValue (&output_stream, show_types); + output_stream.EOL (); + return err; + } + + // The expression result is more complex and requires special handling + DataExtractor data; + Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0); + + if (!expr_error.Success ()) + { + err.SetErrorToGenericError (); + err.SetErrorStringWithFormat ("Couldn't resolve variable value: %s", expr_error.AsCString ()); + return err; + } - uint64_t bit_width = var_decl->getASTContext().getTypeSize(var_decl->getType()); + if (format == lldb::eFormatDefault) + format = val.GetValueDefaultFormat (); - uint32_t byte_size = (bit_width + 7 ) / 8; + void *clang_type = val.GetValueOpaqueClangQualType (); - ret->ResizeData(byte_size); + output_stream.Printf("%s = ", m_name.c_str()); - return ret; + if (clang_type) + { + if (show_types) + output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString()); + + ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to + clang_type, // The opaque clang type we want to dump that value of + &exe_ctx, // The execution context for memory and variable access + &output_stream, // Stream to dump to + format, // Format to use when dumping + data, // A buffer containing the bytes for the clang type + 0, // Byte offset within "data" where value is + data.GetByteSize (), // Size in bytes of the value we are dumping + 0, // Bitfield bit size + 0, // Bitfield bit offset + show_types, // Show types? + show_summary, // Show summary? + verbose, // Debug logging output? + UINT32_MAX); // Depth to dump in case this is an aggregate type + } + else + { + data.Dump (&output_stream, // Stream to dump to + 0, // Byte offset within "data" + format, // Format to use when dumping + data.GetByteSize (), // Size in bytes of each item we are dumping + 1, // Number of items to dump + UINT32_MAX, // Number of items per line + LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context + 0, // Bitfield bit size + 0); // Bitfield bit offset + } + + output_stream.EOL(); + + return err; } -Value * -ClangExpressionVariableList::GetVariableForVarDecl (const VarDecl *var_decl, uint32_t& idx, bool can_create) +ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &cev) : + m_name(cev.m_name), + m_user_type(cev.m_user_type) { - uint32_t num_variables = m_variables.size(); - uint32_t var_index; - - for (var_index = 0; var_index < num_variables; ++var_index) + if (cev.m_parser_vars.get()) { - if (m_variables[var_index].m_var_decl == var_decl) - { - idx = var_index; - return m_variables[var_index].m_value; - } + m_parser_vars.reset(new struct ParserVars); + *m_parser_vars.get() = *cev.m_parser_vars.get(); } - - if (!can_create) - return NULL; - - idx = m_variables.size(); - ClangExpressionVariable val; - val.m_var_decl = var_decl; - val.m_value = ValueForDecl(var_decl); - m_variables.push_back(val); + if (cev.m_jit_vars.get()) + { + m_jit_vars.reset(new struct JITVars); + *m_jit_vars.get() = *cev.m_jit_vars.get(); + } - return m_variables.back().m_value; + if (cev.m_data_vars.get()) + { + m_data_vars.reset(new struct DataVars); + *m_data_vars.get() = *cev.m_data_vars.get(); + } } -Value * -ClangExpressionVariableList::GetVariableAtIndex (uint32_t idx) +bool +ClangExpressionVariable::PointValueAtData(Value &value) { - if (idx < m_variables.size()) - return m_variables[idx].m_value; + if (!m_data_vars.get()) + return false; + + value.SetContext(Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType()); + value.SetValueType(Value::eValueTypeHostAddress); + value.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes(); - return NULL; + return true; } diff --git a/lldb/source/Expression/ClangPersistentVariables.cpp b/lldb/source/Expression/ClangPersistentVariables.cpp index 7e1664889cc..f014811fb17 100644 --- a/lldb/source/Expression/ClangPersistentVariables.cpp +++ b/lldb/source/Expression/ClangPersistentVariables.cpp @@ -15,119 +15,10 @@ using namespace lldb_private; -Error -ClangPersistentVariable::Print (Stream &output_stream, - ExecutionContext &exe_ctx, - lldb::Format format, - bool show_types, - bool show_summary, - bool verbose) -{ - Error err; - - Value val; - - clang::ASTContext *ast_context = m_user_type.GetASTContext(); - - val.SetContext (Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType ()); - val.SetValueType (Value::eValueTypeHostAddress); - val.GetScalar() = (uint64_t)Data (); - - val.ResolveValue (&exe_ctx, ast_context); - - if (val.GetContextType () == Value::eContextTypeInvalid && - val.GetValueType () == Value::eValueTypeScalar && - format == lldb::eFormatDefault) - { - // The expression result is just a scalar with no special formatting - val.GetScalar ().GetValue (&output_stream, show_types); - output_stream.EOL (); - return err; - } - - // The expression result is more complext and requires special handling - DataExtractor data; - Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0); - - if (!expr_error.Success ()) - { - err.SetErrorToGenericError (); - err.SetErrorStringWithFormat ("Couldn't resolve result value: %s", expr_error.AsCString ()); - return err; - } - - if (format == lldb::eFormatDefault) - format = val.GetValueDefaultFormat (); - - void *clang_type = val.GetValueOpaqueClangQualType (); - - output_stream.Printf("%s = ", m_name.AsCString("<anonymous>")); - - if (clang_type) - { - if (show_types) - output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString()); - - ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to - clang_type, // The opaque clang type we want to dump that value of - &exe_ctx, // The execution context for memory and variable access - &output_stream, // Stream to dump to - format, // Format to use when dumping - data, // A buffer containing the bytes for the clang type - 0, // Byte offset within "data" where value is - data.GetByteSize (), // Size in bytes of the value we are dumping - 0, // Bitfield bit size - 0, // Bitfield bit offset - show_types, // Show types? - show_summary, // Show summary? - verbose, // Debug logging output? - UINT32_MAX); // Depth to dump in case this is an aggregate type - } - else - { - data.Dump (&output_stream, // Stream to dump to - 0, // Byte offset within "data" - format, // Format to use when dumping - data.GetByteSize (), // Size in bytes of each item we are dumping - 1, // Number of items to dump - UINT32_MAX, // Number of items per line - LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context - 0, // Bitfield bit size - 0); // Bitfield bit offset - } - - output_stream.EOL(); - - return err; -} - ClangPersistentVariables::ClangPersistentVariables () : - m_variables(), - m_result_counter(0) + ClangExpressionVariableStore() { -} - -ClangPersistentVariable * -ClangPersistentVariables::CreateVariable (ConstString name, - TypeFromUser user_type) -{ - ClangPersistentVariable new_var(name, user_type); - - if (m_variables.find(name) != m_variables.end()) - return NULL; - - m_variables[name] = new_var; - - return &m_variables[name]; -} - -ClangPersistentVariable * -ClangPersistentVariables::GetVariable (ConstString name) -{ - if (m_variables.find(name) == m_variables.end()) - return NULL; - - return &m_variables[name]; + m_result_counter = 0; } void @@ -140,3 +31,22 @@ ClangPersistentVariables::GetNextResultName (std::string &name) name = s.GetString(); } + +bool +ClangPersistentVariables::CreatePersistentVariable(const char *name, + TypeFromUser user_type) +{ + if (GetVariable(name)) + return false; + + ClangExpressionVariable &pvar (VariableAtIndex(CreateVariable())); + + pvar.m_name = name; + pvar.m_user_type = user_type; + + pvar.EnableDataVars(); + + pvar.m_data_vars->m_data = new DataBufferHeap(pvar.Size(), 0); + + return true; +}
\ No newline at end of file diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 9609cad3731..ae6a903c968 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -2435,6 +2435,7 @@ DWARFExpression::Evaluate //---------------------------------------------------------------------- case DW_OP_APPLE_expr_local: { + /* uint32_t idx = opcodes.GetULEB128(&offset); if (expr_locals == NULL) { @@ -2453,6 +2454,7 @@ DWARFExpression::Evaluate stack.push_back(*proxy); delete proxy; //stack.back().SetContext (Value::eContextTypeOpaqueClangQualType, expr_local_variable->GetOpaqueClangQualType()); + */ } break; diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp index c3fce6fbbb0..2c0f86c4120 100644 --- a/lldb/source/Expression/IRForTarget.cpp +++ b/lldb/source/Expression/IRForTarget.cpp @@ -32,7 +32,7 @@ static char ID; IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, const TargetData *target_data) : - ModulePass(ID), + ModulePass(&ID), m_decl_map(decl_map), m_target_data(target_data), m_sel_registerName(NULL) diff --git a/lldb/source/Expression/IRToDWARF.cpp b/lldb/source/Expression/IRToDWARF.cpp index db38e8e53d2..121a47c171e 100644 --- a/lldb/source/Expression/IRToDWARF.cpp +++ b/lldb/source/Expression/IRToDWARF.cpp @@ -29,7 +29,7 @@ static char ID; IRToDWARF::IRToDWARF(lldb_private::ClangExpressionVariableList &variable_list, lldb_private::ClangExpressionDeclMap *decl_map, lldb_private::StreamString &strm) : - ModulePass(ID), + ModulePass(&ID), m_variable_list(variable_list), m_decl_map(decl_map), m_strm(strm) |