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//===----------------------------------------------------------------------===//
8
9#include "clang/Basic/OpenCLOptions.h"
10
11namespace clang {
12
13bool OpenCLOptions::isKnown(llvm::StringRef Ext) const {
14  return OptMap.find(Ext) != OptMap.end();
15}
16
17bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext,
18                                      const LangOptions &LO) const {
19  if (!isKnown(Ext))
20    return false;
21
22  auto &OptInfo = OptMap.find(Ext)->getValue();
23  if (OptInfo.isCoreIn(LO) || OptInfo.isOptionalCoreIn(LO))
24    return isSupported(Ext, LO);
25
26  return isEnabled(Ext);
27}
28
29bool OpenCLOptions::isEnabled(llvm::StringRef Ext) const {
30  auto I = OptMap.find(Ext);
31  return I != OptMap.end() && I->getValue().Enabled;
32}
33
34bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const {
35  auto E = OptMap.find(Ext);
36  return E != OptMap.end() && E->second.WithPragma;
37}
38
39bool OpenCLOptions::isSupported(llvm::StringRef Ext,
40                                const LangOptions &LO) const {
41  auto I = OptMap.find(Ext);
42  return I != OptMap.end() && I->getValue().Supported &&
43         I->getValue().isAvailableIn(LO);
44}
45
46bool OpenCLOptions::isSupportedCore(llvm::StringRef Ext,
47                                    const LangOptions &LO) const {
48  auto I = OptMap.find(Ext);
49  return I != OptMap.end() && I->getValue().Supported &&
50         I->getValue().isCoreIn(LO);
51}
52
53bool OpenCLOptions::isSupportedOptionalCore(llvm::StringRef Ext,
54                                            const LangOptions &LO) const {
55  auto I = OptMap.find(Ext);
56  return I != OptMap.end() && I->getValue().Supported &&
57         I->getValue().isOptionalCoreIn(LO);
58}
59
60bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext,
61                                                  const LangOptions &LO) const {
62  return isSupportedCore(Ext, LO) || isSupportedOptionalCore(Ext, LO);
63}
64
65bool OpenCLOptions::isSupportedExtension(llvm::StringRef Ext,
66                                         const LangOptions &LO) const {
67  auto I = OptMap.find(Ext);
68  return I != OptMap.end() && I->getValue().Supported &&
69         I->getValue().isAvailableIn(LO) &&
70         !isSupportedCoreOrOptionalCore(Ext, LO);
71}
72
73void OpenCLOptions::enable(llvm::StringRef Ext, bool V) {
74  OptMap[Ext].Enabled = V;
75}
76
77void OpenCLOptions::acceptsPragma(llvm::StringRef Ext, bool V) {
78  OptMap[Ext].WithPragma = V;
79}
80
81void OpenCLOptions::support(llvm::StringRef Ext, bool V) {
82  assert(!Ext.empty() && "Extension is empty.");
83  assert(Ext[0] != '+' && Ext[0] != '-');
84  OptMap[Ext].Supported = V;
85}
86
87OpenCLOptions::OpenCLOptions() {
88#define OPENCL_GENERIC_EXTENSION(Ext, ...)                                     \
89  OptMap.insert_or_assign(#Ext, OpenCLOptionInfo{__VA_ARGS__});
90#include "clang/Basic/OpenCLExtensions.def"
91}
92
93void OpenCLOptions::addSupport(const llvm::StringMap<bool> &FeaturesMap,
94                               const LangOptions &Opts) {
95  for (const auto &F : FeaturesMap) {
96    const auto &Name = F.getKey();
97    if (F.getValue() && isKnown(Name) && OptMap[Name].isAvailableIn(Opts))
98      support(Name);
99  }
100}
101
102void OpenCLOptions::disableAll() {
103  for (auto &Opt : OptMap)
104    Opt.getValue().Enabled = false;
105}
106
107} // end namespace clang
108