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