//===--- TypeMismatchCheck.cpp - clang-tidy--------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "TypeMismatchCheck.h"
#include "clang/Lex/Lexer.h"
#include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h"
#include "clang/Tooling/FixIt.h"
#include <map>
#include <unordered_set>

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace mpi {

/// Check if a BuiltinType::Kind matches the MPI datatype.
///
/// \param MultiMap datatype group
/// \param Kind buffer type kind
/// \param MPIDatatype name of the MPI datatype
///
/// \returns true if the pair matches
static bool
isMPITypeMatching(const std::multimap<BuiltinType::Kind, std::string> &MultiMap,
                  const BuiltinType::Kind Kind,
                  const std::string &MPIDatatype) {
  auto ItPair = MultiMap.equal_range(Kind);
  while (ItPair.first != ItPair.second) {
    if (ItPair.first->second == MPIDatatype)
      return true;
    ++ItPair.first;
  }
  return false;
}

/// Check if the MPI datatype is a standard type.
///
/// \param MPIDatatype name of the MPI datatype
///
/// \returns true if the type is a standard type
static bool isStandardMPIDatatype(const std::string &MPIDatatype) {
  static std::unordered_set<std::string> AllTypes = {
      "MPI_C_BOOL",
      "MPI_CHAR",
      "MPI_SIGNED_CHAR",
      "MPI_UNSIGNED_CHAR",
      "MPI_WCHAR",
      "MPI_INT",
      "MPI_LONG",
      "MPI_SHORT",
      "MPI_LONG_LONG",
      "MPI_LONG_LONG_INT",
      "MPI_UNSIGNED",
      "MPI_UNSIGNED_SHORT",
      "MPI_UNSIGNED_LONG",
      "MPI_UNSIGNED_LONG_LONG",
      "MPI_FLOAT",
      "MPI_DOUBLE",
      "MPI_LONG_DOUBLE",
      "MPI_C_COMPLEX",
      "MPI_C_FLOAT_COMPLEX",
      "MPI_C_DOUBLE_COMPLEX",
      "MPI_C_LONG_DOUBLE_COMPLEX",
      "MPI_INT8_T",
      "MPI_INT16_T",
      "MPI_INT32_T",
      "MPI_INT64_T",
      "MPI_UINT8_T",
      "MPI_UINT16_T",
      "MPI_UINT32_T",
      "MPI_UINT64_T",
      "MPI_CXX_BOOL",
      "MPI_CXX_FLOAT_COMPLEX",
      "MPI_CXX_DOUBLE_COMPLEX",
      "MPI_CXX_LONG_DOUBLE_COMPLEX"};

  return AllTypes.find(MPIDatatype) != AllTypes.end();
}

/// Check if a BuiltinType matches the MPI datatype.
///
/// \param Builtin the builtin type
/// \param BufferTypeName buffer type name, gets assigned
/// \param MPIDatatype name of the MPI datatype
/// \param LO language options
///
/// \returns true if the type matches
static bool isBuiltinTypeMatching(const BuiltinType *Builtin,
                                  std::string &BufferTypeName,
                                  const std::string &MPIDatatype,
                                  const LangOptions &LO) {
  static std::multimap<BuiltinType::Kind, std::string> BuiltinMatches = {
      // On some systems like PPC or ARM, 'char' is unsigned by default which is
      // why distinct signedness for the buffer and MPI type is tolerated.
      {BuiltinType::SChar, "MPI_CHAR"},
      {BuiltinType::SChar, "MPI_SIGNED_CHAR"},
      {BuiltinType::SChar, "MPI_UNSIGNED_CHAR"},
      {BuiltinType::Char_S, "MPI_CHAR"},
      {BuiltinType::Char_S, "MPI_SIGNED_CHAR"},
      {BuiltinType::Char_S, "MPI_UNSIGNED_CHAR"},
      {BuiltinType::UChar, "MPI_CHAR"},
      {BuiltinType::UChar, "MPI_SIGNED_CHAR"},
      {BuiltinType::UChar, "MPI_UNSIGNED_CHAR"},
      {BuiltinType::Char_U, "MPI_CHAR"},
      {BuiltinType::Char_U, "MPI_SIGNED_CHAR"},
      {BuiltinType::Char_U, "MPI_UNSIGNED_CHAR"},
      {BuiltinType::WChar_S, "MPI_WCHAR"},
      {BuiltinType::WChar_U, "MPI_WCHAR"},
      {BuiltinType::Bool, "MPI_C_BOOL"},
      {BuiltinType::Bool, "MPI_CXX_BOOL"},
      {BuiltinType::Short, "MPI_SHORT"},
      {BuiltinType::Int, "MPI_INT"},
      {BuiltinType::Long, "MPI_LONG"},
      {BuiltinType::LongLong, "MPI_LONG_LONG"},
      {BuiltinType::LongLong, "MPI_LONG_LONG_INT"},
      {BuiltinType::UShort, "MPI_UNSIGNED_SHORT"},
      {BuiltinType::UInt, "MPI_UNSIGNED"},
      {BuiltinType::ULong, "MPI_UNSIGNED_LONG"},
      {BuiltinType::ULongLong, "MPI_UNSIGNED_LONG_LONG"},
      {BuiltinType::Float, "MPI_FLOAT"},
      {BuiltinType::Double, "MPI_DOUBLE"},
      {BuiltinType::LongDouble, "MPI_LONG_DOUBLE"}};

  if (!isMPITypeMatching(BuiltinMatches, Builtin->getKind(), MPIDatatype)) {
    BufferTypeName = Builtin->getName(LO);
    return false;
  }

  return true;
}

/// Check if a complex float/double/long double buffer type matches
/// the MPI datatype.
///
/// \param Complex buffer type
/// \param BufferTypeName buffer type name, gets assigned
/// \param MPIDatatype name of the MPI datatype
/// \param LO language options
///
/// \returns true if the type matches or the buffer type is unknown
static bool isCComplexTypeMatching(const ComplexType *const Complex,
                                   std::string &BufferTypeName,
                                   const std::string &MPIDatatype,
                                   const LangOptions &LO) {
  static std::multimap<BuiltinType::Kind, std::string> ComplexCMatches = {
      {BuiltinType::Float, "MPI_C_COMPLEX"},
      {BuiltinType::Float, "MPI_C_FLOAT_COMPLEX"},
      {BuiltinType::Double, "MPI_C_DOUBLE_COMPLEX"},
      {BuiltinType::LongDouble, "MPI_C_LONG_DOUBLE_COMPLEX"}};

  const auto *Builtin =
      Complex->getElementType().getTypePtr()->getAs<BuiltinType>();

  if (Builtin &&
      !isMPITypeMatching(ComplexCMatches, Builtin->getKind(), MPIDatatype)) {
    BufferTypeName = (llvm::Twine(Builtin->getName(LO)) + " _Complex").str();
    return false;
  }
  return true;
}

/// Check if a complex<float/double/long double> templated buffer type matches
/// the MPI datatype.
///
/// \param Template buffer type
/// \param BufferTypeName buffer type name, gets assigned
/// \param MPIDatatype name of the MPI datatype
/// \param LO language options
///
/// \returns true if the type matches or the buffer type is unknown
static bool
isCXXComplexTypeMatching(const TemplateSpecializationType *const Template,
                         std::string &BufferTypeName,
                         const std::string &MPIDatatype,
                         const LangOptions &LO) {
  static std::multimap<BuiltinType::Kind, std::string> ComplexCXXMatches = {
      {BuiltinType::Float, "MPI_CXX_FLOAT_COMPLEX"},
      {BuiltinType::Double, "MPI_CXX_DOUBLE_COMPLEX"},
      {BuiltinType::LongDouble, "MPI_CXX_LONG_DOUBLE_COMPLEX"}};

  if (Template->getAsCXXRecordDecl()->getName() != "complex")
    return true;

  const auto *Builtin =
      Template->getArg(0).getAsType().getTypePtr()->getAs<BuiltinType>();

  if (Builtin &&
      !isMPITypeMatching(ComplexCXXMatches, Builtin->getKind(), MPIDatatype)) {
    BufferTypeName =
        (llvm::Twine("complex<") + Builtin->getName(LO) + ">").str();
    return false;
  }

  return true;
}

/// Check if a fixed size width buffer type matches the MPI datatype.
///
/// \param Typedef buffer type
/// \param BufferTypeName buffer type name, gets assigned
/// \param MPIDatatype name of the MPI datatype
///
/// \returns true if the type matches or the buffer type is unknown
static bool isTypedefTypeMatching(const TypedefType *const Typedef,
                                  std::string &BufferTypeName,
                                  const std::string &MPIDatatype) {
  static llvm::StringMap<std::string> FixedWidthMatches = {
      {"int8_t", "MPI_INT8_T"},     {"int16_t", "MPI_INT16_T"},
      {"int32_t", "MPI_INT32_T"},   {"int64_t", "MPI_INT64_T"},
      {"uint8_t", "MPI_UINT8_T"},   {"uint16_t", "MPI_UINT16_T"},
      {"uint32_t", "MPI_UINT32_T"}, {"uint64_t", "MPI_UINT64_T"}};

  const auto it = FixedWidthMatches.find(Typedef->getDecl()->getName());
  // Check if the typedef is known and not matching the MPI datatype.
  if (it != FixedWidthMatches.end() && it->getValue() != MPIDatatype) {
    BufferTypeName = Typedef->getDecl()->getName();
    return false;
  }
  return true;
}

/// Get the unqualified, dereferenced type of an argument.
///
/// \param CE call expression
/// \param idx argument index
///
/// \returns type of the argument
static const Type *argumentType(const CallExpr *const CE, const size_t idx) {
  const QualType QT = CE->getArg(idx)->IgnoreImpCasts()->getType();
  return QT.getTypePtr()->getPointeeOrArrayElementType();
}

void TypeMismatchCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(callExpr().bind("CE"), this);
}

