//=== 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++ 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 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 {
      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 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
