clang  19.0.0git
LangOptions.cpp
Go to the documentation of this file.
1 //===- LangOptions.cpp - C Language Family Language Options ---------------===//
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 // This file defines the LangOptions class.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "llvm/ADT/SmallString.h"
15 #include "llvm/Support/Path.h"
16 
17 using namespace clang;
18 
19 LangOptions::LangOptions() : LangStd(LangStandard::lang_unspecified) {
20 #define LANGOPT(Name, Bits, Default, Description) Name = Default;
21 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default);
22 #include "clang/Basic/LangOptions.def"
23 }
24 
26 #define LANGOPT(Name, Bits, Default, Description)
27 #define BENIGN_LANGOPT(Name, Bits, Default, Description) Name = Default;
28 #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
29  Name = static_cast<unsigned>(Default);
30 #include "clang/Basic/LangOptions.def"
31 
32  // Reset "benign" options with implied values (Options.td ImpliedBy relations)
33  // rather than their defaults. This avoids unexpected combinations and
34  // invocations that cannot be round-tripped to arguments.
35  // FIXME: we should derive this automatically from ImpliedBy in tablegen.
36  AllowFPReassoc = UnsafeFPMath;
37  NoHonorNaNs = FiniteMathOnly;
38  NoHonorInfs = FiniteMathOnly;
39 
40  // These options do not affect AST generation.
41  NoSanitizeFiles.clear();
44 
45  CurrentModule.clear();
46  IsHeaderFile = false;
47 }
48 
49 bool LangOptions::isNoBuiltinFunc(StringRef FuncName) const {
50  for (unsigned i = 0, e = NoBuiltinFuncs.size(); i != e; ++i)
51  if (FuncName == NoBuiltinFuncs[i])
52  return true;
53  return false;
54 }
55 
56 VersionTuple LangOptions::getOpenCLVersionTuple() const {
57  const int Ver = OpenCLCPlusPlus ? OpenCLCPlusPlusVersion : OpenCLVersion;
58  if (OpenCLCPlusPlus && Ver != 100)
59  return VersionTuple(Ver / 100);
60  return VersionTuple(Ver / 100, (Ver % 100) / 10);
61 }
62 
64  if (!OpenCLCPlusPlus)
65  return OpenCLVersion;
66  if (OpenCLCPlusPlusVersion == 100)
67  return 200;
68  if (OpenCLCPlusPlusVersion == 202100)
69  return 300;
70  llvm_unreachable("Unknown OpenCL version");
71 }
72 
74  for (const auto &Entry : MacroPrefixMap)
75  if (llvm::sys::path::replace_path_prefix(Path, Entry.first, Entry.second))
76  break;
77 }
78 
80  std::string Result;
81  {
82  llvm::raw_string_ostream Out(Result);
83  Out << (OpenCLCPlusPlus ? "C++ for OpenCL" : "OpenCL C") << " version "
84  << getOpenCLVersionTuple().getAsString();
85  }
86  return Result;
87 }
88 
90  const llvm::Triple &T,
91  std::vector<std::string> &Includes,
92  LangStandard::Kind LangStd) {
93  // Set some properties which depend solely on the input kind; it would be nice
94  // to move these to the language standard, and have the driver resolve the
95  // input kind + language standard.
96  //
97  // FIXME: Perhaps a better model would be for a single source file to have
98  // multiple language standards (C / C++ std, ObjC std, OpenCL std, OpenMP std)
99  // simultaneously active?
100  if (Lang == Language::Asm) {
101  Opts.AsmPreprocessor = 1;
102  } else if (Lang == Language::ObjC || Lang == Language::ObjCXX) {
103  Opts.ObjC = 1;
104  }
105 
109  Opts.LangStd = LangStd;
110  Opts.LineComment = Std.hasLineComments();
111  Opts.C99 = Std.isC99();
112  Opts.C11 = Std.isC11();
113  Opts.C17 = Std.isC17();
114  Opts.C23 = Std.isC23();
115  Opts.CPlusPlus = Std.isCPlusPlus();
116  Opts.CPlusPlus11 = Std.isCPlusPlus11();
117  Opts.CPlusPlus14 = Std.isCPlusPlus14();
118  Opts.CPlusPlus17 = Std.isCPlusPlus17();
119  Opts.CPlusPlus20 = Std.isCPlusPlus20();
120  Opts.CPlusPlus23 = Std.isCPlusPlus23();
121  Opts.CPlusPlus26 = Std.isCPlusPlus26();
122  Opts.GNUMode = Std.isGNUMode();
123  Opts.GNUCVersion = 0;
124  Opts.HexFloats = Std.hasHexFloats();
125  Opts.WChar = Std.isCPlusPlus();
126  Opts.Digraphs = Std.hasDigraphs();
127 
128  Opts.HLSL = Lang == Language::HLSL;
129  if (Opts.HLSL && Opts.IncludeDefaultHeader)
130  Includes.push_back("hlsl.h");
131 
132  // Set OpenCL Version.
133  Opts.OpenCL = Std.isOpenCL();
134  if (LangStd == LangStandard::lang_opencl10)
135  Opts.OpenCLVersion = 100;
136  else if (LangStd == LangStandard::lang_opencl11)
137  Opts.OpenCLVersion = 110;
138  else if (LangStd == LangStandard::lang_opencl12)
139  Opts.OpenCLVersion = 120;
140  else if (LangStd == LangStandard::lang_opencl20)
141  Opts.OpenCLVersion = 200;
142  else if (LangStd == LangStandard::lang_opencl30)
143  Opts.OpenCLVersion = 300;
144  else if (LangStd == LangStandard::lang_openclcpp10)
145  Opts.OpenCLCPlusPlusVersion = 100;
146  else if (LangStd == LangStandard::lang_openclcpp2021)
147  Opts.OpenCLCPlusPlusVersion = 202100;
148  else if (LangStd == LangStandard::lang_hlsl2015)
149  Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2015;
150  else if (LangStd == LangStandard::lang_hlsl2016)
151  Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2016;
152  else if (LangStd == LangStandard::lang_hlsl2017)
153  Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2017;
154  else if (LangStd == LangStandard::lang_hlsl2018)
155  Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2018;
156  else if (LangStd == LangStandard::lang_hlsl2021)
157  Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2021;
158  else if (LangStd == LangStandard::lang_hlsl202x)
159  Opts.HLSLVersion = (unsigned)LangOptions::HLSL_202x;
160 
161  // OpenCL has some additional defaults.
162  if (Opts.OpenCL) {
163  Opts.AltiVec = 0;
164  Opts.ZVector = 0;
165  Opts.setDefaultFPContractMode(LangOptions::FPM_On);
166  Opts.OpenCLCPlusPlus = Opts.CPlusPlus;
167  Opts.OpenCLPipes = Opts.getOpenCLCompatibleVersion() == 200;
168  Opts.OpenCLGenericAddressSpace = Opts.getOpenCLCompatibleVersion() == 200;
169 
170  // Include default header file for OpenCL.
171  if (Opts.IncludeDefaultHeader) {
172  if (Opts.DeclareOpenCLBuiltins) {
173  // Only include base header file for builtin types and constants.
174  Includes.push_back("opencl-c-base.h");
175  } else {
176  Includes.push_back("opencl-c.h");
177  }
178  }
179  }
180 
181  Opts.HIP = Lang == Language::HIP;
182  Opts.CUDA = Lang == Language::CUDA || Opts.HIP;
183  if (Opts.HIP) {
184  // HIP toolchain does not support 'Fast' FPOpFusion in backends since it
185  // fuses multiplication/addition instructions without contract flag from
186  // device library functions in LLVM bitcode, which causes accuracy loss in
187  // certain math functions, e.g. tan(-1e20) becomes -0.933 instead of 0.8446.
188  // For device library functions in bitcode to work, 'Strict' or 'Standard'
189  // FPOpFusion options in backends is needed. Therefore 'fast-honor-pragmas'
190  // FP contract option is used to allow fuse across statements in frontend
191  // whereas respecting contract flag in backend.
192  Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
193  } else if (Opts.CUDA) {
194  if (T.isSPIRV()) {
195  // Emit OpenCL version metadata in LLVM IR when targeting SPIR-V.
196  Opts.OpenCLVersion = 200;
197  }
198  // Allow fuse across statements disregarding pragmas.
199  Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
200  }
201 
202  Opts.RenderScript = Lang == Language::RenderScript;
203 
204  // OpenCL, C++ and C23 have bool, true, false keywords.
205  Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C23;
206 
207  // OpenCL and HLSL have half keyword
208  Opts.Half = Opts.OpenCL || Opts.HLSL;
209 }
210 
212  FPOptions result(LO);
213  return result;
214 }
215 
216 FPOptionsOverride FPOptions::getChangesSlow(const FPOptions &Base) const {
217  FPOptions::storage_type OverrideMask = 0;
218 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
219  if (get##NAME() != Base.get##NAME()) \
220  OverrideMask |= NAME##Mask;
221 #include "clang/Basic/FPOptions.def"
222  return FPOptionsOverride(*this, OverrideMask);
223 }
224 
225 LLVM_DUMP_METHOD void FPOptions::dump() {
226 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
227  llvm::errs() << "\n " #NAME " " << get##NAME();
228 #include "clang/Basic/FPOptions.def"
229  llvm::errs() << "\n";
230 }
231 
232 LLVM_DUMP_METHOD void FPOptionsOverride::dump() {
233 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
234  if (has##NAME##Override()) \
235  llvm::errs() << "\n " #NAME " Override is " << get##NAME##Override();
236 #include "clang/Basic/FPOptions.def"
237  llvm::errs() << "\n";
238 }
LangStandard::Kind Std
Defines the clang::LangOptions interface.
Represents difference between two FPOptions values.
Definition: LangOptions.h:956
LLVM_DUMP_METHOD void dump()
static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO)
Return the default value of FPOptions that's used when trailing storage isn't required.
uint32_t storage_type
Definition: LangOptions.h:807
LLVM_DUMP_METHOD void dump()
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:482
void resetNonModularOptions()
Reset all of the options that are not considered when building a module.
Definition: LangOptions.cpp:25
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
Definition: LangOptions.h:549
std::vector< std::string > XRayNeverInstrumentFiles
Paths to the XRay "never instrument" files specifying which objects (files, functions,...
Definition: LangOptions.h:506
bool isNoBuiltinFunc(StringRef Name) const
Is this a libc/libm function that is no longer recognized as a builtin because a -fno-builtin-* optio...
Definition: LangOptions.cpp:49
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
Definition: LangOptions.cpp:79
bool IsHeaderFile
Indicates whether the front-end is explicitly told that the input is a header file (i....
Definition: LangOptions.h:574
std::vector< std::string > XRayAlwaysInstrumentFiles
Paths to the XRay "always instrument" files specifying which objects (files, functions,...
Definition: LangOptions.h:500
VersionTuple getOpenCLVersionTuple() const
Return the OpenCL C or C++ version as a VersionTuple.
Definition: LangOptions.cpp:56
static void setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T, std::vector< std::string > &Includes, LangStandard::Kind LangStd=LangStandard::lang_unspecified)
Set language defaults for the given input language and language standard in the given LangOptions obj...
Definition: LangOptions.cpp:89
std::map< std::string, std::string, std::greater< std::string > > MacroPrefixMap
A prefix map for FILE, BASE_FILE and __builtin_FILE().
Definition: LangOptions.h:552
void remapPathPrefix(SmallVectorImpl< char > &Path) const
Remap path prefix according to -fmacro-prefix-path option.
Definition: LangOptions.cpp:73
LangStandard::Kind LangStd
The used language standard.
Definition: LangOptions.h:485
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Definition: LangOptions.cpp:63
std::vector< std::string > NoSanitizeFiles
Paths to files specifying which objects (files, functions, variables) should not be instrumented.
Definition: LangOptions.h:494
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:537
The JSON file list parser is used to communicate input to InstallAPI.
LangStandard::Kind getDefaultLanguageStandard(clang::Language Lang, const llvm::Triple &T)
Language
The language for the input, used to select and validate the language standard and possible actions.
Definition: LangStandard.h:23
@ Asm
Assembly: we accept this only so that we can preprocess it.
const FunctionProtoType * T
LangStandard - Information about the properties of a particular language standard.
Definition: LangStandard.h:71
static const LangStandard & getLangStandardForKind(Kind K)