void TypeMismatchCheck::check(const MatchFinder::MatchResult &Result) {
  static ento::mpi::MPIFunctionClassifier FuncClassifier(*Result.Context);
  const auto *const CE = Result.Nodes.getNodeAs<CallExpr>("CE");
  if (!CE->getDirectCallee())
    return;

  const IdentifierInfo *Identifier = CE->getDirectCallee()->getIdentifier();
  if (!Identifier || !FuncClassifier.isMPIType(Identifier))
    return;

  // These containers are used, to capture buffer, MPI datatype pairs.
  SmallVector<const Type *, 1> BufferTypes;
  SmallVector<const Expr *, 1> BufferExprs;
  SmallVector<StringRef, 1> MPIDatatypes;

  // Adds a buffer, MPI datatype pair of an MPI call expression to the
  // containers. For buffers, the type and expression is captured.
  auto addPair = [&CE, &Result, &BufferTypes, &BufferExprs, &MPIDatatypes](
      const size_t BufferIdx, const size_t DatatypeIdx) {
    // Skip null pointer constants and in place 'operators'.
    if (CE->getArg(BufferIdx)->isNullPointerConstant(
            *Result.Context, Expr::NPC_ValueDependentIsNull) ||
        tooling::fixit::getText(*CE->getArg(BufferIdx), *Result.Context) ==
            "MPI_IN_PLACE")
      return;

    StringRef MPIDatatype =
        tooling::fixit::getText(*CE->getArg(DatatypeIdx), *Result.Context);

    const Type *ArgType = argumentType(CE, BufferIdx);
    // Skip unknown MPI datatypes and void pointers.
    if (!isStandardMPIDatatype(MPIDatatype) || ArgType->isVoidType())
      return;

    BufferTypes.push_back(ArgType);
    BufferExprs.push_back(CE->getArg(BufferIdx));
    MPIDatatypes.push_back(MPIDatatype);
  };

  // Collect all buffer, MPI datatype pairs for the inspected call expression.
  if (FuncClassifier.isPointToPointType(Identifier)) {
    addPair(0, 2);
  } else if (FuncClassifier.isCollectiveType(Identifier)) {
    if (FuncClassifier.isReduceType(Identifier)) {
      addPair(0, 3);
      addPair(1, 3);
    } else if (FuncClassifier.isScatterType(Identifier) ||
               FuncClassifier.isGatherType(Identifier) ||
               FuncClassifier.isAlltoallType(Identifier)) {
      addPair(0, 2);
      addPair(3, 5);
    } else if (FuncClassifier.isBcastType(Identifier)) {
      addPair(0, 2);
    }
  }
  checkArguments(BufferTypes, BufferExprs, MPIDatatypes, getLangOpts());
}

