//=== AnyCall.h - Abstraction over different callables --------*- 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
//
//===----------------------------------------------------------------------===//
//
// A utility class for performing generic operations over different callables.
//
//===----------------------------------------------------------------------===//
//
#ifndef LLVM_CLANG_ANALYSIS_ANYCALL_H
#define LLVM_CLANG_ANALYSIS_ANYCALL_H

#include "clang/AST/Decl.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"

namespace clang {

/// An instance of this class corresponds to a call.
/// It might be a syntactically-concrete call, done as a part of evaluating an
/// expression, or it may be an abstract callee with no associated expression.
class AnyCall {
public:
  enum Kind {
    /// A function, function pointer, or a C++ method call
    Function,

    /// A call to an Objective-C method
    ObjCMethod,

    /// A call to an Objective-C block
    Block,

    /// An implicit C++ destructor call (called implicitly
    /// or by operator 'delete')
    Destructor,

    /// An implicit or explicit C++ constructor call
    Constructor,

    /// A C++ inherited constructor produced by a "using T::T" directive
    InheritedConstructor,

    /// A C++ allocation function call (operator `new`), via C++ new-expression
    Allocator,

    /// A C++ deallocation function call (operator `delete`), via C++
    /// delete-expression
    Deallocator
  };

private:
  /// Either expression or declaration (but not both at the same time)
  /// can be null.

  /// Call expression, is null when is not known (then declaration is non-null),
  /// or for implicit destructor calls (when no expression exists.)
  const Expr *E = nullptr;

  /// Corresponds to a statically known declaration of the called function,
  /// or null if it is not known (e.g. for a function pointer).
  const Decl *D = nullptr;
  Kind K;

public:
  AnyCall(const CallExpr *CE) : E(CE) {
    D = CE->getCalleeDecl();
    K = (CE->getCallee()->getType()->getAs<BlockPointerType>()) ? Block
                                                                : Function;
    if (D && ((K == Function && !isa<FunctionDecl>(D)) ||
              (K == Block && !isa<BlockDecl>(D))))
      D = nullptr;
  }

  AnyCall(const ObjCMessageExpr *ME)
      : E(ME), D(ME->getMethodDecl()), K(ObjCMethod) {}

  AnyCall(const CXXNewExpr *NE)
      : E(NE), D(NE->getOperatorNew()), K(Allocator) {}

  AnyCall(const CXXDeleteExpr *NE)
      : E(NE), D(NE->getOperatorDelete()), K(Deallocator) {}

  AnyCall(const CXXConstructExpr *NE)
      : E(NE), D(NE->getConstructor()), K(Constructor) {}

  AnyCall(const CXXInheritedCtorInitExpr *CIE)
      : E(CIE), D(CIE->getConstructor()), K(InheritedConstructor) {}

  AnyCall(const CXXDestructorDecl *D) : E(nullptr), D(D), K(Destructor) {}

  AnyCall(const CXXConstructorDecl *D) : E(nullptr), D(D), K(Constructor) {}

  AnyCall(const ObjCMethodDecl *D) : E(nullptr), D(D), K(ObjCMethod) {}

  AnyCall(const FunctionDecl *D) : E(nullptr), D(D) {
    if (isa<CXXConstructorDecl>(D)) {
      K = Constructor;
    } else if (isa <CXXDestructorDecl>(D)) {
      K = Destructor;
    } else {
      K = Function;
    }

  }

  /// If @c E is a generic call (to ObjC method /function/block/etc),
  /// return a constructed @c AnyCall object. Return None otherwise.
  static Optional<AnyCall> forExpr(const Expr *E) {
    if (const auto *ME = dyn_cast<ObjCMessageExpr>(E)) {
      return AnyCall(ME);
    } else if (const auto *CE = dyn_cast<CallExpr>(E)) {
      return AnyCall(CE);
    } else if (const auto *CXNE = dyn_cast<CXXNewExpr>(E)) {
      return AnyCall(CXNE);
    } else if (const auto *CXDE = dyn_cast<CXXDeleteExpr>(E)) {
      return AnyCall(CXDE);
    } else if (const auto *CXCE = dyn_cast<CXXConstructExpr>(E)) {
      return AnyCall(CXCE);
    } else if (const auto *CXCIE = dyn_cast<CXXInheritedCtorInitExpr>(E)) {
      return AnyCall(CXCIE);
    } else {
      return None;
    }
  }

  /// If @c D is a callable (Objective-C method or a function), return
  /// a constructed @c AnyCall object. Return None otherwise.
  // FIXME: block support.
  static Optional<AnyCall> forDecl(const Decl *D) {
    if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
      return AnyCall(FD);
    } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
      return AnyCall(MD);
    }
    return None;
  }

  /// \returns formal parameters for direct calls (including virtual calls)
  ArrayRef<ParmVarDecl *> parameters() const {
    if (!D)
      return None;

    if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
      return FD->parameters();
    } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
      return MD->parameters();
    } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
      return BD->parameters();
    } else {
      return None;
    }
  }

  using param_const_iterator = ArrayRef<ParmVarDecl *>::const_iterator;
  param_const_iterator param_begin() const { return parameters().begin(); }
  param_const_iterator param_end() const { return parameters().end(); }
  size_t param_size() const { return parameters().size(); }
  bool param_empty() const { return parameters().empty(); }

  QualType getReturnType(ASTContext &Ctx) const {
    switch (K) {
    case Function:
      if (E)
        return cast<CallExpr>(E)->getCallReturnType(Ctx);
      return cast<FunctionDecl>(D)->getReturnType();
    case ObjCMethod:
      if (E)
        return cast<ObjCMessageExpr>(E)->getCallReturnType(Ctx);
      return cast<ObjCMethodDecl>(D)->getReturnType();
    case Block:
      // FIXME: BlockDecl does not know its return type,
      // hence the asymmetry with the function and method cases above.
      return cast<CallExpr>(E)->getCallReturnType(Ctx);
    case Destructor:
    case Constructor:
    case InheritedConstructor:
    case Allocator:
    case Deallocator:
      return cast<FunctionDecl>(D)->getReturnType();
    }
    llvm_unreachable("Unknown AnyCall::Kind");
  }

  /// \returns Function identifier if it is a named declaration,
  /// @c nullptr otherwise.
  const IdentifierInfo *getIdentifier() const {
    if (const auto *ND = dyn_cast_or_null<NamedDecl>(D))
      return ND->getIdentifier();
    return nullptr;
  }

  const Decl *getDecl() const {
    return D;
  }

  const Expr *getExpr() const {
    return E;
  }

  Kind getKind() const {
    return K;
  }

  void dump() const {
    if (E)
      E->dump();
    if (D)
      D->dump();
  }
};

}

#endif // LLVM_CLANG_ANALYSIS_ANYCALL_H
