| //===-- ClangUserExpression.h -----------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef liblldb_ClangUserExpression_h_ |
| #define liblldb_ClangUserExpression_h_ |
| |
| // C Includes |
| // C++ Includes |
| #include <string> |
| #include <map> |
| #include <memory> |
| #include <vector> |
| |
| // Other libraries and framework includes |
| // Project includes |
| |
| #include "lldb/lldb-forward.h" |
| #include "lldb/lldb-private.h" |
| #include "lldb/Core/ClangForward.h" |
| #include "lldb/Expression/ClangExpression.h" |
| #include "lldb/Expression/ClangExpressionVariable.h" |
| #include "lldb/Expression/IRForTarget.h" |
| #include "lldb/Expression/ProcessDataAllocator.h" |
| #include "lldb/Symbol/TaggedASTType.h" |
| #include "lldb/Target/ExecutionContext.h" |
| |
| #include "llvm/ExecutionEngine/JITMemoryManager.h" |
| |
| namespace lldb_private |
| { |
| |
| //---------------------------------------------------------------------- |
| /// @class ClangUserExpression ClangUserExpression.h "lldb/Expression/ClangUserExpression.h" |
| /// @brief Encapsulates a single expression for use with Clang |
| /// |
| /// LLDB uses expressions for various purposes, notably to call functions |
| /// and as a backend for the expr command. ClangUserExpression encapsulates |
| /// the objects needed to parse and interpret or JIT an expression. It |
| /// uses the Clang parser to produce LLVM IR from the expression. |
| //---------------------------------------------------------------------- |
| class ClangUserExpression : public ClangExpression |
| { |
| public: |
| typedef STD_SHARED_PTR(ClangUserExpression) ClangUserExpressionSP; |
| |
| //------------------------------------------------------------------ |
| /// Constructor |
| /// |
| /// @param[in] expr |
| /// The expression to parse. |
| /// |
| /// @param[in] expr_prefix |
| /// If non-NULL, a C string containing translation-unit level |
| /// definitions to be included when the expression is parsed. |
| /// |
| /// @param[in] language |
| /// If not eLanguageTypeUnknown, a language to use when parsing |
| /// the expression. Currently restricted to those languages |
| /// supported by Clang. |
| /// |
| /// @param[in] desired_type |
| /// If not eResultTypeAny, the type to use for the expression |
| /// result. |
| //------------------------------------------------------------------ |
| ClangUserExpression (const char *expr, |
| const char *expr_prefix, |
| lldb::LanguageType language, |
| ResultType desired_type); |
| |
| //------------------------------------------------------------------ |
| /// Destructor |
| //------------------------------------------------------------------ |
| virtual |
| ~ClangUserExpression (); |
| |
| //------------------------------------------------------------------ |
| /// Parse the expression |
| /// |
| /// @param[in] error_stream |
| /// A stream to print parse errors and warnings to. |
| /// |
| /// @param[in] exe_ctx |
| /// The execution context to use when looking up entities that |
| /// are needed for parsing (locations of functions, types of |
| /// variables, persistent variables, etc.) |
| /// |
| /// @param[in] execution_policy |
| /// Determines whether interpretation is possible or mandatory. |
| /// |
| /// @param[in] keep_result_in_memory |
| /// True if the resulting persistent variable should reside in |
| /// target memory, if applicable. |
| /// |
| /// @return |
| /// True on success (no errors); false otherwise. |
| //------------------------------------------------------------------ |
| bool |
| Parse (Stream &error_stream, |
| ExecutionContext &exe_ctx, |
| lldb_private::ExecutionPolicy execution_policy, |
| bool keep_result_in_memory); |
| |
| //------------------------------------------------------------------ |
| /// Execute the parsed expression |
| /// |
| /// @param[in] error_stream |
| /// A stream to print errors to. |
| /// |
| /// @param[in] exe_ctx |
| /// The execution context to use when looking up entities that |
| /// are needed for parsing (locations of variables, etc.) |
| /// |
| /// @param[in] discard_on_error |
| /// If true, and the execution stops before completion, we unwind the |
| /// function call, and return the program state to what it was before the |
| /// execution. If false, we leave the program in the stopped state. |
| /// |
| /// @param[in] shared_ptr_to_me |
| /// This is a shared pointer to this ClangUserExpression. This is |
| /// needed because Execute can push a thread plan that will hold onto |
| /// the ClangUserExpression for an unbounded period of time. So you |
| /// need to give the thread plan a reference to this object that can |
| /// keep it alive. |
| /// |
| /// @param[in] result |
| /// A pointer to direct at the persistent variable in which the |
| /// expression's result is stored. |
| /// |
| /// @return |
| /// A Process::Execution results value. |
| //------------------------------------------------------------------ |
| ExecutionResults |
| Execute (Stream &error_stream, |
| ExecutionContext &exe_ctx, |
| bool discard_on_error, |
| ClangUserExpressionSP &shared_ptr_to_me, |
| lldb::ClangExpressionVariableSP &result); |
| |
| ThreadPlan * |
| GetThreadPlanToExecuteJITExpression (Stream &error_stream, |
| ExecutionContext &exe_ctx); |
| |
| //------------------------------------------------------------------ |
| /// Apply the side effects of the function to program state. |
| /// |
| /// @param[in] error_stream |
| /// A stream to print errors to. |
| /// |
| /// @param[in] exe_ctx |
| /// The execution context to use when looking up entities that |
| /// are needed for parsing (locations of variables, etc.) |
| /// |
| /// @param[in] result |
| /// A pointer to direct at the persistent variable in which the |
| /// expression's result is stored. |
| /// |
| /// @param[in] function_stack_pointer |
| /// A pointer to the base of the function's stack frame. This |
| /// is used to determine whether the expession result resides in |
| /// memory that will still be valid, or whether it needs to be |
| /// treated as homeless for the purpose of future expressions. |
| /// |
| /// @return |
| /// A Process::Execution results value. |
| //------------------------------------------------------------------ |
| bool |
| FinalizeJITExecution (Stream &error_stream, |
| ExecutionContext &exe_ctx, |
| lldb::ClangExpressionVariableSP &result, |
| lldb::addr_t function_stack_pointer = LLDB_INVALID_ADDRESS); |
| |
| //------------------------------------------------------------------ |
| /// Return the string that the parser should parse. Must be a full |
| /// translation unit. |
| //------------------------------------------------------------------ |
| const char * |
| Text () |
| { |
| return m_transformed_text.c_str(); |
| } |
| |
| //------------------------------------------------------------------ |
| /// Return the string that the user typed. |
| //------------------------------------------------------------------ |
| const char * |
| GetUserText () |
| { |
| return m_expr_text.c_str(); |
| } |
| |
| //------------------------------------------------------------------ |
| /// Return the function name that should be used for executing the |
| /// expression. Text() should contain the definition of this |
| /// function. |
| //------------------------------------------------------------------ |
| const char * |
| FunctionName () |
| { |
| return "$__lldb_expr"; |
| } |
| |
| //------------------------------------------------------------------ |
| /// Return the language that should be used when parsing. To use |
| /// the default, return eLanguageTypeUnknown. |
| //------------------------------------------------------------------ |
| virtual lldb::LanguageType |
| Language () |
| { |
| return m_language; |
| } |
| |
| //------------------------------------------------------------------ |
| /// Return the object that the parser should use when resolving external |
| /// values. May be NULL if everything should be self-contained. |
| //------------------------------------------------------------------ |
| ClangExpressionDeclMap * |
| DeclMap () |
| { |
| return m_expr_decl_map.get(); |
| } |
| |
| //------------------------------------------------------------------ |
| /// Return the object that the parser should use when registering |
| /// local variables. May be NULL if the Expression doesn't care. |
| //------------------------------------------------------------------ |
| ClangExpressionVariableList * |
| LocalVariables () |
| { |
| return m_local_variables.get(); |
| } |
| |
| //------------------------------------------------------------------ |
| /// Return the object that the parser should allow to access ASTs. |
| /// May be NULL if the ASTs do not need to be transformed. |
| /// |
| /// @param[in] passthrough |
| /// The ASTConsumer that the returned transformer should send |
| /// the ASTs to after transformation. |
| //------------------------------------------------------------------ |
| clang::ASTConsumer * |
| ASTTransformer (clang::ASTConsumer *passthrough); |
| |
| //------------------------------------------------------------------ |
| /// Return the desired result type of the function, or |
| /// eResultTypeAny if indifferent. |
| //------------------------------------------------------------------ |
| virtual ResultType |
| DesiredResultType () |
| { |
| return m_desired_type; |
| } |
| |
| //------------------------------------------------------------------ |
| /// Return true if validation code should be inserted into the |
| /// expression. |
| //------------------------------------------------------------------ |
| bool |
| NeedsValidation () |
| { |
| return true; |
| } |
| |
| //------------------------------------------------------------------ |
| /// Return true if external variables in the expression should be |
| /// resolved. |
| //------------------------------------------------------------------ |
| bool |
| NeedsVariableResolution () |
| { |
| return true; |
| } |
| |
| //------------------------------------------------------------------ |
| /// Evaluate one expression and return its result. |
| /// |
| /// @param[in] exe_ctx |
| /// The execution context to use when evaluating the expression. |
| /// |
| /// @param[in] execution_policy |
| /// Determines whether or not to try using the IR interpreter to |
| /// avoid running the expression on the parser. |
| /// |
| /// @param[in] language |
| /// If not eLanguageTypeUnknown, a language to use when parsing |
| /// the expression. Currently restricted to those languages |
| /// supported by Clang. |
| /// |
| /// @param[in] discard_on_error |
| /// True if the thread's state should be restored in the case |
| /// of an error. |
| /// |
| /// @param[in] result_type |
| /// If not eResultTypeAny, the type of the desired result. Will |
| /// result in parse errors if impossible. |
| /// |
| /// @param[in] expr_cstr |
| /// A C string containing the expression to be evaluated. |
| /// |
| /// @param[in] expr_prefix |
| /// If non-NULL, a C string containing translation-unit level |
| /// definitions to be included when the expression is parsed. |
| /// |
| /// @param[in/out] result_valobj_sp |
| /// If execution is successful, the result valobj is placed here. |
| /// |
| /// @result |
| /// A Process::ExecutionResults value. eExecutionCompleted for success. |
| //------------------------------------------------------------------ |
| static ExecutionResults |
| Evaluate (ExecutionContext &exe_ctx, |
| lldb_private::ExecutionPolicy execution_policy, |
| lldb::LanguageType language, |
| ResultType desired_type, |
| bool discard_on_error, |
| const char *expr_cstr, |
| const char *expr_prefix, |
| lldb::ValueObjectSP &result_valobj_sp); |
| |
| static ExecutionResults |
| EvaluateWithError (ExecutionContext &exe_ctx, |
| lldb_private::ExecutionPolicy execution_policy, |
| lldb::LanguageType language, |
| ResultType desired_type, |
| bool discard_on_error, |
| const char *expr_cstr, |
| const char *expr_prefix, |
| lldb::ValueObjectSP &result_valobj_sp, |
| Error &error); |
| |
| static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression. |
| private: |
| //------------------------------------------------------------------ |
| /// Populate m_cplusplus and m_objetivec based on the environment. |
| //------------------------------------------------------------------ |
| |
| void |
| ScanContext (ExecutionContext &exe_ctx, |
| lldb_private::Error &err); |
| |
| bool |
| PrepareToExecuteJITExpression (Stream &error_stream, |
| ExecutionContext &exe_ctx, |
| lldb::addr_t &struct_address, |
| lldb::addr_t &object_ptr, |
| lldb::addr_t &cmd_ptr); |
| |
| bool |
| EvaluatedStatically () |
| { |
| return m_evaluated_statically; |
| } |
| |
| void |
| InstallContext (ExecutionContext &exe_ctx) |
| { |
| m_process_wp = exe_ctx.GetProcessSP(); |
| m_target_wp = exe_ctx.GetTargetSP(); |
| m_frame_wp = exe_ctx.GetFrameSP(); |
| } |
| |
| bool |
| LockAndCheckContext (ExecutionContext &exe_ctx, |
| lldb::TargetSP &target_sp, |
| lldb::ProcessSP &process_sp, |
| lldb::StackFrameSP &frame_sp) |
| { |
| target_sp = m_target_wp.lock(); |
| process_sp = m_process_wp.lock(); |
| frame_sp = m_frame_wp.lock(); |
| |
| if ((target_sp && target_sp.get() != exe_ctx.GetTargetPtr()) || |
| (process_sp && process_sp.get() != exe_ctx.GetProcessPtr()) || |
| (frame_sp && frame_sp.get() != exe_ctx.GetFramePtr())) |
| return false; |
| |
| return true; |
| } |
| |
| lldb::TargetWP m_target_wp; ///< The target used as the context for the expression. |
| lldb::ProcessWP m_process_wp; ///< The process used as the context for the expression. |
| lldb::StackFrameWP m_frame_wp; ///< The stack frame used as context for the expression. |
| |
| std::string m_expr_text; ///< The text of the expression, as typed by the user |
| std::string m_expr_prefix; ///< The text of the translation-level definitions, as provided by the user |
| lldb::LanguageType m_language; ///< The language to use when parsing (eLanguageTypeUnknown means use defaults) |
| bool m_allow_cxx; ///< True if the language allows C++. |
| bool m_allow_objc; ///< True if the language allows Objective-C. |
| std::string m_transformed_text; ///< The text of the expression, as send to the parser |
| ResultType m_desired_type; ///< The type to coerce the expression's result to. If eResultTypeAny, inferred from the expression. |
| |
| std::auto_ptr<ClangExpressionDeclMap> m_expr_decl_map; ///< The map to use when parsing and materializing the expression. |
| std::auto_ptr<ClangExpressionVariableList> m_local_variables; ///< The local expression variables, if the expression is DWARF. |
| std::auto_ptr<ProcessDataAllocator> m_data_allocator; ///< The allocator that the parser uses to place strings for use by JIT-compiled code. |
| |
| std::auto_ptr<ASTResultSynthesizer> m_result_synthesizer; ///< The result synthesizer, if one is needed. |
| |
| bool m_enforce_valid_object; ///< True if the expression parser should enforce the presence of a valid class pointer in order to generate the expression as a method. |
| bool m_cplusplus; ///< True if the expression is compiled as a C++ member function (true if it was parsed when exe_ctx was in a C++ method). |
| bool m_objectivec; ///< True if the expression is compiled as an Objective-C method (true if it was parsed when exe_ctx was in an Objective-C method). |
| bool m_static_method; ///< True if the expression is compiled as a static (or class) method (currently true if it was parsed when exe_ctx was in an Objective-C class method). |
| bool m_needs_object_ptr; ///< True if "this" or "self" must be looked up and passed in. False if the expression doesn't really use them and they can be NULL. |
| bool m_const_object; ///< True if "this" is const. |
| Target *m_target; ///< The target for storing persistent data like types and variables. |
| |
| bool m_evaluated_statically; ///< True if the expression could be evaluated statically; false otherwise. |
| lldb::ClangExpressionVariableSP m_const_result; ///< The statically-computed result of the expression. NULL if it could not be computed statically or the expression has side effects. |
| }; |
| |
| } // namespace lldb_private |
| |
| #endif // liblldb_ClangUserExpression_h_ |