text: //===-- IRDynamicChecks.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_IRDynamicChecks_h_
  #define liblldb_IRDynamicChecks_h_
  
  #include "lldb/lldb-types.h"
  #include "llvm/Pass.h"
  
  namespace llvm {
  class BasicBlock;
  class CallInst;
  class Constant;
  class Function;
  class Instruction;
  class Module;
  class DataLayout;
  class Value;
  }
  
  namespace lldb_private {
  
  class ClangExpressionDeclMap;
  class ExecutionContext;
  class Stream;
  
  //----------------------------------------------------------------------
  /// @class DynamicCheckerFunctions IRDynamicChecks.h
  /// "lldb/Expression/IRDynamicChecks.h"
  /// @brief Encapsulates dynamic check functions used by expressions.
  ///
  /// Each of the utility functions encapsulated in this class is responsible
  /// for validating some data that an expression is about to use.  Examples are:
  ///
  /// a = *b;     // check that b is a valid pointer
  /// [b init];   // check that b is a valid object to send "init" to
  ///
  /// The class installs each checker function into the target process and
  /// makes it available to IRDynamicChecks to use.
  //----------------------------------------------------------------------
  class DynamicCheckerFunctions {
  public:
    //------------------------------------------------------------------
    /// Constructor
    //------------------------------------------------------------------
    DynamicCheckerFunctions();
  
    //------------------------------------------------------------------
    /// Destructor
    //------------------------------------------------------------------
    ~DynamicCheckerFunctions();
  
    //------------------------------------------------------------------
    /// Install the utility functions into a process.  This binds the
    /// instance of DynamicCheckerFunctions to that process.
    ///
    /// @param[in] diagnostic_manager
    ///     A diagnostic manager to report errors to.
    ///
    /// @param[in] exe_ctx
    ///     The execution context to install the functions into.
    ///
    /// @return
    ///     True on success; false on failure, or if the functions have
    ///     already been installed.
    //------------------------------------------------------------------
    bool Install(DiagnosticManager &diagnostic_manager,
                 ExecutionContext &exe_ctx);
  
    bool DoCheckersExplainStop(lldb::addr_t addr, Stream &message);
  
    std::unique_ptr<UtilityFunction> m_valid_pointer_check;
    std::unique_ptr<UtilityFunction> m_objc_object_check;
  };
  
  //----------------------------------------------------------------------
  /// @class IRDynamicChecks IRDynamicChecks.h "lldb/Expression/IRDynamicChecks.h"
  /// @brief Adds dynamic checks to a user-entered expression to reduce its
  /// likelihood of crashing
  ///
  /// When an IR function is executed in the target process, it may cause
  /// crashes or hangs by dereferencing NULL pointers, trying to call Objective-C
  /// methods on objects that do not respond to them, and so forth.
  ///
  /// IRDynamicChecks adds calls to the functions in DynamicCheckerFunctions
  /// to appropriate locations in an expression's IR.
  //----------------------------------------------------------------------
  class IRDynamicChecks : public llvm::ModulePass {
  public:
    //------------------------------------------------------------------
    /// Constructor
    ///
    /// @param[in] checker_functions
    ///     The checker functions for the target process.
    ///
    /// @param[in] func_name
    ///     The name of the function to prepare for execution in the target.
    ///
    /// @param[in] decl_map
    ///     The mapping used to look up entities in the target process. In
    ///     this case, used to find objc_msgSend
    //------------------------------------------------------------------
    IRDynamicChecks(DynamicCheckerFunctions &checker_functions,
                    const char *func_name = "$__lldb_expr");
  
    //------------------------------------------------------------------
    /// Destructor
    //------------------------------------------------------------------
    ~IRDynamicChecks() override;
  
    //------------------------------------------------------------------
    /// Run this IR transformer on a single module
    ///
    /// @param[in] M
    ///     The module to run on.  This module is searched for the function
    ///     $__lldb_expr, and that function is passed to the passes one by
    ///     one.
    ///
    /// @return
    ///     True on success; false otherwise
    //------------------------------------------------------------------
    bool runOnModule(llvm::Module &M) override;
  
    //------------------------------------------------------------------
    /// Interface stub
    //------------------------------------------------------------------
    void assignPassManager(
        llvm::PMStack &PMS,
        llvm::PassManagerType T = llvm::PMT_ModulePassManager) override;
  
    //------------------------------------------------------------------
    /// Returns PMT_ModulePassManager
    //------------------------------------------------------------------
    llvm::PassManagerType getPotentialPassManagerType() const override;
  
  private:
    //------------------------------------------------------------------
    /// A basic block-level pass to find all pointer dereferences and
    /// validate them before use.
    //------------------------------------------------------------------
  
    //------------------------------------------------------------------
    /// The top-level pass implementation
    ///
    /// @param[in] M
    ///     The module currently being processed.
    ///
    /// @param[in] BB
    ///     The basic block currently being processed.
    ///
    /// @return
    ///     True on success; false otherwise
    //------------------------------------------------------------------
    bool FindDataLoads(llvm::Module &M, llvm::BasicBlock &BB);
  
    std::string m_func_name; ///< The name of the function to add checks to
    DynamicCheckerFunctions
        &m_checker_functions; ///< The checker functions for the process
  };
  
  } // namespace lldb_private
  
  #endif // liblldb_IRDynamicChecks_h_
  