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