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/TargetParser/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 to use target's platform-specific file separator when
483   /// __FILE__ macro is used and when concatenating filename with directory or
484   /// to use build environment 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   // Indicates whether we should keep all nullptr checks for pointers
491   // received as a result of a standard operator new (-fcheck-new)
492   bool CheckNew = false;
493 
494   LangOptions();
495 
496   /// Set language defaults for the given input language and
497   /// language standard in the given LangOptions object.
498   ///
499   /// \param Opts - The LangOptions object to set up.
500   /// \param Lang - The input language.
501   /// \param T - The target triple.
502   /// \param Includes - If the language requires extra headers to be implicitly
503   ///                   included, they will be appended to this list.
504   /// \param LangStd - The input language standard.
505   static void
506   setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T,
507                   std::vector<std::string> &Includes,
508                   LangStandard::Kind LangStd = LangStandard::lang_unspecified);
509 
510   // Define accessors/mutators for language options of enumeration type.
511 #define LANGOPT(Name, Bits, Default, Description)
512 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
513   Type get##Name() const { return static_cast<Type>(Name); } \
514   void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
515 #include "clang/Basic/LangOptions.def"
516 
517   /// Are we compiling a module?
518   bool isCompilingModule() const {
519     return getCompilingModule() != CMK_None;
520   }
521 
522   /// Are we compiling a standard c++ module interface?
523   bool isCompilingModuleInterface() const {
524     return getCompilingModule() == CMK_ModuleInterface;
525   }
526 
527   /// Are we compiling a module implementation?
528   bool isCompilingModuleImplementation() const {
529     return !isCompilingModule() && !ModuleName.empty();
530   }
531 
532   /// Do we need to track the owning module for a local declaration?
533   bool trackLocalOwningModule() const {
534     return isCompilingModule() || ModulesLocalVisibility;
535   }
536 
537   bool isSignedOverflowDefined() const {
538     return getSignedOverflowBehavior() == SOB_Defined;
539   }
540 
541   bool isSubscriptPointerArithmetic() const {
542     return ObjCRuntime.isSubscriptPointerArithmetic() &&
543            !ObjCSubscriptingLegacyRuntime;
544   }
545 
546   bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
547     return MSCompatibilityVersion >= MajorVersion * 100000U;
548   }
549 
550   /// Reset all of the options that are not considered when building a
551   /// module.
552   void resetNonModularOptions();
553 
554   /// Is this a libc/libm function that is no longer recognized as a
555   /// builtin because a -fno-builtin-* option has been specified?
556   bool isNoBuiltinFunc(StringRef Name) const;
557 
558   /// True if any ObjC types may have non-trivial lifetime qualifiers.
559   bool allowsNonTrivialObjCLifetimeQualifiers() const {
560     return ObjCAutoRefCount || ObjCWeak;
561   }
562 
563   bool assumeFunctionsAreConvergent() const {
564     return ConvergentFunctions;
565   }
566 
567   /// Return the OpenCL C or C++ version as a VersionTuple.
568   VersionTuple getOpenCLVersionTuple() const;
569 
570   /// Return the OpenCL version that kernel language is compatible with
571   unsigned getOpenCLCompatibleVersion() const;
572 
573   /// Return the OpenCL C or C++ for OpenCL language name and version
574   /// as a string.
575   std::string getOpenCLVersionString() const;
576 
577   /// Returns true if functions without prototypes or functions with an
578   /// identifier list (aka K&R C functions) are not allowed.
579   bool requiresStrictPrototypes() const {
580     return CPlusPlus || C2x || DisableKNRFunctions;
581   }
582 
583   /// Returns true if implicit function declarations are allowed in the current
584   /// language mode.
585   bool implicitFunctionsAllowed() const {
586     return !requiresStrictPrototypes() && !OpenCL;
587   }
588 
589   /// Returns true if implicit int is part of the language requirements.
590   bool isImplicitIntRequired() const { return !CPlusPlus && !C99; }
591 
592   /// Returns true if implicit int is supported at all.
593   bool isImplicitIntAllowed() const { return !CPlusPlus && !C2x; }
594 
595   /// Check if return address signing is enabled.
596   bool hasSignReturnAddress() const {
597     return getSignReturnAddressScope() != SignReturnAddressScopeKind::None;
598   }
599 
600   /// Check if return address signing uses AKey.
601   bool isSignReturnAddressWithAKey() const {
602     return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey;
603   }
604 
605   /// Check if leaf functions are also signed.
606   bool isSignReturnAddressScopeAll() const {
607     return getSignReturnAddressScope() == SignReturnAddressScopeKind::All;
608   }
609 
610   bool hasSjLjExceptions() const {
611     return getExceptionHandling() == ExceptionHandlingKind::SjLj;
612   }
613 
614   bool hasSEHExceptions() const {
615     return getExceptionHandling() == ExceptionHandlingKind::WinEH;
616   }
617 
618   bool hasDWARFExceptions() const {
619     return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI;
620   }
621 
622   bool hasWasmExceptions() const {
623     return getExceptionHandling() == ExceptionHandlingKind::Wasm;
624   }
625 
626   bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; }
627 
628   bool hasDefaultVisibilityExportMapping() const {
629     return getDefaultVisibilityExportMapping() !=
630            DefaultVisiblityExportMapping::None;
631   }
632 
633   bool isExplicitDefaultVisibilityExportMapping() const {
634     return getDefaultVisibilityExportMapping() ==
635            DefaultVisiblityExportMapping::Explicit;
636   }
637 
638   bool isAllDefaultVisibilityExportMapping() const {
639     return getDefaultVisibilityExportMapping() ==
640            DefaultVisiblityExportMapping::All;
641   }
642 
643   /// Remap path prefix according to -fmacro-prefix-path option.
644   void remapPathPrefix(SmallVectorImpl<char> &Path) const;
645 
646   RoundingMode getDefaultRoundingMode() const {
647     return RoundingMath ? RoundingMode::Dynamic
648                         : RoundingMode::NearestTiesToEven;
649   }
650 
651   FPExceptionModeKind getDefaultExceptionMode() const {
652     FPExceptionModeKind EM = getFPExceptionMode();
653     if (EM == FPExceptionModeKind::FPE_Default)
654       return FPExceptionModeKind::FPE_Ignore;
655     return EM;
656   }
657 };
658 
659 /// Floating point control options
660 class FPOptionsOverride;
661 class FPOptions {
662 public:
663   // We start by defining the layout.
664   using storage_type = uint32_t;
665 
666   using RoundingMode = llvm::RoundingMode;
667 
668   static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type);
669 
670   // Define a fake option named "First" so that we have a PREVIOUS even for the
671   // real first option.
672   static constexpr storage_type FirstShift = 0, FirstWidth = 0;
673 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
674   static constexpr storage_type NAME##Shift =                                  \
675       PREVIOUS##Shift + PREVIOUS##Width;                                       \
676   static constexpr storage_type NAME##Width = WIDTH;                           \
677   static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1)          \
678                                              << NAME##Shift;
679 #include "clang/Basic/FPOptions.def"
680 
681   static constexpr storage_type TotalWidth = 0
682 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH
683 #include "clang/Basic/FPOptions.def"
684       ;
685   static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions");
686 
687 private:
688   storage_type Value;
689 
690   FPOptionsOverride getChangesSlow(const FPOptions &Base) const;
691 
692 public:
693   FPOptions() : Value(0) {
694     setFPContractMode(LangOptions::FPM_Off);
695     setConstRoundingMode(RoundingMode::Dynamic);
696     setSpecifiedExceptionMode(LangOptions::FPE_Default);
697   }
698   explicit FPOptions(const LangOptions &LO) {
699     Value = 0;
700     // The language fp contract option FPM_FastHonorPragmas has the same effect
701     // as FPM_Fast in frontend. For simplicity, use FPM_Fast uniformly in
702     // frontend.
703     auto LangOptContractMode = LO.getDefaultFPContractMode();
704     if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas)
705       LangOptContractMode = LangOptions::FPM_Fast;
706     setFPContractMode(LangOptContractMode);
707     setRoundingMath(LO.RoundingMath);
708     setConstRoundingMode(LangOptions::RoundingMode::Dynamic);
709     setSpecifiedExceptionMode(LO.getFPExceptionMode());
710     setAllowFPReassociate(LO.AllowFPReassoc);
711     setNoHonorNaNs(LO.NoHonorNaNs);
712     setNoHonorInfs(LO.NoHonorInfs);
713     setNoSignedZero(LO.NoSignedZero);
714     setAllowReciprocal(LO.AllowRecip);
715     setAllowApproxFunc(LO.ApproxFunc);
716     if (getFPContractMode() == LangOptions::FPM_On &&
717         getRoundingMode() == llvm::RoundingMode::Dynamic &&
718         getExceptionMode() == LangOptions::FPE_Strict)
719       // If the FP settings are set to the "strict" model, then
720       // FENV access is set to true. (ffp-model=strict)
721       setAllowFEnvAccess(true);
722     else
723       setAllowFEnvAccess(LangOptions::FPM_Off);
724   }
725 
726   bool allowFPContractWithinStatement() const {
727     return getFPContractMode() == LangOptions::FPM_On;
728   }
729   void setAllowFPContractWithinStatement() {
730     setFPContractMode(LangOptions::FPM_On);
731   }
732 
733   bool allowFPContractAcrossStatement() const {
734     return getFPContractMode() == LangOptions::FPM_Fast;
735   }
736   void setAllowFPContractAcrossStatement() {
737     setFPContractMode(LangOptions::FPM_Fast);
738   }
739 
740   bool isFPConstrained() const {
741     return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven ||
742            getExceptionMode() != LangOptions::FPE_Ignore ||
743            getAllowFEnvAccess();
744   }
745 
746   RoundingMode getRoundingMode() const {
747     RoundingMode RM = getConstRoundingMode();
748     if (RM == RoundingMode::Dynamic) {
749       // C2x: 7.6.2p3  If the FE_DYNAMIC mode is specified and FENV_ACCESS is
750       // "off", the translator may assume that the default rounding mode is in
751       // effect.
752       if (!getAllowFEnvAccess() && !getRoundingMath())
753         RM = RoundingMode::NearestTiesToEven;
754     }
755     return RM;
756   }
757 
758   LangOptions::FPExceptionModeKind getExceptionMode() const {
759     LangOptions::FPExceptionModeKind EM = getSpecifiedExceptionMode();
760     if (EM == LangOptions::FPExceptionModeKind::FPE_Default) {
761       if (getAllowFEnvAccess())
762         return LangOptions::FPExceptionModeKind::FPE_Strict;
763       else
764         return LangOptions::FPExceptionModeKind::FPE_Ignore;
765     }
766     return EM;
767   }
768 
769   bool operator==(FPOptions other) const { return Value == other.Value; }
770 
771   /// Return the default value of FPOptions that's used when trailing
772   /// storage isn't required.
773   static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO);
774 
775   storage_type getAsOpaqueInt() const { return Value; }
776   static FPOptions getFromOpaqueInt(storage_type Value) {
777     FPOptions Opts;
778     Opts.Value = Value;
779     return Opts;
780   }
781 
782   /// Return difference with the given option set.
783   FPOptionsOverride getChangesFrom(const FPOptions &Base) const;
784 
785   // We can define most of the accessors automatically:
786 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
787   TYPE get##NAME() const {                                                     \
788     return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift);             \
789   }                                                                            \
790   void set##NAME(TYPE value) {                                                 \
791     Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift);      \
792   }
793 #include "clang/Basic/FPOptions.def"
794   LLVM_DUMP_METHOD void dump();
795 };
796 
797 /// Represents difference between two FPOptions values.
798 ///
799 /// The effect of language constructs changing the set of floating point options
800 /// is usually a change of some FP properties while leaving others intact. This
801 /// class describes such changes by keeping information about what FP options
802 /// are overridden.
803 ///
804 /// The integral set of FP options, described by the class FPOptions, may be
805 /// represented as a default FP option set, defined by language standard and
806 /// command line options, with the overrides introduced by pragmas.
807 ///
808 /// The is implemented as a value of the new FPOptions plus a mask showing which
809 /// fields are actually set in it.
810 class FPOptionsOverride {
811   FPOptions Options = FPOptions::getFromOpaqueInt(0);
812   FPOptions::storage_type OverrideMask = 0;
813 
814 public:
815   using RoundingMode = llvm::RoundingMode;
816 
817   /// The type suitable for storing values of FPOptionsOverride. Must be twice
818   /// as wide as bit size of FPOption.
819   using storage_type = uint64_t;
820   static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type),
821                 "Too short type for FPOptionsOverride");
822 
823   /// Bit mask selecting bits of OverrideMask in serialized representation of
824   /// FPOptionsOverride.
825   static constexpr storage_type OverrideMaskBits =
826       (static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1;
827 
828   FPOptionsOverride() {}
829   FPOptionsOverride(const LangOptions &LO)
830       : Options(LO), OverrideMask(OverrideMaskBits) {}
831   FPOptionsOverride(FPOptions FPO)
832       : Options(FPO), OverrideMask(OverrideMaskBits) {}
833   FPOptionsOverride(FPOptions FPO, FPOptions::storage_type Mask)
834       : Options(FPO), OverrideMask(Mask) {}
835 
836   bool requiresTrailingStorage() const { return OverrideMask != 0; }
837 
838   void setAllowFPContractWithinStatement() {
839     setFPContractModeOverride(LangOptions::FPM_On);
840   }
841 
842   void setAllowFPContractAcrossStatement() {
843     setFPContractModeOverride(LangOptions::FPM_Fast);
844   }
845 
846   void setDisallowFPContract() {
847     setFPContractModeOverride(LangOptions::FPM_Off);
848   }
849 
850   void setFPPreciseEnabled(bool Value) {
851     setAllowFPReassociateOverride(!Value);
852     setNoHonorNaNsOverride(!Value);
853     setNoHonorInfsOverride(!Value);
854     setNoSignedZeroOverride(!Value);
855     setAllowReciprocalOverride(!Value);
856     setAllowApproxFuncOverride(!Value);
857     if (Value)
858       /* Precise mode implies fp_contract=on and disables ffast-math */
859       setAllowFPContractWithinStatement();
860     else
861       /* Precise mode disabled sets fp_contract=fast and enables ffast-math */
862       setAllowFPContractAcrossStatement();
863   }
864 
865   storage_type getAsOpaqueInt() const {
866     return (static_cast<storage_type>(Options.getAsOpaqueInt())
867             << FPOptions::StorageBitSize) |
868            OverrideMask;
869   }
870   static FPOptionsOverride getFromOpaqueInt(storage_type I) {
871     FPOptionsOverride Opts;
872     Opts.OverrideMask = I & OverrideMaskBits;
873     Opts.Options = FPOptions::getFromOpaqueInt(I >> FPOptions::StorageBitSize);
874     return Opts;
875   }
876 
877   FPOptions applyOverrides(FPOptions Base) {
878     FPOptions Result =
879         FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) |
880                                      (Options.getAsOpaqueInt() & OverrideMask));
881     return Result;
882   }
883 
884   FPOptions applyOverrides(const LangOptions &LO) {
885     return applyOverrides(FPOptions(LO));
886   }
887 
888   bool operator==(FPOptionsOverride other) const {
889     return Options == other.Options && OverrideMask == other.OverrideMask;
890   }
891   bool operator!=(FPOptionsOverride other) const { return !(*this == other); }
892 
893 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
894   bool has##NAME##Override() const {                                           \
895     return OverrideMask & FPOptions::NAME##Mask;                               \
896   }                                                                            \
897   TYPE get##NAME##Override() const {                                           \
898     assert(has##NAME##Override());                                             \
899     return Options.get##NAME();                                                \
900   }                                                                            \
901   void clear##NAME##Override() {                                               \
902     /* Clear the actual value so that we don't have spurious differences when  \
903      * testing equality. */                                                    \
904     Options.set##NAME(TYPE(0));                                                \
905     OverrideMask &= ~FPOptions::NAME##Mask;                                    \
906   }                                                                            \
907   void set##NAME##Override(TYPE value) {                                       \
908     Options.set##NAME(value);                                                  \
909     OverrideMask |= FPOptions::NAME##Mask;                                     \
910   }
911 #include "clang/Basic/FPOptions.def"
912   LLVM_DUMP_METHOD void dump();
913 };
914 
915 inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const {
916   if (Value == Base.Value)
917     return FPOptionsOverride();
918   return getChangesSlow(Base);
919 }
920 
921 /// Describes the kind of translation unit being processed.
922 enum TranslationUnitKind {
923   /// The translation unit is a complete translation unit.
924   TU_Complete,
925 
926   /// The translation unit is a prefix to a translation unit, and is
927   /// not complete.
928   TU_Prefix,
929 
930   /// The translation unit is a module.
931   TU_Module,
932 
933   /// The translation unit is a is a complete translation unit that we might
934   /// incrementally extend later.
935   TU_Incremental
936 };
937 
938 } // namespace clang
939 
940 #endif // LLVM_CLANG_BASIC_LANGOPTIONS_H
941