1 //===--- OpenCLOptions.h ----------------------------------------*- 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 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// Defines the clang::OpenCLOptions class. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H 15 #define LLVM_CLANG_BASIC_OPENCLOPTIONS_H 16 17 #include "clang/Basic/LangOptions.h" 18 #include "llvm/ADT/StringMap.h" 19 20 namespace clang { 21 22 /// OpenCL supported extensions and optional core features 23 class OpenCLOptions { 24 struct Info { 25 bool Supported; // Is this option supported 26 bool Enabled; // Is this option enabled 27 unsigned Avail; // Option starts to be available in this OpenCL version 28 unsigned Core; // Option becomes (optional) core feature in this OpenCL 29 // version 30 Info(bool S = false, bool E = false, unsigned A = 100, unsigned C = ~0U) SupportedInfo31 :Supported(S), Enabled(E), Avail(A), Core(C){} 32 }; 33 llvm::StringMap<Info> OptMap; 34 public: isKnown(llvm::StringRef Ext)35 bool isKnown(llvm::StringRef Ext) const { 36 return OptMap.find(Ext) != OptMap.end(); 37 } 38 isEnabled(llvm::StringRef Ext)39 bool isEnabled(llvm::StringRef Ext) const { 40 return OptMap.find(Ext)->second.Enabled; 41 } 42 43 // Is supported as either an extension or an (optional) core feature for 44 // OpenCL version \p CLVer. isSupported(llvm::StringRef Ext,const LangOptions & LO)45 bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const { 46 // In C++ mode all extensions should work at least as in v2.0. 47 auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; 48 auto I = OptMap.find(Ext)->getValue(); 49 return I.Supported && I.Avail <= CLVer; 50 } 51 52 // Is supported (optional) OpenCL core features for OpenCL version \p CLVer. 53 // For supported extension, return false. isSupportedCore(llvm::StringRef Ext,const LangOptions & LO)54 bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const { 55 // In C++ mode all extensions should work at least as in v2.0. 56 auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; 57 auto I = OptMap.find(Ext)->getValue(); 58 return I.Supported && I.Avail <= CLVer && I.Core != ~0U && CLVer >= I.Core; 59 } 60 61 // Is supported OpenCL extension for OpenCL version \p CLVer. 62 // For supported (optional) core feature, return false. isSupportedExtension(llvm::StringRef Ext,const LangOptions & LO)63 bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const { 64 // In C++ mode all extensions should work at least as in v2.0. 65 auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; 66 auto I = OptMap.find(Ext)->getValue(); 67 return I.Supported && I.Avail <= CLVer && (I.Core == ~0U || CLVer < I.Core); 68 } 69 70 void enable(llvm::StringRef Ext, bool V = true) { 71 OptMap[Ext].Enabled = V; 72 } 73 74 /// Enable or disable support for OpenCL extensions 75 /// \param Ext name of the extension optionally prefixed with 76 /// '+' or '-' 77 /// \param V used when \p Ext is not prefixed by '+' or '-' 78 void support(llvm::StringRef Ext, bool V = true) { 79 assert(!Ext.empty() && "Extension is empty."); 80 81 switch (Ext[0]) { 82 case '+': 83 V = true; 84 Ext = Ext.drop_front(); 85 break; 86 case '-': 87 V = false; 88 Ext = Ext.drop_front(); 89 break; 90 } 91 92 if (Ext.equals("all")) { 93 supportAll(V); 94 return; 95 } 96 OptMap[Ext].Supported = V; 97 } 98 OpenCLOptions()99 OpenCLOptions(){ 100 #define OPENCLEXT_INTERNAL(Ext, AvailVer, CoreVer) \ 101 OptMap[#Ext].Avail = AvailVer; \ 102 OptMap[#Ext].Core = CoreVer; 103 #include "clang/Basic/OpenCLExtensions.def" 104 } 105 addSupport(const OpenCLOptions & Opts)106 void addSupport(const OpenCLOptions &Opts) { 107 for (auto &I:Opts.OptMap) 108 if (I.second.Supported) 109 OptMap[I.getKey()].Supported = true; 110 } 111 copy(const OpenCLOptions & Opts)112 void copy(const OpenCLOptions &Opts) { 113 OptMap = Opts.OptMap; 114 } 115 116 // Turn on or off support of all options. 117 void supportAll(bool On = true) { 118 for (llvm::StringMap<Info>::iterator I = OptMap.begin(), 119 E = OptMap.end(); I != E; ++I) 120 I->second.Supported = On; 121 } 122 disableAll()123 void disableAll() { 124 for (llvm::StringMap<Info>::iterator I = OptMap.begin(), 125 E = OptMap.end(); I != E; ++I) 126 I->second.Enabled = false; 127 } 128 enableSupportedCore(LangOptions LO)129 void enableSupportedCore(LangOptions LO) { 130 for (llvm::StringMap<Info>::iterator I = OptMap.begin(), E = OptMap.end(); 131 I != E; ++I) 132 if (isSupportedCore(I->getKey(), LO)) 133 I->second.Enabled = true; 134 } 135 136 friend class ASTWriter; 137 friend class ASTReader; 138 }; 139 140 } // end namespace clang 141 142 #endif 143