aboutsummaryrefslogtreecommitdiff
path: root/clang/include/clang/Basic/OpenCLOptions.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang/Basic/OpenCLOptions.h')
-rw-r--r--clang/include/clang/Basic/OpenCLOptions.h87
1 files changed, 71 insertions, 16 deletions
diff --git a/clang/include/clang/Basic/OpenCLOptions.h b/clang/include/clang/Basic/OpenCLOptions.h
index fe27ef19d4d5..1a035626fade 100644
--- a/clang/include/clang/Basic/OpenCLOptions.h
+++ b/clang/include/clang/Basic/OpenCLOptions.h
@@ -19,6 +19,9 @@
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
@@ -51,28 +54,48 @@ static inline OpenCLVersionID encodeOpenCLVersion(unsigned OpenCLVersion) {
}
}
-// Simple helper to check if OpenCL C version is contained in a given encoded
-// OpenCL C version mask
-static inline bool isOpenCLVersionIsContainedInMask(const LangOptions &LO,
- unsigned Mask) {
+// 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:
+ // 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.OpenCLCPlusPlus || Opts.OpenCLVersion == 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;
+ unsigned Avail = 100U;
// Option becomes core feature in this OpenCL versions
- unsigned Core;
+ unsigned Core = 0U;
// Option becomes optional core feature in this OpenCL versions
- unsigned Opt;
+ unsigned Opt = 0U;
// Is this option supported
bool Supported = false;
@@ -80,8 +103,10 @@ public:
// Is this option enabled
bool Enabled = false;
- OpenCLOptionInfo(unsigned A = 100, unsigned C = 0U, unsigned O = 0U)
- : Avail(A), Core(C), Opt(O) {}
+ 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; }
@@ -96,18 +121,23 @@ public:
// Is core option in OpenCL version \p LO.
bool isCoreIn(const LangOptions &LO) const {
- return isAvailableIn(LO) && isOpenCLVersionIsContainedInMask(LO, Core);
+ return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Core);
}
// Is optional core option in OpenCL version \p LO.
bool isOptionalCoreIn(const LangOptions &LO) const {
- return isAvailableIn(LO) && isOpenCLVersionIsContainedInMask(LO, Opt);
+ return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Opt);
}
};
bool isKnown(llvm::StringRef Ext) const;
- bool isEnabled(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.
@@ -131,6 +161,11 @@ public:
// 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
@@ -139,7 +174,6 @@ public:
void support(llvm::StringRef Ext, bool V = true);
OpenCLOptions();
- OpenCLOptions(const OpenCLOptions &) = default;
// Set supported options based on target settings and language version
void addSupport(const llvm::StringMap<bool> &FeaturesMap,
@@ -148,15 +182,36 @@ public:
// Disable all extensions
void disableAll();
- // Enable supported core and optional core features
- void enableSupportedCore(const LangOptions &LO);
-
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;
};