[clang][extract-api][NFC] Use dedicated API to check for macro equality
[llvm-project.git] / clang / lib / Basic / OpenCLOptions.cpp
blob44edf54025405833f1d851f4f44f58e1d4160bcc
1 //===--- OpenCLOptions.cpp---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "clang/Basic/OpenCLOptions.h"
10 #include "clang/Basic/Diagnostic.h"
11 #include "clang/Basic/TargetInfo.h"
13 namespace clang {
15 // First feature in a pair requires the second one to be supported.
16 static const std::pair<StringRef, StringRef> DependentFeaturesList[] = {
17 {"__opencl_c_read_write_images", "__opencl_c_images"},
18 {"__opencl_c_3d_image_writes", "__opencl_c_images"},
19 {"__opencl_c_pipes", "__opencl_c_generic_address_space"},
20 {"__opencl_c_device_enqueue", "__opencl_c_generic_address_space"},
21 {"__opencl_c_device_enqueue", "__opencl_c_program_scope_global_variables"}};
23 // Extensions and equivalent feature pairs.
24 static const std::pair<StringRef, StringRef> FeatureExtensionMap[] = {
25 {"cl_khr_fp64", "__opencl_c_fp64"},
26 {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}};
28 bool OpenCLOptions::isKnown(llvm::StringRef Ext) const {
29 return OptMap.find(Ext) != OptMap.end();
32 bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext,
33 const LangOptions &LO) const {
34 if (!isKnown(Ext))
35 return false;
37 auto &OptInfo = OptMap.find(Ext)->getValue();
38 if (OptInfo.isCoreIn(LO) || OptInfo.isOptionalCoreIn(LO))
39 return isSupported(Ext, LO);
41 return isEnabled(Ext);
44 bool OpenCLOptions::isEnabled(llvm::StringRef Ext) const {
45 auto I = OptMap.find(Ext);
46 return I != OptMap.end() && I->getValue().Enabled;
49 bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const {
50 auto E = OptMap.find(Ext);
51 return E != OptMap.end() && E->second.WithPragma;
54 bool OpenCLOptions::isSupported(llvm::StringRef Ext,
55 const LangOptions &LO) const {
56 auto I = OptMap.find(Ext);
57 return I != OptMap.end() && I->getValue().Supported &&
58 I->getValue().isAvailableIn(LO);
61 bool OpenCLOptions::isSupportedCore(llvm::StringRef Ext,
62 const LangOptions &LO) const {
63 auto I = OptMap.find(Ext);
64 return I != OptMap.end() && I->getValue().Supported &&
65 I->getValue().isCoreIn(LO);
68 bool OpenCLOptions::isSupportedOptionalCore(llvm::StringRef Ext,
69 const LangOptions &LO) const {
70 auto I = OptMap.find(Ext);
71 return I != OptMap.end() && I->getValue().Supported &&
72 I->getValue().isOptionalCoreIn(LO);
75 bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext,
76 const LangOptions &LO) const {
77 return isSupportedCore(Ext, LO) || isSupportedOptionalCore(Ext, LO);
80 bool OpenCLOptions::isSupportedExtension(llvm::StringRef Ext,
81 const LangOptions &LO) const {
82 auto I = OptMap.find(Ext);
83 return I != OptMap.end() && I->getValue().Supported &&
84 I->getValue().isAvailableIn(LO) &&
85 !isSupportedCoreOrOptionalCore(Ext, LO);
88 void OpenCLOptions::enable(llvm::StringRef Ext, bool V) {
89 OptMap[Ext].Enabled = V;
92 void OpenCLOptions::acceptsPragma(llvm::StringRef Ext, bool V) {
93 OptMap[Ext].WithPragma = V;
96 void OpenCLOptions::support(llvm::StringRef Ext, bool V) {
97 assert(!Ext.empty() && "Extension is empty.");
98 assert(Ext[0] != '+' && Ext[0] != '-');
99 OptMap[Ext].Supported = V;
102 OpenCLOptions::OpenCLOptions() {
103 #define OPENCL_GENERIC_EXTENSION(Ext, ...) \
104 OptMap.insert_or_assign(#Ext, OpenCLOptionInfo{__VA_ARGS__});
105 #include "clang/Basic/OpenCLExtensions.def"
108 void OpenCLOptions::addSupport(const llvm::StringMap<bool> &FeaturesMap,
109 const LangOptions &Opts) {
110 for (const auto &F : FeaturesMap) {
111 const auto &Name = F.getKey();
112 if (F.getValue() && isKnown(Name) && OptMap[Name].isAvailableIn(Opts))
113 support(Name);
117 void OpenCLOptions::disableAll() {
118 for (auto &Opt : OptMap)
119 Opt.getValue().Enabled = false;
122 bool OpenCLOptions::diagnoseUnsupportedFeatureDependencies(
123 const TargetInfo &TI, DiagnosticsEngine &Diags) {
124 auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
126 bool IsValid = true;
127 for (auto &FeaturePair : DependentFeaturesList) {
128 auto Feature = FeaturePair.first;
129 auto Dep = FeaturePair.second;
130 if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Feature) &&
131 !TI.hasFeatureEnabled(OpenCLFeaturesMap, Dep)) {
132 IsValid = false;
133 Diags.Report(diag::err_opencl_feature_requires) << Feature << Dep;
136 return IsValid;
139 bool OpenCLOptions::diagnoseFeatureExtensionDifferences(
140 const TargetInfo &TI, DiagnosticsEngine &Diags) {
141 auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
143 bool IsValid = true;
144 for (auto &ExtAndFeat : FeatureExtensionMap)
145 if (TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.first) !=
146 TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.second)) {
147 IsValid = false;
148 Diags.Report(diag::err_opencl_extension_and_feature_differs)
149 << ExtAndFeat.first << ExtAndFeat.second;
151 return IsValid;
154 } // end namespace clang