Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- LangOptions.h - C Language Family Language Options -------*- 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::LangOptions interface. |
||
11 | // |
||
12 | //===----------------------------------------------------------------------===// |
||
13 | |||
14 | #ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H |
||
15 | #define LLVM_CLANG_BASIC_LANGOPTIONS_H |
||
16 | |||
17 | #include "clang/Basic/CommentOptions.h" |
||
18 | #include "clang/Basic/LLVM.h" |
||
19 | #include "clang/Basic/LangStandard.h" |
||
20 | #include "clang/Basic/ObjCRuntime.h" |
||
21 | #include "clang/Basic/Sanitizers.h" |
||
22 | #include "clang/Basic/TargetCXXABI.h" |
||
23 | #include "clang/Basic/Visibility.h" |
||
24 | #include "llvm/ADT/FloatingPointMode.h" |
||
25 | #include "llvm/ADT/StringRef.h" |
||
26 | #include "llvm/ADT/Triple.h" |
||
27 | #include <optional> |
||
28 | #include <string> |
||
29 | #include <vector> |
||
30 | |||
31 | namespace clang { |
||
32 | |||
33 | /// Bitfields of LangOptions, split out from LangOptions in order to ensure that |
||
34 | /// this large collection of bitfields is a trivial class type. |
||
35 | class LangOptionsBase { |
||
36 | friend class CompilerInvocation; |
||
37 | |||
38 | public: |
||
39 | // Define simple language options (with no accessors). |
||
40 | #define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits; |
||
41 | #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) |
||
42 | #include "clang/Basic/LangOptions.def" |
||
43 | |||
44 | protected: |
||
45 | // Define language options of enumeration type. These are private, and will |
||
46 | // have accessors (below). |
||
47 | #define LANGOPT(Name, Bits, Default, Description) |
||
48 | #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ |
||
49 | unsigned Name : Bits; |
||
50 | #include "clang/Basic/LangOptions.def" |
||
51 | }; |
||
52 | |||
53 | /// In the Microsoft ABI, this controls the placement of virtual displacement |
||
54 | /// members used to implement virtual inheritance. |
||
55 | enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable }; |
||
56 | |||
57 | /// Shader programs run in specific pipeline stages. |
||
58 | /// The order of these values matters, and must be kept in sync with the |
||
59 | /// Triple Environment enum in llvm::Triple. The ordering is enforced in |
||
60 | /// static_asserts in Triple.cpp and in clang/Basic/HLSLRuntime.h. |
||
61 | enum class ShaderStage { |
||
62 | Pixel = 0, |
||
63 | Vertex, |
||
64 | Geometry, |
||
65 | Hull, |
||
66 | Domain, |
||
67 | Compute, |
||
68 | Library, |
||
69 | RayGeneration, |
||
70 | Intersection, |
||
71 | AnyHit, |
||
72 | ClosestHit, |
||
73 | Miss, |
||
74 | Callable, |
||
75 | Mesh, |
||
76 | Amplification, |
||
77 | Invalid, |
||
78 | }; |
||
79 | |||
80 | /// Keeps track of the various options that can be |
||
81 | /// enabled, which controls the dialect of C or C++ that is accepted. |
||
82 | class LangOptions : public LangOptionsBase { |
||
83 | public: |
||
84 | using Visibility = clang::Visibility; |
||
85 | using RoundingMode = llvm::RoundingMode; |
||
86 | |||
87 | enum GCMode { NonGC, GCOnly, HybridGC }; |
||
88 | enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq }; |
||
89 | |||
90 | // Automatic variables live on the stack, and when trivial they're usually |
||
91 | // uninitialized because it's undefined behavior to use them without |
||
92 | // initializing them. |
||
93 | enum class TrivialAutoVarInitKind { Uninitialized, Zero, Pattern }; |
||
94 | |||
95 | enum SignedOverflowBehaviorTy { |
||
96 | // Default C standard behavior. |
||
97 | SOB_Undefined, |
||
98 | |||
99 | // -fwrapv |
||
100 | SOB_Defined, |
||
101 | |||
102 | // -ftrapv |
||
103 | SOB_Trapping |
||
104 | }; |
||
105 | |||
106 | // FIXME: Unify with TUKind. |
||
107 | enum CompilingModuleKind { |
||
108 | /// Not compiling a module interface at all. |
||
109 | CMK_None, |
||
110 | |||
111 | /// Compiling a module from a module map. |
||
112 | CMK_ModuleMap, |
||
113 | |||
114 | /// Compiling a module header unit. |
||
115 | CMK_HeaderUnit, |
||
116 | |||
117 | /// Compiling a C++ modules interface unit. |
||
118 | CMK_ModuleInterface, |
||
119 | }; |
||
120 | |||
121 | enum PragmaMSPointersToMembersKind { |
||
122 | PPTMK_BestCase, |
||
123 | PPTMK_FullGeneralitySingleInheritance, |
||
124 | PPTMK_FullGeneralityMultipleInheritance, |
||
125 | PPTMK_FullGeneralityVirtualInheritance |
||
126 | }; |
||
127 | |||
128 | using MSVtorDispMode = clang::MSVtorDispMode; |
||
129 | |||
130 | enum DefaultCallingConvention { |
||
131 | DCC_None, |
||
132 | DCC_CDecl, |
||
133 | DCC_FastCall, |
||
134 | DCC_StdCall, |
||
135 | DCC_VectorCall, |
||
136 | DCC_RegCall |
||
137 | }; |
||
138 | |||
139 | enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; |
||
140 | |||
141 | // Corresponds to _MSC_VER |
||
142 | enum MSVCMajorVersion { |
||
143 | MSVC2010 = 1600, |
||
144 | MSVC2012 = 1700, |
||
145 | MSVC2013 = 1800, |
||
146 | MSVC2015 = 1900, |
||
147 | MSVC2017 = 1910, |
||
148 | MSVC2017_5 = 1912, |
||
149 | MSVC2017_7 = 1914, |
||
150 | MSVC2019 = 1920, |
||
151 | MSVC2019_5 = 1925, |
||
152 | MSVC2019_8 = 1928, |
||
153 | }; |
||
154 | |||
155 | enum SYCLMajorVersion { |
||
156 | SYCL_None, |
||
157 | SYCL_2017, |
||
158 | SYCL_2020, |
||
159 | // The "default" SYCL version to be used when none is specified on the |
||
160 | // frontend command line. |
||
161 | SYCL_Default = SYCL_2020 |
||
162 | }; |
||
163 | |||
164 | enum HLSLLangStd { |
||
165 | HLSL_Unset = 0, |
||
166 | HLSL_2015 = 2015, |
||
167 | HLSL_2016 = 2016, |
||
168 | HLSL_2017 = 2017, |
||
169 | HLSL_2018 = 2018, |
||
170 | HLSL_2021 = 2021, |
||
171 | HLSL_202x = 2029, |
||
172 | }; |
||
173 | |||
174 | /// Clang versions with different platform ABI conformance. |
||
175 | enum class ClangABI { |
||
176 | /// Attempt to be ABI-compatible with code generated by Clang 3.8.x |
||
177 | /// (SVN r257626). This causes <1 x long long> to be passed in an |
||
178 | /// integer register instead of an SSE register on x64_64. |
||
179 | Ver3_8, |
||
180 | |||
181 | /// Attempt to be ABI-compatible with code generated by Clang 4.0.x |
||
182 | /// (SVN r291814). This causes move operations to be ignored when |
||
183 | /// determining whether a class type can be passed or returned directly. |
||
184 | Ver4, |
||
185 | |||
186 | /// Attempt to be ABI-compatible with code generated by Clang 6.0.x |
||
187 | /// (SVN r321711). This causes determination of whether a type is |
||
188 | /// standard-layout to ignore collisions between empty base classes |
||
189 | /// and between base classes and member subobjects, which affects |
||
190 | /// whether we reuse base class tail padding in some ABIs. |
||
191 | Ver6, |
||
192 | |||
193 | /// Attempt to be ABI-compatible with code generated by Clang 7.0.x |
||
194 | /// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be |
||
195 | /// compatible with __alignof (i.e., return the preferred alignment) |
||
196 | /// rather than returning the required alignment. |
||
197 | Ver7, |
||
198 | |||
199 | /// Attempt to be ABI-compatible with code generated by Clang 9.0.x |
||
200 | /// (SVN r351319). This causes vectors of __int128 to be passed in memory |
||
201 | /// instead of passing in multiple scalar registers on x86_64 on Linux and |
||
202 | /// NetBSD. |
||
203 | Ver9, |
||
204 | |||
205 | /// Attempt to be ABI-compatible with code generated by Clang 11.0.x |
||
206 | /// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit |
||
207 | /// vector member on the stack instead of using registers, to not properly |
||
208 | /// mangle substitutions for template names in some cases, and to mangle |
||
209 | /// declaration template arguments without a cast to the parameter type |
||
210 | /// even when that can lead to mangling collisions. |
||
211 | Ver11, |
||
212 | |||
213 | /// Attempt to be ABI-compatible with code generated by Clang 12.0.x |
||
214 | /// (git 8e464dd76bef). This causes clang to mangle lambdas within |
||
215 | /// global-scope inline variables incorrectly. |
||
216 | Ver12, |
||
217 | |||
218 | /// Attempt to be ABI-compatible with code generated by Clang 14.0.x. |
||
219 | /// This causes clang to: |
||
220 | /// - mangle dependent nested names incorrectly. |
||
221 | /// - make trivial only those defaulted copy constructors with a |
||
222 | /// parameter-type-list equivalent to the parameter-type-list of an |
||
223 | /// implicit declaration. |
||
224 | Ver14, |
||
225 | |||
226 | /// Attempt to be ABI-compatible with code generated by Clang 15.0.x. |
||
227 | /// This causes clang to: |
||
228 | /// - Reverse the implementation for DR692, DR1395 and DR1432. |
||
229 | /// - pack non-POD members of packed structs. |
||
230 | /// - consider classes with defaulted special member functions non-pod. |
||
231 | Ver15, |
||
232 | |||
233 | /// Conform to the underlying platform's C and C++ ABIs as closely |
||
234 | /// as we can. |
||
235 | Latest |
||
236 | }; |
||
237 | |||
238 | enum class CoreFoundationABI { |
||
239 | /// No interoperability ABI has been specified |
||
240 | Unspecified, |
||
241 | /// CoreFoundation does not have any language interoperability |
||
242 | Standalone, |
||
243 | /// Interoperability with the ObjectiveC runtime |
||
244 | ObjectiveC, |
||
245 | /// Interoperability with the latest known version of the Swift runtime |
||
246 | Swift, |
||
247 | /// Interoperability with the Swift 5.0 runtime |
||
248 | Swift5_0, |
||
249 | /// Interoperability with the Swift 4.2 runtime |
||
250 | Swift4_2, |
||
251 | /// Interoperability with the Swift 4.1 runtime |
||
252 | Swift4_1, |
||
253 | }; |
||
254 | |||
255 | enum FPModeKind { |
||
256 | // Disable the floating point pragma |
||
257 | FPM_Off, |
||
258 | |||
259 | // Enable the floating point pragma |
||
260 | FPM_On, |
||
261 | |||
262 | // Aggressively fuse FP ops (E.g. FMA) disregarding pragmas. |
||
263 | FPM_Fast, |
||
264 | |||
265 | // Aggressively fuse FP ops and honor pragmas. |
||
266 | FPM_FastHonorPragmas |
||
267 | }; |
||
268 | |||
269 | /// Possible floating point exception behavior. |
||
270 | enum FPExceptionModeKind { |
||
271 | /// Assume that floating-point exceptions are masked. |
||
272 | FPE_Ignore, |
||
273 | /// Transformations do not cause new exceptions but may hide some. |
||
274 | FPE_MayTrap, |
||
275 | /// Strictly preserve the floating-point exception semantics. |
||
276 | FPE_Strict, |
||
277 | /// Used internally to represent initial unspecified value. |
||
278 | FPE_Default |
||
279 | }; |
||
280 | |||
281 | /// Possible float expression evaluation method choices. |
||
282 | enum FPEvalMethodKind { |
||
283 | /// The evaluation method cannot be determined or is inconsistent for this |
||
284 | /// target. |
||
285 | FEM_Indeterminable = -1, |
||
286 | /// Use the declared type for fp arithmetic. |
||
287 | FEM_Source = 0, |
||
288 | /// Use the type double for fp arithmetic. |
||
289 | FEM_Double = 1, |
||
290 | /// Use extended type for fp arithmetic. |
||
291 | FEM_Extended = 2, |
||
292 | /// Used only for FE option processing; this is only used to indicate that |
||
293 | /// the user did not specify an explicit evaluation method on the command |
||
294 | /// line and so the target should be queried for its default evaluation |
||
295 | /// method instead. |
||
296 | FEM_UnsetOnCommandLine = 3 |
||
297 | }; |
||
298 | |||
299 | enum ExcessPrecisionKind { FPP_Standard, FPP_Fast, FPP_None }; |
||
300 | |||
301 | /// Possible exception handling behavior. |
||
302 | enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm }; |
||
303 | |||
304 | enum class LaxVectorConversionKind { |
||
305 | /// Permit no implicit vector bitcasts. |
||
306 | None, |
||
307 | /// Permit vector bitcasts between integer vectors with different numbers |
||
308 | /// of elements but the same total bit-width. |
||
309 | Integer, |
||
310 | /// Permit vector bitcasts between all vectors with the same total |
||
311 | /// bit-width. |
||
312 | All, |
||
313 | }; |
||
314 | |||
315 | enum class AltivecSrcCompatKind { |
||
316 | // All vector compares produce scalars except vector pixel and vector bool. |
||
317 | // The types vector pixel and vector bool return vector results. |
||
318 | Mixed, |
||
319 | // All vector compares produce vector results as in GCC. |
||
320 | GCC, |
||
321 | // All vector compares produce scalars as in XL. |
||
322 | XL, |
||
323 | // Default clang behaviour. |
||
324 | Default = Mixed, |
||
325 | }; |
||
326 | |||
327 | enum class SignReturnAddressScopeKind { |
||
328 | /// No signing for any function. |
||
329 | None, |
||
330 | /// Sign the return address of functions that spill LR. |
||
331 | NonLeaf, |
||
332 | /// Sign the return address of all functions, |
||
333 | All |
||
334 | }; |
||
335 | |||
336 | enum class SignReturnAddressKeyKind { |
||
337 | /// Return address signing uses APIA key. |
||
338 | AKey, |
||
339 | /// Return address signing uses APIB key. |
||
340 | BKey |
||
341 | }; |
||
342 | |||
343 | enum class ThreadModelKind { |
||
344 | /// POSIX Threads. |
||
345 | POSIX, |
||
346 | /// Single Threaded Environment. |
||
347 | Single |
||
348 | }; |
||
349 | |||
350 | enum class ExtendArgsKind { |
||
351 | /// Integer arguments are sign or zero extended to 32/64 bits |
||
352 | /// during default argument promotions. |
||
353 | ExtendTo32, |
||
354 | ExtendTo64 |
||
355 | }; |
||
356 | |||
357 | enum class GPUDefaultStreamKind { |
||
358 | /// Legacy default stream |
||
359 | Legacy, |
||
360 | /// Per-thread default stream |
||
361 | PerThread, |
||
362 | }; |
||
363 | |||
364 | enum class DefaultVisiblityExportMapping { |
||
365 | None, |
||
366 | /// map only explicit default visibilities to exported |
||
367 | Explicit, |
||
368 | /// map all default visibilities to exported |
||
369 | All, |
||
370 | }; |
||
371 | |||
372 | enum class StrictFlexArraysLevelKind { |
||
373 | /// Any trailing array member is a FAM. |
||
374 | Default = 0, |
||
375 | /// Any trailing array member of undefined, 0, or 1 size is a FAM. |
||
376 | OneZeroOrIncomplete = 1, |
||
377 | /// Any trailing array member of undefined or 0 size is a FAM. |
||
378 | ZeroOrIncomplete = 2, |
||
379 | /// Any trailing array member of undefined size is a FAM. |
||
380 | IncompleteOnly = 3, |
||
381 | }; |
||
382 | |||
383 | public: |
||
384 | /// The used language standard. |
||
385 | LangStandard::Kind LangStd; |
||
386 | |||
387 | /// Set of enabled sanitizers. |
||
388 | SanitizerSet Sanitize; |
||
389 | /// Is at least one coverage instrumentation type enabled. |
||
390 | bool SanitizeCoverage = false; |
||
391 | |||
392 | /// Paths to files specifying which objects |
||
393 | /// (files, functions, variables) should not be instrumented. |
||
394 | std::vector<std::string> NoSanitizeFiles; |
||
395 | |||
396 | /// Paths to the XRay "always instrument" files specifying which |
||
397 | /// objects (files, functions, variables) should be imbued with the XRay |
||
398 | /// "always instrument" attribute. |
||
399 | /// WARNING: This is a deprecated field and will go away in the future. |
||
400 | std::vector<std::string> XRayAlwaysInstrumentFiles; |
||
401 | |||
402 | /// Paths to the XRay "never instrument" files specifying which |
||
403 | /// objects (files, functions, variables) should be imbued with the XRay |
||
404 | /// "never instrument" attribute. |
||
405 | /// WARNING: This is a deprecated field and will go away in the future. |
||
406 | std::vector<std::string> XRayNeverInstrumentFiles; |
||
407 | |||
408 | /// Paths to the XRay attribute list files, specifying which objects |
||
409 | /// (files, functions, variables) should be imbued with the appropriate XRay |
||
410 | /// attribute(s). |
||
411 | std::vector<std::string> XRayAttrListFiles; |
||
412 | |||
413 | /// Paths to special case list files specifying which entities |
||
414 | /// (files, functions) should or should not be instrumented. |
||
415 | std::vector<std::string> ProfileListFiles; |
||
416 | |||
417 | clang::ObjCRuntime ObjCRuntime; |
||
418 | |||
419 | CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified; |
||
420 | |||
421 | std::string ObjCConstantStringClass; |
||
422 | |||
423 | /// The name of the handler function to be called when -ftrapv is |
||
424 | /// specified. |
||
425 | /// |
||
426 | /// If none is specified, abort (GCC-compatible behaviour). |
||
427 | std::string OverflowHandler; |
||
428 | |||
429 | /// The module currently being compiled as specified by -fmodule-name. |
||
430 | std::string ModuleName; |
||
431 | |||
432 | /// The name of the current module, of which the main source file |
||
433 | /// is a part. If CompilingModule is set, we are compiling the interface |
||
434 | /// of this module, otherwise we are compiling an implementation file of |
||
435 | /// it. This starts as ModuleName in case -fmodule-name is provided and |
||
436 | /// changes during compilation to reflect the current module. |
||
437 | std::string CurrentModule; |
||
438 | |||
439 | /// The names of any features to enable in module 'requires' decls |
||
440 | /// in addition to the hard-coded list in Module.cpp and the target features. |
||
441 | /// |
||
442 | /// This list is sorted. |
||
443 | std::vector<std::string> ModuleFeatures; |
||
444 | |||
445 | /// Options for parsing comments. |
||
446 | CommentOptions CommentOpts; |
||
447 | |||
448 | /// A list of all -fno-builtin-* function names (e.g., memset). |
||
449 | std::vector<std::string> NoBuiltinFuncs; |
||
450 | |||
451 | /// A prefix map for __FILE__, __BASE_FILE__ and __builtin_FILE(). |
||
452 | std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap; |
||
453 | |||
454 | /// Triples of the OpenMP targets that the host code codegen should |
||
455 | /// take into account in order to generate accurate offloading descriptors. |
||
456 | std::vector<llvm::Triple> OMPTargetTriples; |
||
457 | |||
458 | /// Name of the IR file that contains the result of the OpenMP target |
||
459 | /// host code generation. |
||
460 | std::string OMPHostIRFile; |
||
461 | |||
462 | /// The user provided compilation unit ID, if non-empty. This is used to |
||
463 | /// externalize static variables which is needed to support accessing static |
||
464 | /// device variables in host code for single source offloading languages |
||
465 | /// like CUDA/HIP. |
||
466 | std::string CUID; |
||
467 | |||
468 | /// C++ ABI to compile with, if specified by the frontend through -fc++-abi=. |
||
469 | /// This overrides the default ABI used by the target. |
||
470 | std::optional<TargetCXXABI::Kind> CXXABI; |
||
471 | |||
472 | /// Indicates whether the front-end is explicitly told that the |
||
473 | /// input is a header file (i.e. -x c-header). |
||
474 | bool IsHeaderFile = false; |
||
475 | |||
476 | /// The default stream kind used for HIP kernel launching. |
||
477 | GPUDefaultStreamKind GPUDefaultStream; |
||
478 | |||
479 | /// The seed used by the randomize structure layout feature. |
||
480 | std::string RandstructSeed; |
||
481 | |||
482 | /// Indicates whether the __FILE__ macro should use the target's |
||
483 | /// platform-specific file separator or whether it should use the build |
||
484 | /// environment's platform-specific file separator. |
||
485 | /// |
||
486 | /// The plaform-specific path separator is the backslash(\) for Windows and |
||
487 | /// forward slash (/) elsewhere. |
||
488 | bool UseTargetPathSeparator = false; |
||
489 | |||
490 | LangOptions(); |
||
491 | |||
492 | /// Set language defaults for the given input language and |
||
493 | /// language standard in the given LangOptions object. |
||
494 | /// |
||
495 | /// \param Opts - The LangOptions object to set up. |
||
496 | /// \param Lang - The input language. |
||
497 | /// \param T - The target triple. |
||
498 | /// \param Includes - If the language requires extra headers to be implicitly |
||
499 | /// included, they will be appended to this list. |
||
500 | /// \param LangStd - The input language standard. |
||
501 | static void |
||
502 | setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T, |
||
503 | std::vector<std::string> &Includes, |
||
504 | LangStandard::Kind LangStd = LangStandard::lang_unspecified); |
||
505 | |||
506 | // Define accessors/mutators for language options of enumeration type. |
||
507 | #define LANGOPT(Name, Bits, Default, Description) |
||
508 | #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ |
||
509 | Type get##Name() const { return static_cast<Type>(Name); } \ |
||
510 | void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } |
||
511 | #include "clang/Basic/LangOptions.def" |
||
512 | |||
513 | /// Are we compiling a module? |
||
514 | bool isCompilingModule() const { |
||
515 | return getCompilingModule() != CMK_None; |
||
516 | } |
||
517 | |||
518 | /// Are we compiling a standard c++ module interface? |
||
519 | bool isCompilingModuleInterface() const { |
||
520 | return getCompilingModule() == CMK_ModuleInterface; |
||
521 | } |
||
522 | |||
523 | /// Are we compiling a module implementation? |
||
524 | bool isCompilingModuleImplementation() const { |
||
525 | return !isCompilingModule() && !ModuleName.empty(); |
||
526 | } |
||
527 | |||
528 | /// Do we need to track the owning module for a local declaration? |
||
529 | bool trackLocalOwningModule() const { |
||
530 | return isCompilingModule() || ModulesLocalVisibility; |
||
531 | } |
||
532 | |||
533 | bool isSignedOverflowDefined() const { |
||
534 | return getSignedOverflowBehavior() == SOB_Defined; |
||
535 | } |
||
536 | |||
537 | bool isSubscriptPointerArithmetic() const { |
||
538 | return ObjCRuntime.isSubscriptPointerArithmetic() && |
||
539 | !ObjCSubscriptingLegacyRuntime; |
||
540 | } |
||
541 | |||
542 | bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const { |
||
543 | return MSCompatibilityVersion >= MajorVersion * 100000U; |
||
544 | } |
||
545 | |||
546 | /// Reset all of the options that are not considered when building a |
||
547 | /// module. |
||
548 | void resetNonModularOptions(); |
||
549 | |||
550 | /// Is this a libc/libm function that is no longer recognized as a |
||
551 | /// builtin because a -fno-builtin-* option has been specified? |
||
552 | bool isNoBuiltinFunc(StringRef Name) const; |
||
553 | |||
554 | /// True if any ObjC types may have non-trivial lifetime qualifiers. |
||
555 | bool allowsNonTrivialObjCLifetimeQualifiers() const { |
||
556 | return ObjCAutoRefCount || ObjCWeak; |
||
557 | } |
||
558 | |||
559 | bool assumeFunctionsAreConvergent() const { |
||
560 | return ConvergentFunctions; |
||
561 | } |
||
562 | |||
563 | /// Return the OpenCL C or C++ version as a VersionTuple. |
||
564 | VersionTuple getOpenCLVersionTuple() const; |
||
565 | |||
566 | /// Return the OpenCL version that kernel language is compatible with |
||
567 | unsigned getOpenCLCompatibleVersion() const; |
||
568 | |||
569 | /// Return the OpenCL C or C++ for OpenCL language name and version |
||
570 | /// as a string. |
||
571 | std::string getOpenCLVersionString() const; |
||
572 | |||
573 | /// Returns true if functions without prototypes or functions with an |
||
574 | /// identifier list (aka K&R C functions) are not allowed. |
||
575 | bool requiresStrictPrototypes() const { |
||
576 | return CPlusPlus || C2x || DisableKNRFunctions; |
||
577 | } |
||
578 | |||
579 | /// Returns true if implicit function declarations are allowed in the current |
||
580 | /// language mode. |
||
581 | bool implicitFunctionsAllowed() const { |
||
582 | return !requiresStrictPrototypes() && !OpenCL; |
||
583 | } |
||
584 | |||
585 | /// Returns true if implicit int is part of the language requirements. |
||
586 | bool isImplicitIntRequired() const { return !CPlusPlus && !C99; } |
||
587 | |||
588 | /// Returns true if implicit int is supported at all. |
||
589 | bool isImplicitIntAllowed() const { return !CPlusPlus && !C2x; } |
||
590 | |||
591 | /// Check if return address signing is enabled. |
||
592 | bool hasSignReturnAddress() const { |
||
593 | return getSignReturnAddressScope() != SignReturnAddressScopeKind::None; |
||
594 | } |
||
595 | |||
596 | /// Check if return address signing uses AKey. |
||
597 | bool isSignReturnAddressWithAKey() const { |
||
598 | return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey; |
||
599 | } |
||
600 | |||
601 | /// Check if leaf functions are also signed. |
||
602 | bool isSignReturnAddressScopeAll() const { |
||
603 | return getSignReturnAddressScope() == SignReturnAddressScopeKind::All; |
||
604 | } |
||
605 | |||
606 | bool hasSjLjExceptions() const { |
||
607 | return getExceptionHandling() == ExceptionHandlingKind::SjLj; |
||
608 | } |
||
609 | |||
610 | bool hasSEHExceptions() const { |
||
611 | return getExceptionHandling() == ExceptionHandlingKind::WinEH; |
||
612 | } |
||
613 | |||
614 | bool hasDWARFExceptions() const { |
||
615 | return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI; |
||
616 | } |
||
617 | |||
618 | bool hasWasmExceptions() const { |
||
619 | return getExceptionHandling() == ExceptionHandlingKind::Wasm; |
||
620 | } |
||
621 | |||
622 | bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; } |
||
623 | |||
624 | bool hasDefaultVisibilityExportMapping() const { |
||
625 | return getDefaultVisibilityExportMapping() != |
||
626 | DefaultVisiblityExportMapping::None; |
||
627 | } |
||
628 | |||
629 | bool isExplicitDefaultVisibilityExportMapping() const { |
||
630 | return getDefaultVisibilityExportMapping() == |
||
631 | DefaultVisiblityExportMapping::Explicit; |
||
632 | } |
||
633 | |||
634 | bool isAllDefaultVisibilityExportMapping() const { |
||
635 | return getDefaultVisibilityExportMapping() == |
||
636 | DefaultVisiblityExportMapping::All; |
||
637 | } |
||
638 | |||
639 | /// Remap path prefix according to -fmacro-prefix-path option. |
||
640 | void remapPathPrefix(SmallVectorImpl<char> &Path) const; |
||
641 | |||
642 | RoundingMode getDefaultRoundingMode() const { |
||
643 | return RoundingMath ? RoundingMode::Dynamic |
||
644 | : RoundingMode::NearestTiesToEven; |
||
645 | } |
||
646 | |||
647 | FPExceptionModeKind getDefaultExceptionMode() const { |
||
648 | FPExceptionModeKind EM = getFPExceptionMode(); |
||
649 | if (EM == FPExceptionModeKind::FPE_Default) |
||
650 | return FPExceptionModeKind::FPE_Ignore; |
||
651 | return EM; |
||
652 | } |
||
653 | }; |
||
654 | |||
655 | /// Floating point control options |
||
656 | class FPOptionsOverride; |
||
657 | class FPOptions { |
||
658 | public: |
||
659 | // We start by defining the layout. |
||
660 | using storage_type = uint32_t; |
||
661 | |||
662 | using RoundingMode = llvm::RoundingMode; |
||
663 | |||
664 | static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type); |
||
665 | |||
666 | // Define a fake option named "First" so that we have a PREVIOUS even for the |
||
667 | // real first option. |
||
668 | static constexpr storage_type FirstShift = 0, FirstWidth = 0; |
||
669 | #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
||
670 | static constexpr storage_type NAME##Shift = \ |
||
671 | PREVIOUS##Shift + PREVIOUS##Width; \ |
||
672 | static constexpr storage_type NAME##Width = WIDTH; \ |
||
673 | static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1) \ |
||
674 | << NAME##Shift; |
||
675 | #include "clang/Basic/FPOptions.def" |
||
676 | |||
677 | static constexpr storage_type TotalWidth = 0 |
||
678 | #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH |
||
679 | #include "clang/Basic/FPOptions.def" |
||
680 | ; |
||
681 | static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions"); |
||
682 | |||
683 | private: |
||
684 | storage_type Value; |
||
685 | |||
686 | FPOptionsOverride getChangesSlow(const FPOptions &Base) const; |
||
687 | |||
688 | public: |
||
689 | FPOptions() : Value(0) { |
||
690 | setFPContractMode(LangOptions::FPM_Off); |
||
691 | setConstRoundingMode(RoundingMode::Dynamic); |
||
692 | setSpecifiedExceptionMode(LangOptions::FPE_Default); |
||
693 | } |
||
694 | explicit FPOptions(const LangOptions &LO) { |
||
695 | Value = 0; |
||
696 | // The language fp contract option FPM_FastHonorPragmas has the same effect |
||
697 | // as FPM_Fast in frontend. For simplicity, use FPM_Fast uniformly in |
||
698 | // frontend. |
||
699 | auto LangOptContractMode = LO.getDefaultFPContractMode(); |
||
700 | if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas) |
||
701 | LangOptContractMode = LangOptions::FPM_Fast; |
||
702 | setFPContractMode(LangOptContractMode); |
||
703 | setRoundingMath(LO.RoundingMath); |
||
704 | setConstRoundingMode(LangOptions::RoundingMode::Dynamic); |
||
705 | setSpecifiedExceptionMode(LO.getFPExceptionMode()); |
||
706 | setAllowFPReassociate(LO.AllowFPReassoc); |
||
707 | setNoHonorNaNs(LO.NoHonorNaNs); |
||
708 | setNoHonorInfs(LO.NoHonorInfs); |
||
709 | setNoSignedZero(LO.NoSignedZero); |
||
710 | setAllowReciprocal(LO.AllowRecip); |
||
711 | setAllowApproxFunc(LO.ApproxFunc); |
||
712 | if (getFPContractMode() == LangOptions::FPM_On && |
||
713 | getRoundingMode() == llvm::RoundingMode::Dynamic && |
||
714 | getExceptionMode() == LangOptions::FPE_Strict) |
||
715 | // If the FP settings are set to the "strict" model, then |
||
716 | // FENV access is set to true. (ffp-model=strict) |
||
717 | setAllowFEnvAccess(true); |
||
718 | else |
||
719 | setAllowFEnvAccess(LangOptions::FPM_Off); |
||
720 | } |
||
721 | |||
722 | bool allowFPContractWithinStatement() const { |
||
723 | return getFPContractMode() == LangOptions::FPM_On; |
||
724 | } |
||
725 | void setAllowFPContractWithinStatement() { |
||
726 | setFPContractMode(LangOptions::FPM_On); |
||
727 | } |
||
728 | |||
729 | bool allowFPContractAcrossStatement() const { |
||
730 | return getFPContractMode() == LangOptions::FPM_Fast; |
||
731 | } |
||
732 | void setAllowFPContractAcrossStatement() { |
||
733 | setFPContractMode(LangOptions::FPM_Fast); |
||
734 | } |
||
735 | |||
736 | bool isFPConstrained() const { |
||
737 | return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven || |
||
738 | getExceptionMode() != LangOptions::FPE_Ignore || |
||
739 | getAllowFEnvAccess(); |
||
740 | } |
||
741 | |||
742 | RoundingMode getRoundingMode() const { |
||
743 | RoundingMode RM = getConstRoundingMode(); |
||
744 | if (RM == RoundingMode::Dynamic) { |
||
745 | // C2x: 7.6.2p3 If the FE_DYNAMIC mode is specified and FENV_ACCESS is |
||
746 | // "off", the translator may assume that the default rounding mode is in |
||
747 | // effect. |
||
748 | if (!getAllowFEnvAccess() && !getRoundingMath()) |
||
749 | RM = RoundingMode::NearestTiesToEven; |
||
750 | } |
||
751 | return RM; |
||
752 | } |
||
753 | |||
754 | LangOptions::FPExceptionModeKind getExceptionMode() const { |
||
755 | LangOptions::FPExceptionModeKind EM = getSpecifiedExceptionMode(); |
||
756 | if (EM == LangOptions::FPExceptionModeKind::FPE_Default) { |
||
757 | if (getAllowFEnvAccess()) |
||
758 | return LangOptions::FPExceptionModeKind::FPE_Strict; |
||
759 | else |
||
760 | return LangOptions::FPExceptionModeKind::FPE_Ignore; |
||
761 | } |
||
762 | return EM; |
||
763 | } |
||
764 | |||
765 | bool operator==(FPOptions other) const { return Value == other.Value; } |
||
766 | |||
767 | /// Return the default value of FPOptions that's used when trailing |
||
768 | /// storage isn't required. |
||
769 | static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO); |
||
770 | |||
771 | storage_type getAsOpaqueInt() const { return Value; } |
||
772 | static FPOptions getFromOpaqueInt(storage_type Value) { |
||
773 | FPOptions Opts; |
||
774 | Opts.Value = Value; |
||
775 | return Opts; |
||
776 | } |
||
777 | |||
778 | /// Return difference with the given option set. |
||
779 | FPOptionsOverride getChangesFrom(const FPOptions &Base) const; |
||
780 | |||
781 | // We can define most of the accessors automatically: |
||
782 | #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
||
783 | TYPE get##NAME() const { \ |
||
784 | return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift); \ |
||
785 | } \ |
||
786 | void set##NAME(TYPE value) { \ |
||
787 | Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \ |
||
788 | } |
||
789 | #include "clang/Basic/FPOptions.def" |
||
790 | LLVM_DUMP_METHOD void dump(); |
||
791 | }; |
||
792 | |||
793 | /// Represents difference between two FPOptions values. |
||
794 | /// |
||
795 | /// The effect of language constructs changing the set of floating point options |
||
796 | /// is usually a change of some FP properties while leaving others intact. This |
||
797 | /// class describes such changes by keeping information about what FP options |
||
798 | /// are overridden. |
||
799 | /// |
||
800 | /// The integral set of FP options, described by the class FPOptions, may be |
||
801 | /// represented as a default FP option set, defined by language standard and |
||
802 | /// command line options, with the overrides introduced by pragmas. |
||
803 | /// |
||
804 | /// The is implemented as a value of the new FPOptions plus a mask showing which |
||
805 | /// fields are actually set in it. |
||
806 | class FPOptionsOverride { |
||
807 | FPOptions Options = FPOptions::getFromOpaqueInt(0); |
||
808 | FPOptions::storage_type OverrideMask = 0; |
||
809 | |||
810 | public: |
||
811 | using RoundingMode = llvm::RoundingMode; |
||
812 | |||
813 | /// The type suitable for storing values of FPOptionsOverride. Must be twice |
||
814 | /// as wide as bit size of FPOption. |
||
815 | using storage_type = uint64_t; |
||
816 | static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type), |
||
817 | "Too short type for FPOptionsOverride"); |
||
818 | |||
819 | /// Bit mask selecting bits of OverrideMask in serialized representation of |
||
820 | /// FPOptionsOverride. |
||
821 | static constexpr storage_type OverrideMaskBits = |
||
822 | (static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1; |
||
823 | |||
824 | FPOptionsOverride() {} |
||
825 | FPOptionsOverride(const LangOptions &LO) |
||
826 | : Options(LO), OverrideMask(OverrideMaskBits) {} |
||
827 | FPOptionsOverride(FPOptions FPO) |
||
828 | : Options(FPO), OverrideMask(OverrideMaskBits) {} |
||
829 | FPOptionsOverride(FPOptions FPO, FPOptions::storage_type Mask) |
||
830 | : Options(FPO), OverrideMask(Mask) {} |
||
831 | |||
832 | bool requiresTrailingStorage() const { return OverrideMask != 0; } |
||
833 | |||
834 | void setAllowFPContractWithinStatement() { |
||
835 | setFPContractModeOverride(LangOptions::FPM_On); |
||
836 | } |
||
837 | |||
838 | void setAllowFPContractAcrossStatement() { |
||
839 | setFPContractModeOverride(LangOptions::FPM_Fast); |
||
840 | } |
||
841 | |||
842 | void setDisallowFPContract() { |
||
843 | setFPContractModeOverride(LangOptions::FPM_Off); |
||
844 | } |
||
845 | |||
846 | void setFPPreciseEnabled(bool Value) { |
||
847 | setAllowFPReassociateOverride(!Value); |
||
848 | setNoHonorNaNsOverride(!Value); |
||
849 | setNoHonorInfsOverride(!Value); |
||
850 | setNoSignedZeroOverride(!Value); |
||
851 | setAllowReciprocalOverride(!Value); |
||
852 | setAllowApproxFuncOverride(!Value); |
||
853 | if (Value) |
||
854 | /* Precise mode implies fp_contract=on and disables ffast-math */ |
||
855 | setAllowFPContractWithinStatement(); |
||
856 | else |
||
857 | /* Precise mode disabled sets fp_contract=fast and enables ffast-math */ |
||
858 | setAllowFPContractAcrossStatement(); |
||
859 | } |
||
860 | |||
861 | storage_type getAsOpaqueInt() const { |
||
862 | return (static_cast<storage_type>(Options.getAsOpaqueInt()) |
||
863 | << FPOptions::StorageBitSize) | |
||
864 | OverrideMask; |
||
865 | } |
||
866 | static FPOptionsOverride getFromOpaqueInt(storage_type I) { |
||
867 | FPOptionsOverride Opts; |
||
868 | Opts.OverrideMask = I & OverrideMaskBits; |
||
869 | Opts.Options = FPOptions::getFromOpaqueInt(I >> FPOptions::StorageBitSize); |
||
870 | return Opts; |
||
871 | } |
||
872 | |||
873 | FPOptions applyOverrides(FPOptions Base) { |
||
874 | FPOptions Result = |
||
875 | FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) | |
||
876 | (Options.getAsOpaqueInt() & OverrideMask)); |
||
877 | return Result; |
||
878 | } |
||
879 | |||
880 | FPOptions applyOverrides(const LangOptions &LO) { |
||
881 | return applyOverrides(FPOptions(LO)); |
||
882 | } |
||
883 | |||
884 | bool operator==(FPOptionsOverride other) const { |
||
885 | return Options == other.Options && OverrideMask == other.OverrideMask; |
||
886 | } |
||
887 | bool operator!=(FPOptionsOverride other) const { return !(*this == other); } |
||
888 | |||
889 | #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
||
890 | bool has##NAME##Override() const { \ |
||
891 | return OverrideMask & FPOptions::NAME##Mask; \ |
||
892 | } \ |
||
893 | TYPE get##NAME##Override() const { \ |
||
894 | assert(has##NAME##Override()); \ |
||
895 | return Options.get##NAME(); \ |
||
896 | } \ |
||
897 | void clear##NAME##Override() { \ |
||
898 | /* Clear the actual value so that we don't have spurious differences when \ |
||
899 | * testing equality. */ \ |
||
900 | Options.set##NAME(TYPE(0)); \ |
||
901 | OverrideMask &= ~FPOptions::NAME##Mask; \ |
||
902 | } \ |
||
903 | void set##NAME##Override(TYPE value) { \ |
||
904 | Options.set##NAME(value); \ |
||
905 | OverrideMask |= FPOptions::NAME##Mask; \ |
||
906 | } |
||
907 | #include "clang/Basic/FPOptions.def" |
||
908 | LLVM_DUMP_METHOD void dump(); |
||
909 | }; |
||
910 | |||
911 | inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const { |
||
912 | if (Value == Base.Value) |
||
913 | return FPOptionsOverride(); |
||
914 | return getChangesSlow(Base); |
||
915 | } |
||
916 | |||
917 | /// Describes the kind of translation unit being processed. |
||
918 | enum TranslationUnitKind { |
||
919 | /// The translation unit is a complete translation unit. |
||
920 | TU_Complete, |
||
921 | |||
922 | /// The translation unit is a prefix to a translation unit, and is |
||
923 | /// not complete. |
||
924 | TU_Prefix, |
||
925 | |||
926 | /// The translation unit is a module. |
||
927 | TU_Module, |
||
928 | |||
929 | /// The translation unit is a is a complete translation unit that we might |
||
930 | /// incrementally extend later. |
||
931 | TU_Incremental |
||
932 | }; |
||
933 | |||
934 | } // namespace clang |
||
935 | |||
936 | #endif // LLVM_CLANG_BASIC_LANGOPTIONS_H |