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?
isCompilingModule()514 bool isCompilingModule() const {
515 return getCompilingModule() != CMK_None;
516 }
517
518 /// Are we compiling a standard c++ module interface?
isCompilingModuleInterface()519 bool isCompilingModuleInterface() const {
520 return getCompilingModule() == CMK_ModuleInterface;
521 }
522
523 /// Are we compiling a module implementation?
isCompilingModuleImplementation()524 bool isCompilingModuleImplementation() const {
525 return !isCompilingModule() && !ModuleName.empty();
526 }
527
528 /// Do we need to track the owning module for a local declaration?
trackLocalOwningModule()529 bool trackLocalOwningModule() const {
530 return isCompilingModule() || ModulesLocalVisibility;
531 }
532
isSignedOverflowDefined()533 bool isSignedOverflowDefined() const {
534 return getSignedOverflowBehavior() == SOB_Defined;
535 }
536
isSubscriptPointerArithmetic()537 bool isSubscriptPointerArithmetic() const {
538 return ObjCRuntime.isSubscriptPointerArithmetic() &&
539 !ObjCSubscriptingLegacyRuntime;
540 }
541
isCompatibleWithMSVC(MSVCMajorVersion MajorVersion)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.
allowsNonTrivialObjCLifetimeQualifiers()555 bool allowsNonTrivialObjCLifetimeQualifiers() const {
556 return ObjCAutoRefCount || ObjCWeak;
557 }
558
assumeFunctionsAreConvergent()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.
requiresStrictPrototypes()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.
implicitFunctionsAllowed()581 bool implicitFunctionsAllowed() const {
582 return !requiresStrictPrototypes() && !OpenCL;
583 }
584
585 /// Returns true if implicit int is part of the language requirements.
isImplicitIntRequired()586 bool isImplicitIntRequired() const { return !CPlusPlus && !C99; }
587
588 /// Returns true if implicit int is supported at all.
isImplicitIntAllowed()589 bool isImplicitIntAllowed() const { return !CPlusPlus && !C2x; }
590
591 /// Check if return address signing is enabled.
hasSignReturnAddress()592 bool hasSignReturnAddress() const {
593 return getSignReturnAddressScope() != SignReturnAddressScopeKind::None;
594 }
595
596 /// Check if return address signing uses AKey.
isSignReturnAddressWithAKey()597 bool isSignReturnAddressWithAKey() const {
598 return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey;
599 }
600
601 /// Check if leaf functions are also signed.
isSignReturnAddressScopeAll()602 bool isSignReturnAddressScopeAll() const {
603 return getSignReturnAddressScope() == SignReturnAddressScopeKind::All;
604 }
605
hasSjLjExceptions()606 bool hasSjLjExceptions() const {
607 return getExceptionHandling() == ExceptionHandlingKind::SjLj;
608 }
609
hasSEHExceptions()610 bool hasSEHExceptions() const {
611 return getExceptionHandling() == ExceptionHandlingKind::WinEH;
612 }
613
hasDWARFExceptions()614 bool hasDWARFExceptions() const {
615 return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI;
616 }
617
hasWasmExceptions()618 bool hasWasmExceptions() const {
619 return getExceptionHandling() == ExceptionHandlingKind::Wasm;
620 }
621
isSYCL()622 bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; }
623
hasDefaultVisibilityExportMapping()624 bool hasDefaultVisibilityExportMapping() const {
625 return getDefaultVisibilityExportMapping() !=
626 DefaultVisiblityExportMapping::None;
627 }
628
isExplicitDefaultVisibilityExportMapping()629 bool isExplicitDefaultVisibilityExportMapping() const {
630 return getDefaultVisibilityExportMapping() ==
631 DefaultVisiblityExportMapping::Explicit;
632 }
633
isAllDefaultVisibilityExportMapping()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
getDefaultRoundingMode()642 RoundingMode getDefaultRoundingMode() const {
643 return RoundingMath ? RoundingMode::Dynamic
644 : RoundingMode::NearestTiesToEven;
645 }
646
getDefaultExceptionMode()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:
FPOptions()689 FPOptions() : Value(0) {
690 setFPContractMode(LangOptions::FPM_Off);
691 setConstRoundingMode(RoundingMode::Dynamic);
692 setSpecifiedExceptionMode(LangOptions::FPE_Default);
693 }
FPOptions(const LangOptions & LO)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
allowFPContractWithinStatement()722 bool allowFPContractWithinStatement() const {
723 return getFPContractMode() == LangOptions::FPM_On;
724 }
setAllowFPContractWithinStatement()725 void setAllowFPContractWithinStatement() {
726 setFPContractMode(LangOptions::FPM_On);
727 }
728
allowFPContractAcrossStatement()729 bool allowFPContractAcrossStatement() const {
730 return getFPContractMode() == LangOptions::FPM_Fast;
731 }
setAllowFPContractAcrossStatement()732 void setAllowFPContractAcrossStatement() {
733 setFPContractMode(LangOptions::FPM_Fast);
734 }
735
isFPConstrained()736 bool isFPConstrained() const {
737 return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven ||
738 getExceptionMode() != LangOptions::FPE_Ignore ||
739 getAllowFEnvAccess();
740 }
741
getRoundingMode()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
getExceptionMode()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
getAsOpaqueInt()771 storage_type getAsOpaqueInt() const { return Value; }
getFromOpaqueInt(storage_type 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
FPOptionsOverride()824 FPOptionsOverride() {}
FPOptionsOverride(const LangOptions & LO)825 FPOptionsOverride(const LangOptions &LO)
826 : Options(LO), OverrideMask(OverrideMaskBits) {}
FPOptionsOverride(FPOptions FPO)827 FPOptionsOverride(FPOptions FPO)
828 : Options(FPO), OverrideMask(OverrideMaskBits) {}
FPOptionsOverride(FPOptions FPO,FPOptions::storage_type Mask)829 FPOptionsOverride(FPOptions FPO, FPOptions::storage_type Mask)
830 : Options(FPO), OverrideMask(Mask) {}
831
requiresTrailingStorage()832 bool requiresTrailingStorage() const { return OverrideMask != 0; }
833
setAllowFPContractWithinStatement()834 void setAllowFPContractWithinStatement() {
835 setFPContractModeOverride(LangOptions::FPM_On);
836 }
837
setAllowFPContractAcrossStatement()838 void setAllowFPContractAcrossStatement() {
839 setFPContractModeOverride(LangOptions::FPM_Fast);
840 }
841
setDisallowFPContract()842 void setDisallowFPContract() {
843 setFPContractModeOverride(LangOptions::FPM_Off);
844 }
845
setFPPreciseEnabled(bool Value)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
getAsOpaqueInt()861 storage_type getAsOpaqueInt() const {
862 return (static_cast<storage_type>(Options.getAsOpaqueInt())
863 << FPOptions::StorageBitSize) |
864 OverrideMask;
865 }
getFromOpaqueInt(storage_type I)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
applyOverrides(FPOptions Base)873 FPOptions applyOverrides(FPOptions Base) {
874 FPOptions Result =
875 FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) |
876 (Options.getAsOpaqueInt() & OverrideMask));
877 return Result;
878 }
879
applyOverrides(const LangOptions & LO)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
getChangesFrom(const FPOptions & Base)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
937