//===--- OpenCLOptions.h ----------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Defines the clang::OpenCLOptions class.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H
#define LLVM_CLANG_BASIC_OPENCLOPTIONS_H

#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/StringMap.h"

namespace clang {

namespace {
// This enum maps OpenCL version(s) into value. These values are used as
// a mask to indicate in which OpenCL version(s) extension is a core or
// optional core feature.
enum OpenCLVersionID : unsigned int {
  OCL_C_10 = 0x1,
  OCL_C_11 = 0x2,
  OCL_C_12 = 0x4,
  OCL_C_20 = 0x8,
  OCL_C_30 = 0x10,
  OCL_C_ALL = 0x1f,
  OCL_C_11P = OCL_C_ALL ^ OCL_C_10,              // OpenCL C 1.1+
  OCL_C_12P = OCL_C_ALL ^ (OCL_C_10 | OCL_C_11), // OpenCL C 1.2+
};

static inline OpenCLVersionID encodeOpenCLVersion(unsigned OpenCLVersion) {
  switch (OpenCLVersion) {
  default:
    llvm_unreachable("Unknown OpenCL version code");
  case 100:
    return OCL_C_10;
  case 110:
    return OCL_C_11;
  case 120:
    return OCL_C_12;
  case 200:
    return OCL_C_20;
  case 300:
    return OCL_C_30;
  }
}

// Check if OpenCL C version is contained in a given encoded OpenCL C version
// mask.
static inline bool isOpenCLVersionContainedInMask(const LangOptions &LO,
                                                  unsigned Mask) {
  auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
  OpenCLVersionID Code = encodeOpenCLVersion(CLVer);
  return Mask & Code;
}

} // end anonymous namespace

/// OpenCL supported extensions and optional core features
class OpenCLOptions {
public:
  struct OpenCLOptionInfo {
    // Does this option have pragma.
    bool WithPragma = false;

    // Option starts to be available in this OpenCL version
    unsigned Avail = 100U;

    // Option becomes core feature in this OpenCL versions
    unsigned Core = 0U;

    // Option becomes optional core feature in this OpenCL versions
    unsigned Opt = 0U;

    // Is this option supported
    bool Supported = false;

    // Is this option enabled
    bool Enabled = false;

    OpenCLOptionInfo() = default;
    OpenCLOptionInfo(bool Pragma, unsigned AvailV, unsigned CoreV,
                     unsigned OptV)
        : WithPragma(Pragma), Avail(AvailV), Core(CoreV), Opt(OptV) {}

    bool isCore() const { return Core != 0U; }

    bool isOptionalCore() const { return Opt != 0U; }

    // Is option available in OpenCL version \p LO.
    bool isAvailableIn(const LangOptions &LO) const {
      // In C++ mode all extensions should work at least as in v2.0.
      auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
      return CLVer >= Avail;
    }

    // Is core option in OpenCL version \p LO.
    bool isCoreIn(const LangOptions &LO) const {
      return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Core);
    }

    // Is optional core option in OpenCL version \p LO.
    bool isOptionalCoreIn(const LangOptions &LO) const {
      return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Opt);
    }
  };

  bool isKnown(llvm::StringRef Ext) const;

  // For core or optional core feature check that it is supported
  // by a target, for any other option (extension) check that it is
  // enabled via pragma
  bool isAvailableOption(llvm::StringRef Ext, const LangOptions &LO) const;

  bool isWithPragma(llvm::StringRef Ext) const;

  // Is supported as either an extension or an (optional) core feature for
  // OpenCL version \p LO.
  bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const;

  // Is supported OpenCL core feature for OpenCL version \p LO.
  // For supported extension, return false.
  bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const;

  // Is supported optional core OpenCL feature for OpenCL version \p LO.
  // For supported extension, return false.
  bool isSupportedOptionalCore(llvm::StringRef Ext,
                               const LangOptions &LO) const;

  // Is supported optional core or core OpenCL feature for OpenCL version \p
  // LO. For supported extension, return false.
  bool isSupportedCoreOrOptionalCore(llvm::StringRef Ext,
                                     const LangOptions &LO) const;

  // Is supported OpenCL extension for OpenCL version \p LO.
  // For supported core or optional core feature, return false.
  bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const;

  // FIXME: Whether extension should accept pragma should not
  // be reset dynamically. But it currently required when
  // registering new extensions via pragmas.
  void acceptsPragma(llvm::StringRef Ext, bool V = true);

  void enable(llvm::StringRef Ext, bool V = true);

  /// Enable or disable support for OpenCL extensions
  /// \param Ext name of the extension (not prefixed with '+' or '-')
  /// \param V value to set for a extension
  void support(llvm::StringRef Ext, bool V = true);

  OpenCLOptions();

  // Set supported options based on target settings and language version
  void addSupport(const llvm::StringMap<bool> &FeaturesMap,
                  const LangOptions &Opts);

  // Disable all extensions
  void disableAll();

  friend class ASTWriter;
  friend class ASTReader;

  using OpenCLOptionInfoMap = llvm::StringMap<OpenCLOptionInfo>;

  template <typename... Args>
  static bool isOpenCLOptionCoreIn(const LangOptions &LO, Args &&... args) {
    return OpenCLOptionInfo(std::forward<Args>(args)...).isCoreIn(LO);
  }

  template <typename... Args>
  static bool isOpenCLOptionAvailableIn(const LangOptions &LO,
                                        Args &&... args) {
    return OpenCLOptionInfo(std::forward<Args>(args)...).isAvailableIn(LO);
  }

private:
  // Option is enabled via pragma
  bool isEnabled(llvm::StringRef Ext) const;

  OpenCLOptionInfoMap OptMap;
};

} // end namespace clang

#endif