void TypeMismatchCheck::checkArguments(ArrayRef<const Type *> BufferTypes,
                                       ArrayRef<const Expr *> BufferExprs,
                                       ArrayRef<StringRef> MPIDatatypes,
                                       const LangOptions &LO) {
  std::string BufferTypeName;

  for (size_t i = 0; i < MPIDatatypes.size(); ++i) {
    const Type *const BT = BufferTypes[i];
    bool Error = false;

    if (const auto *Typedef = BT->getAs<TypedefType>()) {
      Error = !isTypedefTypeMatching(Typedef, BufferTypeName, MPIDatatypes[i]);
    } else if (const auto *Complex = BT->getAs<ComplexType>()) {
      Error =
          !isCComplexTypeMatching(Complex, BufferTypeName, MPIDatatypes[i], LO);
    } else if (const auto *Template = BT->getAs<TemplateSpecializationType>()) {
      Error = !isCXXComplexTypeMatching(Template, BufferTypeName,
                                        MPIDatatypes[i], LO);
    } else if (const auto *Builtin = BT->getAs<BuiltinType>()) {
      Error =
          !isBuiltinTypeMatching(Builtin, BufferTypeName, MPIDatatypes[i], LO);
    }

    if (Error) {
      const auto Loc = BufferExprs[i]->getSourceRange().getBegin();
      diag(Loc, "buffer type '%0' does not match the MPI datatype '%1'")
          << BufferTypeName << MPIDatatypes[i];
    }
  }
}

} // namespace mpi
} // namespace tidy
} // namespace clang
