summaryrefslogtreecommitdiff
path: root/include/lldb/Expression/UtilityFunction.h
blob: 4c87f4d1047968b3f88f2c37eb871ecdcac55dea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//===-- UtilityFunction.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_UtilityFunction_h_
#define liblldb_UtilityFunction_h_

#include <memory>
#include <string>

#include "lldb/Expression/Expression.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

//----------------------------------------------------------------------
/// @class UtilityFunction UtilityFunction.h
/// "lldb/Expression/UtilityFunction.h" Encapsulates a bit of source code that
/// provides a function that is callable
///
/// LLDB uses expressions for various purposes, notably to call functions
/// and as a backend for the expr command.  UtilityFunction encapsulates a
/// self-contained function meant to be used from other code.  Utility
/// functions can perform error-checking for ClangUserExpressions,
//----------------------------------------------------------------------
class UtilityFunction : public Expression {
public:
  //------------------------------------------------------------------
  /// Constructor
  ///
  /// @param[in] text
  ///     The text of the function.  Must be a full translation unit.
  ///
  /// @param[in] name
  ///     The name of the function, as used in the text.
  //------------------------------------------------------------------
  UtilityFunction(ExecutionContextScope &exe_scope, const char *text,
                  const char *name);

  ~UtilityFunction() override;

  //------------------------------------------------------------------
  /// Install the utility function into a process
  ///
  /// @param[in] diagnostic_manager
  ///     A diagnostic manager to print parse errors and warnings to.
  ///
  /// @param[in] exe_ctx
  ///     The execution context to install the utility function to.
  ///
  /// @return
  ///     True on success (no errors); false otherwise.
  //------------------------------------------------------------------
  virtual bool Install(DiagnosticManager &diagnostic_manager,
                       ExecutionContext &exe_ctx) = 0;

  //------------------------------------------------------------------
  /// Check whether the given PC is inside the function
  ///
  /// Especially useful if the function dereferences nullptr to indicate a
  /// failed assert.
  ///
  /// @param[in] pc
  ///     The program counter to check.
  ///
  /// @return
  ///     True if the program counter falls within the function's bounds;
  ///     false if not (or the function is not JIT compiled)
  //------------------------------------------------------------------
  bool ContainsAddress(lldb::addr_t address) {
    // nothing is both >= LLDB_INVALID_ADDRESS and < LLDB_INVALID_ADDRESS, so
    // this always returns false if the function is not JIT compiled yet
    return (address >= m_jit_start_addr && address < m_jit_end_addr);
  }

  //------------------------------------------------------------------
  /// Return the string that the parser should parse.  Must be a full
  /// translation unit.
  //------------------------------------------------------------------
  const char *Text() override { return m_function_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() override { return m_function_name.c_str(); }

  //------------------------------------------------------------------
  /// Return the object that the parser should use when registering local
  /// variables. May be nullptr if the Expression doesn't care.
  //------------------------------------------------------------------
  ExpressionVariableList *LocalVariables() { return nullptr; }

  //------------------------------------------------------------------
  /// Return true if validation code should be inserted into the expression.
  //------------------------------------------------------------------
  bool NeedsValidation() override { return false; }

  //------------------------------------------------------------------
  /// Return true if external variables in the expression should be resolved.
  //------------------------------------------------------------------
  bool NeedsVariableResolution() override { return false; }

  // This makes the function caller function. Pass in the ThreadSP if you have
  // one available, compilation can end up calling code (e.g. to look up
  // indirect functions) and we don't want this to wander onto another thread.
  FunctionCaller *MakeFunctionCaller(const CompilerType &return_type,
                                     const ValueList &arg_value_list,
                                     lldb::ThreadSP compilation_thread,
                                     Status &error);

  // This one retrieves the function caller that is already made.  If you
  // haven't made it yet, this returns nullptr
  FunctionCaller *GetFunctionCaller() { return m_caller_up.get(); }

protected:
  std::shared_ptr<IRExecutionUnit> m_execution_unit_sp;
  lldb::ModuleWP m_jit_module_wp;
  std::string m_function_text; ///< The text of the function.  Must be a
                               ///well-formed translation unit.
  std::string m_function_name; ///< The name of the function.
  std::unique_ptr<FunctionCaller> m_caller_up;
};

} // namespace lldb_private

#endif // liblldb_UtilityFunction_h_