OpenCLOptions.h revision 360784
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 20namespace clang { 21 22/// OpenCL supported extensions and optional core features 23class 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) 31 :Supported(S), Enabled(E), Avail(A), Core(C){} 32 }; 33 llvm::StringMap<Info> OptMap; 34public: 35 bool isKnown(llvm::StringRef Ext) const { 36 return OptMap.find(Ext) != OptMap.end(); 37 } 38 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. 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. 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. 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 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 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 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 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 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