//=== 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_ANY_CALL_H
#define LLVM_CLANG_ANALYSIS_ANY_CALL_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 {@code E} is a generic call (to ObjC method /function/block/etc),
  /// return a constructed {@code 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 {@code D} is a callable (Objective-C method or a function), return
  /// a constructed {@code 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,
  /// {@code 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_ANY_CALL_H
