reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
//===-- ClangFunctionCaller.h -----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_ClangFunctionCaller_h_
#define liblldb_ClangFunctionCaller_h_

#include "ClangExpressionHelper.h"

#include "lldb/Core/Address.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Process.h"

namespace lldb_private {

class ASTStructExtractor;
class ClangExpressionParser;

/// \class ClangFunctionCaller ClangFunctionCaller.h
/// "lldb/Expression/ClangFunctionCaller.h" Encapsulates a function that can
/// be called.
///
/// A given ClangFunctionCaller object can handle a single function signature.
/// Once constructed, it can set up any number of concurrent calls to
/// functions with that signature.
///
/// It performs the call by synthesizing a structure that contains the pointer
/// to the function and the arguments that should be passed to that function,
/// and producing a special-purpose JIT-compiled function that accepts a void*
/// pointing to this struct as its only argument and calls the function in the
/// struct with the written arguments.  This method lets Clang handle the
/// vagaries of function calling conventions.
///
/// The simplest use of the ClangFunctionCaller is to construct it with a
/// function representative of the signature you want to use, then call
/// ExecuteFunction(ExecutionContext &, Stream &, Value &).
///
/// If you need to reuse the arguments for several calls, you can call
/// InsertFunction() followed by WriteFunctionArguments(), which will return
/// the location of the args struct for the wrapper function in args_addr_ref.
///
/// If you need to call the function on the thread plan stack, you can also
/// call InsertFunction() followed by GetThreadPlanToCallFunction().
///
/// Any of the methods that take arg_addr_ptr or arg_addr_ref can be passed a
/// pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated
/// and its address returned in that variable.
///
/// Any of the methods that take arg_addr_ptr can be passed NULL, and the
/// argument space will be managed for you.
class ClangFunctionCaller : public FunctionCaller {
  friend class ASTStructExtractor;

  /// LLVM-style RTTI support.
  static bool classof(const Expression *E) {
    return E->getKind() == eKindClangFunctionCaller;
  }

  class ClangFunctionCallerHelper : public ClangExpressionHelper {
  public:
    ClangFunctionCallerHelper(ClangFunctionCaller &owner) : m_owner(owner) {}

    ~ClangFunctionCallerHelper() override = default;

    /// Return the object that the parser should use when resolving external
    /// values.  May be NULL if everything should be self-contained.
    ClangExpressionDeclMap *DeclMap() override { return nullptr; }

    /// 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) override;

  private:
    ClangFunctionCaller &m_owner;
    std::unique_ptr<ASTStructExtractor> m_struct_extractor; ///< The class that
                                                            ///generates the
                                                            ///argument struct
                                                            ///layout.
  };

public:
  /// Constructor
  ///
  /// \param[in] exe_scope
  ///     An execution context scope that gets us at least a target and
  ///     process.
  ///
  /// \param[in] ast_context
  ///     The AST context to evaluate argument types in.
  ///
  /// \param[in] return_qualtype
  ///     An opaque Clang QualType for the function result.  Should be
  ///     defined in ast_context.
  ///
  /// \param[in] function_address
  ///     The address of the function to call.
  ///
  /// \param[in] arg_value_list
  ///     The default values to use when calling this function.  Can
  ///     be overridden using WriteFunctionArguments().
  ClangFunctionCaller(ExecutionContextScope &exe_scope,
                      const CompilerType &return_type,
                      const Address &function_address,
                      const ValueList &arg_value_list, const char *name);

  ~ClangFunctionCaller() override;

  /// Compile the wrapper function
  ///
  /// \param[in] thread_to_use_sp
  ///     Compilation might end up calling functions.  Pass in the thread you
  ///     want the compilation to use.  If you pass in an empty ThreadSP it will
  ///     use the currently selected thread.
  ///
  /// \param[in] diagnostic_manager
  ///     The diagnostic manager to report parser errors to.
  ///
  /// \return
  ///     The number of errors.
  unsigned CompileFunction(lldb::ThreadSP thread_to_use_sp,
                           DiagnosticManager &diagnostic_manager) override;

  ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
    return &m_type_system_helper;
  }

protected:
  const char *GetWrapperStructName() { return m_wrapper_struct_name.c_str(); }

private:
  // For ClangFunctionCaller only

  // Note: the parser needs to be destructed before the execution unit, so
  // declare the execution unit first.
  ClangFunctionCallerHelper m_type_system_helper;
};

} // namespace lldb_private

#endif // liblldb_ClangFunctionCaller_h_