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

class DiagnosticsEngine;
class TargetInfo;

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.getOpenCLCompatibleVersion();
  OpenCLVersionID Code = encodeOpenCLVersion(CLVer);
  return Mask & Code;
}

} // end anonymous namespace

/// OpenCL supported extensions and optional core features
class OpenCLOptions {

public:
  // OpenCL C v1.2 s6.5 - All program scope variables must be declared in the
  // __constant address space.
  // OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static
  // variables inside a function can also be declared in the global
  // address space.
  // OpenCL C v3.0 s6.7.1 - Variables at program scope or static or extern
  // variables inside functions can be declared in global address space if
  // the __opencl_c_program_scope_global_variables feature is supported
  // C++ for OpenCL inherits rule from OpenCL C v2.0.
  bool areProgramScopeVariablesSupported(const LangOptions &Opts) const {
    return Opts.getOpenCLCompatibleVersion() == 200 ||
           (Opts.OpenCLVersion == 300 &&
            isSupported("__opencl_c_program_scope_global_variables", Opts));
  }

  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.
      return LO.getOpenCLCompatibleVersion() >= 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);
  }

  // Diagnose feature dependencies for OpenCL C 3.0. Return false if target
  // doesn't follow these requirements.
  static bool diagnoseUnsupportedFeatureDependencies(const TargetInfo &TI,
                                                     DiagnosticsEngine &Diags);

  // Diagnose that features and equivalent extension are set to same values.
  // Return false if target doesn't follow these requirements.
  static bool diagnoseFeatureExtensionDifferences(const TargetInfo &TI,
                                                  DiagnosticsEngine &Diags);

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

  OpenCLOptionInfoMap OptMap;
};

} // end namespace clang

#endif
