1 //===-- ClangUserExpression.h -----------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_ClangUserExpression_h_ 11 #define liblldb_ClangUserExpression_h_ 12 13 #include <vector> 14 15 #include "ASTResultSynthesizer.h" 16 #include "ASTStructExtractor.h" 17 #include "ClangExpressionDeclMap.h" 18 #include "ClangExpressionHelper.h" 19 #include "ClangExpressionVariable.h" 20 #include "IRForTarget.h" 21 22 #include "lldb/Core/Address.h" 23 #include "lldb/Core/ClangForward.h" 24 #include "lldb/Expression/LLVMUserExpression.h" 25 #include "lldb/Expression/Materializer.h" 26 #include "lldb/Target/ExecutionContext.h" 27 #include "lldb/lldb-forward.h" 28 #include "lldb/lldb-private.h" 29 30 namespace lldb_private { 31 32 //---------------------------------------------------------------------- 33 /// @class ClangUserExpression ClangUserExpression.h 34 /// "lldb/Expression/ClangUserExpression.h" Encapsulates a single expression 35 /// for use with Clang 36 /// 37 /// LLDB uses expressions for various purposes, notably to call functions 38 /// and as a backend for the expr command. ClangUserExpression encapsulates 39 /// the objects needed to parse and interpret or JIT an expression. It uses 40 /// the Clang parser to produce LLVM IR from the expression. 41 //---------------------------------------------------------------------- 42 class ClangUserExpression : public LLVMUserExpression { 43 public: 44 enum { kDefaultTimeout = 500000u }; 45 46 class ClangUserExpressionHelper : public ClangExpressionHelper { 47 public: ClangUserExpressionHelper(Target & target,bool top_level)48 ClangUserExpressionHelper(Target &target, bool top_level) 49 : m_target(target), m_top_level(top_level) {} 50 51 ~ClangUserExpressionHelper() override = default; 52 53 //------------------------------------------------------------------ 54 /// Return the object that the parser should use when resolving external 55 /// values. May be NULL if everything should be self-contained. 56 //------------------------------------------------------------------ DeclMap()57 ClangExpressionDeclMap *DeclMap() override { 58 return m_expr_decl_map_up.get(); 59 } 60 ResetDeclMap()61 void ResetDeclMap() { m_expr_decl_map_up.reset(); } 62 63 void ResetDeclMap(ExecutionContext &exe_ctx, 64 Materializer::PersistentVariableDelegate &result_delegate, 65 bool keep_result_in_memory); 66 67 //------------------------------------------------------------------ 68 /// Return the object that the parser should allow to access ASTs. May be 69 /// NULL if the ASTs do not need to be transformed. 70 /// 71 /// @param[in] passthrough 72 /// The ASTConsumer that the returned transformer should send 73 /// the ASTs to after transformation. 74 //------------------------------------------------------------------ 75 clang::ASTConsumer * 76 ASTTransformer(clang::ASTConsumer *passthrough) override; 77 78 void CommitPersistentDecls() override; 79 80 private: 81 Target &m_target; 82 std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up; 83 std::unique_ptr<ASTStructExtractor> m_struct_extractor_up; ///< The class 84 ///that generates 85 ///the argument 86 ///struct layout. 87 std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up; 88 bool m_top_level; 89 }; 90 91 //------------------------------------------------------------------ 92 /// Constructor 93 /// 94 /// @param[in] expr 95 /// The expression to parse. 96 /// 97 /// @param[in] expr_prefix 98 /// If non-NULL, a C string containing translation-unit level 99 /// definitions to be included when the expression is parsed. 100 /// 101 /// @param[in] language 102 /// If not eLanguageTypeUnknown, a language to use when parsing 103 /// the expression. Currently restricted to those languages 104 /// supported by Clang. 105 /// 106 /// @param[in] desired_type 107 /// If not eResultTypeAny, the type to use for the expression 108 /// result. 109 //------------------------------------------------------------------ 110 ClangUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr, 111 llvm::StringRef prefix, lldb::LanguageType language, 112 ResultType desired_type, 113 const EvaluateExpressionOptions &options); 114 115 ~ClangUserExpression() override; 116 117 //------------------------------------------------------------------ 118 /// Parse the expression 119 /// 120 /// @param[in] diagnostic_manager 121 /// A diagnostic manager to report parse errors and warnings to. 122 /// 123 /// @param[in] exe_ctx 124 /// The execution context to use when looking up entities that 125 /// are needed for parsing (locations of functions, types of 126 /// variables, persistent variables, etc.) 127 /// 128 /// @param[in] execution_policy 129 /// Determines whether interpretation is possible or mandatory. 130 /// 131 /// @param[in] keep_result_in_memory 132 /// True if the resulting persistent variable should reside in 133 /// target memory, if applicable. 134 /// 135 /// @return 136 /// True on success (no errors); false otherwise. 137 //------------------------------------------------------------------ 138 bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, 139 lldb_private::ExecutionPolicy execution_policy, 140 bool keep_result_in_memory, bool generate_debug_info) override; 141 142 bool Complete(ExecutionContext &exe_ctx, CompletionRequest &request, 143 unsigned complete_pos) override; 144 GetTypeSystemHelper()145 ExpressionTypeSystemHelper *GetTypeSystemHelper() override { 146 return &m_type_system_helper; 147 } 148 DeclMap()149 ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); } 150 ResetDeclMap()151 void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); } 152 ResetDeclMap(ExecutionContext & exe_ctx,Materializer::PersistentVariableDelegate & result_delegate,bool keep_result_in_memory)153 void ResetDeclMap(ExecutionContext &exe_ctx, 154 Materializer::PersistentVariableDelegate &result_delegate, 155 bool keep_result_in_memory) { 156 m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate, 157 keep_result_in_memory); 158 } 159 160 lldb::ExpressionVariableSP 161 GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override; 162 163 private: 164 //------------------------------------------------------------------ 165 /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the 166 /// environment. 167 //------------------------------------------------------------------ 168 169 void ScanContext(ExecutionContext &exe_ctx, 170 lldb_private::Status &err) override; 171 172 bool AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args, 173 lldb::addr_t struct_address, 174 DiagnosticManager &diagnostic_manager) override; 175 176 void UpdateLanguageForExpr(DiagnosticManager &diagnostic_manager, 177 ExecutionContext &exe_ctx); 178 bool SetupPersistentState(DiagnosticManager &diagnostic_manager, 179 ExecutionContext &exe_ctx); 180 bool PrepareForParsing(DiagnosticManager &diagnostic_manager, 181 ExecutionContext &exe_ctx); 182 183 ClangUserExpressionHelper m_type_system_helper; 184 185 class ResultDelegate : public Materializer::PersistentVariableDelegate { 186 public: ResultDelegate(lldb::TargetSP target)187 ResultDelegate(lldb::TargetSP target) : m_target_sp(target) {} 188 ConstString GetName() override; 189 void DidDematerialize(lldb::ExpressionVariableSP &variable) override; 190 191 void RegisterPersistentState(PersistentExpressionState *persistent_state); 192 lldb::ExpressionVariableSP &GetVariable(); 193 194 private: 195 PersistentExpressionState *m_persistent_state; 196 lldb::ExpressionVariableSP m_variable; 197 lldb::TargetSP m_target_sp; 198 }; 199 200 /// The language type of the current expression. 201 lldb::LanguageType m_expr_lang = lldb::eLanguageTypeUnknown; 202 203 /// The absolute character position in the transformed source code where the 204 /// user code (as typed by the user) starts. If the variable is empty, then we 205 /// were not able to calculate this position. 206 llvm::Optional<size_t> m_user_expression_start_pos; 207 ResultDelegate m_result_delegate; 208 }; 209 210 } // namespace lldb_private 211 212 #endif // liblldb_ClangUserExpression_h_ 213