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 <string>
28 #include <vector>
29 
30 namespace clang {
31 
32 /// Bitfields of LangOptions, split out from LangOptions in order to ensure that
33 /// this large collection of bitfields is a trivial class type.
34 class LangOptionsBase {
35   friend class CompilerInvocation;
36 
37 public:
38   // Define simple language options (with no accessors).
39 #define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits;
40 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
41 #include "clang/Basic/LangOptions.def"
42 
43 protected:
44   // Define language options of enumeration type. These are private, and will
45   // have accessors (below).
46 #define LANGOPT(Name, Bits, Default, Description)
47 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
48   unsigned Name : Bits;
49 #include "clang/Basic/LangOptions.def"
50 };
51 
52 /// In the Microsoft ABI, this controls the placement of virtual displacement
53 /// members used to implement virtual inheritance.
54 enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable };
55 
56 /// Keeps track of the various options that can be
57 /// enabled, which controls the dialect of C or C++ that is accepted.
58 class LangOptions : public LangOptionsBase {
59 public:
60   using Visibility = clang::Visibility;
61   using RoundingMode = llvm::RoundingMode;
62 
63   enum GCMode { NonGC, GCOnly, HybridGC };
64   enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
65 
66   // Automatic variables live on the stack, and when trivial they're usually
67   // uninitialized because it's undefined behavior to use them without
68   // initializing them.
69   enum class TrivialAutoVarInitKind { Uninitialized, Zero, Pattern };
70 
71   enum SignedOverflowBehaviorTy {
72     // Default C standard behavior.
73     SOB_Undefined,
74 
75     // -fwrapv
76     SOB_Defined,
77 
78     // -ftrapv
79     SOB_Trapping
80   };
81 
82   // FIXME: Unify with TUKind.
83   enum CompilingModuleKind {
84     /// Not compiling a module interface at all.
85     CMK_None,
86 
87     /// Compiling a module from a module map.
88     CMK_ModuleMap,
89 
90     /// Compiling a module from a list of header files.
91     CMK_HeaderModule,
92 
93     /// Compiling a C++ modules TS module interface unit.
94     CMK_ModuleInterface,
95   };
96 
97   enum PragmaMSPointersToMembersKind {
98     PPTMK_BestCase,
99     PPTMK_FullGeneralitySingleInheritance,
100     PPTMK_FullGeneralityMultipleInheritance,
101     PPTMK_FullGeneralityVirtualInheritance
102   };
103 
104   using MSVtorDispMode = clang::MSVtorDispMode;
105 
106   enum DefaultCallingConvention {
107     DCC_None,
108     DCC_CDecl,
109     DCC_FastCall,
110     DCC_StdCall,
111     DCC_VectorCall,
112     DCC_RegCall
113   };
114 
115   enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
116 
117   // Corresponds to _MSC_VER
118   enum MSVCMajorVersion {
119     MSVC2010 = 1600,
120     MSVC2012 = 1700,
121     MSVC2013 = 1800,
122     MSVC2015 = 1900,
123     MSVC2017 = 1910,
124     MSVC2017_5 = 1912,
125     MSVC2017_7 = 1914,
126     MSVC2019 = 1920,
127     MSVC2019_8 = 1928,
128   };
129 
130   enum SYCLMajorVersion {
131     SYCL_None,
132     SYCL_2017,
133     SYCL_2020,
134     // The "default" SYCL version to be used when none is specified on the
135     // frontend command line.
136     SYCL_Default = SYCL_2020
137   };
138 
139   /// Clang versions with different platform ABI conformance.
140   enum class ClangABI {
141     /// Attempt to be ABI-compatible with code generated by Clang 3.8.x
142     /// (SVN r257626). This causes <1 x long long> to be passed in an
143     /// integer register instead of an SSE register on x64_64.
144     Ver3_8,
145 
146     /// Attempt to be ABI-compatible with code generated by Clang 4.0.x
147     /// (SVN r291814). This causes move operations to be ignored when
148     /// determining whether a class type can be passed or returned directly.
149     Ver4,
150 
151     /// Attempt to be ABI-compatible with code generated by Clang 6.0.x
152     /// (SVN r321711). This causes determination of whether a type is
153     /// standard-layout to ignore collisions between empty base classes
154     /// and between base classes and member subobjects, which affects
155     /// whether we reuse base class tail padding in some ABIs.
156     Ver6,
157 
158     /// Attempt to be ABI-compatible with code generated by Clang 7.0.x
159     /// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be
160     /// compatible with __alignof (i.e., return the preferred alignment)
161     /// rather than returning the required alignment.
162     Ver7,
163 
164     /// Attempt to be ABI-compatible with code generated by Clang 9.0.x
165     /// (SVN r351319). This causes vectors of __int128 to be passed in memory
166     /// instead of passing in multiple scalar registers on x86_64 on Linux and
167     /// NetBSD.
168     Ver9,
169 
170     /// Attempt to be ABI-compatible with code generated by Clang 11.0.x
171     /// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit
172     /// vector member on the stack instead of using registers, to not properly
173     /// mangle substitutions for template names in some cases, and to mangle
174     /// declaration template arguments without a cast to the parameter type
175     /// even when that can lead to mangling collisions.
176     Ver11,
177 
178     /// Attempt to be ABI-compatible with code generated by Clang 12.0.x
179     /// (git 8e464dd76bef). This causes clang to mangle lambdas within
180     /// global-scope inline variables incorrectly.
181     Ver12,
182 
183     /// Conform to the underlying platform's C and C++ ABIs as closely
184     /// as we can.
185     Latest
186   };
187 
188   enum class CoreFoundationABI {
189     /// No interoperability ABI has been specified
190     Unspecified,
191     /// CoreFoundation does not have any language interoperability
192     Standalone,
193     /// Interoperability with the ObjectiveC runtime
194     ObjectiveC,
195     /// Interoperability with the latest known version of the Swift runtime
196     Swift,
197     /// Interoperability with the Swift 5.0 runtime
198     Swift5_0,
199     /// Interoperability with the Swift 4.2 runtime
200     Swift4_2,
201     /// Interoperability with the Swift 4.1 runtime
202     Swift4_1,
203   };
204 
205   enum FPModeKind {
206     // Disable the floating point pragma
207     FPM_Off,
208 
209     // Enable the floating point pragma
210     FPM_On,
211 
212     // Aggressively fuse FP ops (E.g. FMA) disregarding pragmas.
213     FPM_Fast,
214 
215     // Aggressively fuse FP ops and honor pragmas.
216     FPM_FastHonorPragmas
217   };
218 
219   /// Alias for RoundingMode::NearestTiesToEven.
220   static constexpr unsigned FPR_ToNearest =
221       static_cast<unsigned>(llvm::RoundingMode::NearestTiesToEven);
222 
223   /// Possible floating point exception behavior.
224   enum FPExceptionModeKind {
225     /// Assume that floating-point exceptions are masked.
226     FPE_Ignore,
227     /// Transformations do not cause new exceptions but may hide some.
228     FPE_MayTrap,
229     /// Strictly preserve the floating-point exception semantics.
230     FPE_Strict
231   };
232 
233   /// Possible exception handling behavior.
234   enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm };
235 
236   enum class LaxVectorConversionKind {
237     /// Permit no implicit vector bitcasts.
238     None,
239     /// Permit vector bitcasts between integer vectors with different numbers
240     /// of elements but the same total bit-width.
241     Integer,
242     /// Permit vector bitcasts between all vectors with the same total
243     /// bit-width.
244     All,
245   };
246 
247   enum class SignReturnAddressScopeKind {
248     /// No signing for any function.
249     None,
250     /// Sign the return address of functions that spill LR.
251     NonLeaf,
252     /// Sign the return address of all functions,
253     All
254   };
255 
256   enum class SignReturnAddressKeyKind {
257     /// Return address signing uses APIA key.
258     AKey,
259     /// Return address signing uses APIB key.
260     BKey
261   };
262 
263   enum class ThreadModelKind {
264     /// POSIX Threads.
265     POSIX,
266     /// Single Threaded Environment.
267     Single
268   };
269 
270   enum class ExtendArgsKind {
271     /// Integer arguments are sign or zero extended to 32/64 bits
272     /// during default argument promotions.
273     ExtendTo32,
274     ExtendTo64
275   };
276 
277 public:
278   /// The used language standard.
279   LangStandard::Kind LangStd;
280 
281   /// Set of enabled sanitizers.
282   SanitizerSet Sanitize;
283 
284   /// Paths to files specifying which objects
285   /// (files, functions, variables) should not be instrumented.
286   std::vector<std::string> NoSanitizeFiles;
287 
288   /// Paths to the XRay "always instrument" files specifying which
289   /// objects (files, functions, variables) should be imbued with the XRay
290   /// "always instrument" attribute.
291   /// WARNING: This is a deprecated field and will go away in the future.
292   std::vector<std::string> XRayAlwaysInstrumentFiles;
293 
294   /// Paths to the XRay "never instrument" files specifying which
295   /// objects (files, functions, variables) should be imbued with the XRay
296   /// "never instrument" attribute.
297   /// WARNING: This is a deprecated field and will go away in the future.
298   std::vector<std::string> XRayNeverInstrumentFiles;
299 
300   /// Paths to the XRay attribute list files, specifying which objects
301   /// (files, functions, variables) should be imbued with the appropriate XRay
302   /// attribute(s).
303   std::vector<std::string> XRayAttrListFiles;
304 
305   /// Paths to special case list files specifying which entities
306   /// (files, functions) should or should not be instrumented.
307   std::vector<std::string> ProfileListFiles;
308 
309   clang::ObjCRuntime ObjCRuntime;
310 
311   CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified;
312 
313   std::string ObjCConstantStringClass;
314 
315   /// The name of the handler function to be called when -ftrapv is
316   /// specified.
317   ///
318   /// If none is specified, abort (GCC-compatible behaviour).
319   std::string OverflowHandler;
320 
321   /// The module currently being compiled as specified by -fmodule-name.
322   std::string ModuleName;
323 
324   /// The name of the current module, of which the main source file
325   /// is a part. If CompilingModule is set, we are compiling the interface
326   /// of this module, otherwise we are compiling an implementation file of
327   /// it. This starts as ModuleName in case -fmodule-name is provided and
328   /// changes during compilation to reflect the current module.
329   std::string CurrentModule;
330 
331   /// The names of any features to enable in module 'requires' decls
332   /// in addition to the hard-coded list in Module.cpp and the target features.
333   ///
334   /// This list is sorted.
335   std::vector<std::string> ModuleFeatures;
336 
337   /// Options for parsing comments.
338   CommentOptions CommentOpts;
339 
340   /// A list of all -fno-builtin-* function names (e.g., memset).
341   std::vector<std::string> NoBuiltinFuncs;
342 
343   /// Triples of the OpenMP targets that the host code codegen should
344   /// take into account in order to generate accurate offloading descriptors.
345   std::vector<llvm::Triple> OMPTargetTriples;
346 
347   /// Name of the IR file that contains the result of the OpenMP target
348   /// host code generation.
349   std::string OMPHostIRFile;
350 
351   /// The user provided compilation unit ID, if non-empty. This is used to
352   /// externalize static variables which is needed to support accessing static
353   /// device variables in host code for single source offloading languages
354   /// like CUDA/HIP.
355   std::string CUID;
356 
357   /// C++ ABI to compile with, if specified by the frontend through -fc++-abi=.
358   /// This overrides the default ABI used by the target.
359   llvm::Optional<TargetCXXABI::Kind> CXXABI;
360 
361   /// Indicates whether the front-end is explicitly told that the
362   /// input is a header file (i.e. -x c-header).
363   bool IsHeaderFile = false;
364 
365   LangOptions();
366 
367   // Define accessors/mutators for language options of enumeration type.
368 #define LANGOPT(Name, Bits, Default, Description)
369 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
370   Type get##Name() const { return static_cast<Type>(Name); } \
371   void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
372 #include "clang/Basic/LangOptions.def"
373 
374   /// Are we compiling a module interface (.cppm or module map)?
isCompilingModule()375   bool isCompilingModule() const {
376     return getCompilingModule() != CMK_None;
377   }
378 
379   /// Do we need to track the owning module for a local declaration?
trackLocalOwningModule()380   bool trackLocalOwningModule() const {
381     return isCompilingModule() || ModulesLocalVisibility;
382   }
383 
isSignedOverflowDefined()384   bool isSignedOverflowDefined() const {
385     return getSignedOverflowBehavior() == SOB_Defined;
386   }
387 
isSubscriptPointerArithmetic()388   bool isSubscriptPointerArithmetic() const {
389     return ObjCRuntime.isSubscriptPointerArithmetic() &&
390            !ObjCSubscriptingLegacyRuntime;
391   }
392 
isCompatibleWithMSVC(MSVCMajorVersion MajorVersion)393   bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
394     return MSCompatibilityVersion >= MajorVersion * 100000U;
395   }
396 
397   /// Reset all of the options that are not considered when building a
398   /// module.
399   void resetNonModularOptions();
400 
401   /// Is this a libc/libm function that is no longer recognized as a
402   /// builtin because a -fno-builtin-* option has been specified?
403   bool isNoBuiltinFunc(StringRef Name) const;
404 
405   /// True if any ObjC types may have non-trivial lifetime qualifiers.
allowsNonTrivialObjCLifetimeQualifiers()406   bool allowsNonTrivialObjCLifetimeQualifiers() const {
407     return ObjCAutoRefCount || ObjCWeak;
408   }
409 
assumeFunctionsAreConvergent()410   bool assumeFunctionsAreConvergent() const {
411     return ConvergentFunctions;
412   }
413 
414   /// Return the OpenCL C or C++ version as a VersionTuple.
415   VersionTuple getOpenCLVersionTuple() const;
416 
417   /// Check if return address signing is enabled.
hasSignReturnAddress()418   bool hasSignReturnAddress() const {
419     return getSignReturnAddressScope() != SignReturnAddressScopeKind::None;
420   }
421 
422   /// Check if return address signing uses AKey.
isSignReturnAddressWithAKey()423   bool isSignReturnAddressWithAKey() const {
424     return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey;
425   }
426 
427   /// Check if leaf functions are also signed.
isSignReturnAddressScopeAll()428   bool isSignReturnAddressScopeAll() const {
429     return getSignReturnAddressScope() == SignReturnAddressScopeKind::All;
430   }
431 
hasSjLjExceptions()432   bool hasSjLjExceptions() const {
433     return getExceptionHandling() == ExceptionHandlingKind::SjLj;
434   }
435 
hasSEHExceptions()436   bool hasSEHExceptions() const {
437     return getExceptionHandling() == ExceptionHandlingKind::WinEH;
438   }
439 
hasDWARFExceptions()440   bool hasDWARFExceptions() const {
441     return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI;
442   }
443 
hasWasmExceptions()444   bool hasWasmExceptions() const {
445     return getExceptionHandling() == ExceptionHandlingKind::Wasm;
446   }
447 };
448 
449 /// Floating point control options
450 class FPOptionsOverride;
451 class FPOptions {
452 public:
453   // We start by defining the layout.
454   using storage_type = uint16_t;
455 
456   using RoundingMode = llvm::RoundingMode;
457 
458   static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type);
459 
460   // Define a fake option named "First" so that we have a PREVIOUS even for the
461   // real first option.
462   static constexpr storage_type FirstShift = 0, FirstWidth = 0;
463 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
464   static constexpr storage_type NAME##Shift =                                  \
465       PREVIOUS##Shift + PREVIOUS##Width;                                       \
466   static constexpr storage_type NAME##Width = WIDTH;                           \
467   static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1)          \
468                                              << NAME##Shift;
469 #include "clang/Basic/FPOptions.def"
470 
471   static constexpr storage_type TotalWidth = 0
472 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH
473 #include "clang/Basic/FPOptions.def"
474       ;
475   static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions");
476 
477 private:
478   storage_type Value;
479 
480 public:
FPOptions()481   FPOptions() : Value(0) {
482     setFPContractMode(LangOptions::FPM_Off);
483     setRoundingMode(static_cast<RoundingMode>(LangOptions::FPR_ToNearest));
484     setFPExceptionMode(LangOptions::FPE_Ignore);
485   }
FPOptions(const LangOptions & LO)486   explicit FPOptions(const LangOptions &LO) {
487     Value = 0;
488     // The language fp contract option FPM_FastHonorPragmas has the same effect
489     // as FPM_Fast in frontend. For simplicity, use FPM_Fast uniformly in
490     // frontend.
491     auto LangOptContractMode = LO.getDefaultFPContractMode();
492     if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas)
493       LangOptContractMode = LangOptions::FPM_Fast;
494     setFPContractMode(LangOptContractMode);
495     setRoundingMode(LO.getFPRoundingMode());
496     setFPExceptionMode(LO.getFPExceptionMode());
497     setAllowFPReassociate(LO.AllowFPReassoc);
498     setNoHonorNaNs(LO.NoHonorNaNs);
499     setNoHonorInfs(LO.NoHonorInfs);
500     setNoSignedZero(LO.NoSignedZero);
501     setAllowReciprocal(LO.AllowRecip);
502     setAllowApproxFunc(LO.ApproxFunc);
503     if (getFPContractMode() == LangOptions::FPM_On &&
504         getRoundingMode() == llvm::RoundingMode::Dynamic &&
505         getFPExceptionMode() == LangOptions::FPE_Strict)
506       // If the FP settings are set to the "strict" model, then
507       // FENV access is set to true. (ffp-model=strict)
508       setAllowFEnvAccess(true);
509     else
510       setAllowFEnvAccess(LangOptions::FPM_Off);
511   }
512 
allowFPContractWithinStatement()513   bool allowFPContractWithinStatement() const {
514     return getFPContractMode() == LangOptions::FPM_On;
515   }
setAllowFPContractWithinStatement()516   void setAllowFPContractWithinStatement() {
517     setFPContractMode(LangOptions::FPM_On);
518   }
519 
allowFPContractAcrossStatement()520   bool allowFPContractAcrossStatement() const {
521     return getFPContractMode() == LangOptions::FPM_Fast;
522   }
setAllowFPContractAcrossStatement()523   void setAllowFPContractAcrossStatement() {
524     setFPContractMode(LangOptions::FPM_Fast);
525   }
526 
isFPConstrained()527   bool isFPConstrained() const {
528     return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven ||
529            getFPExceptionMode() != LangOptions::FPE_Ignore ||
530            getAllowFEnvAccess();
531   }
532 
533   bool operator==(FPOptions other) const { return Value == other.Value; }
534 
535   /// Return the default value of FPOptions that's used when trailing
536   /// storage isn't required.
537   static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO);
538 
getAsOpaqueInt()539   storage_type getAsOpaqueInt() const { return Value; }
getFromOpaqueInt(storage_type Value)540   static FPOptions getFromOpaqueInt(storage_type Value) {
541     FPOptions Opts;
542     Opts.Value = Value;
543     return Opts;
544   }
545 
546   // We can define most of the accessors automatically:
547 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
548   TYPE get##NAME() const {                                                     \
549     return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift);             \
550   }                                                                            \
551   void set##NAME(TYPE value) {                                                 \
552     Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift);      \
553   }
554 #include "clang/Basic/FPOptions.def"
555   LLVM_DUMP_METHOD void dump();
556 };
557 
558 /// Represents difference between two FPOptions values.
559 ///
560 /// The effect of language constructs changing the set of floating point options
561 /// is usually a change of some FP properties while leaving others intact. This
562 /// class describes such changes by keeping information about what FP options
563 /// are overridden.
564 ///
565 /// The integral set of FP options, described by the class FPOptions, may be
566 /// represented as a default FP option set, defined by language standard and
567 /// command line options, with the overrides introduced by pragmas.
568 ///
569 /// The is implemented as a value of the new FPOptions plus a mask showing which
570 /// fields are actually set in it.
571 class FPOptionsOverride {
572   FPOptions Options = FPOptions::getFromOpaqueInt(0);
573   FPOptions::storage_type OverrideMask = 0;
574 
575 public:
576   using RoundingMode = llvm::RoundingMode;
577 
578   /// The type suitable for storing values of FPOptionsOverride. Must be twice
579   /// as wide as bit size of FPOption.
580   using storage_type = uint32_t;
581   static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type),
582                 "Too short type for FPOptionsOverride");
583 
584   /// Bit mask selecting bits of OverrideMask in serialized representation of
585   /// FPOptionsOverride.
586   static constexpr storage_type OverrideMaskBits =
587       (static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1;
588 
FPOptionsOverride()589   FPOptionsOverride() {}
FPOptionsOverride(const LangOptions & LO)590   FPOptionsOverride(const LangOptions &LO)
591       : Options(LO), OverrideMask(OverrideMaskBits) {}
FPOptionsOverride(FPOptions FPO)592   FPOptionsOverride(FPOptions FPO)
593       : Options(FPO), OverrideMask(OverrideMaskBits) {}
594 
requiresTrailingStorage()595   bool requiresTrailingStorage() const { return OverrideMask != 0; }
596 
setAllowFPContractWithinStatement()597   void setAllowFPContractWithinStatement() {
598     setFPContractModeOverride(LangOptions::FPM_On);
599   }
600 
setAllowFPContractAcrossStatement()601   void setAllowFPContractAcrossStatement() {
602     setFPContractModeOverride(LangOptions::FPM_Fast);
603   }
604 
setDisallowFPContract()605   void setDisallowFPContract() {
606     setFPContractModeOverride(LangOptions::FPM_Off);
607   }
608 
setFPPreciseEnabled(bool Value)609   void setFPPreciseEnabled(bool Value) {
610     setAllowFPReassociateOverride(!Value);
611     setNoHonorNaNsOverride(!Value);
612     setNoHonorInfsOverride(!Value);
613     setNoSignedZeroOverride(!Value);
614     setAllowReciprocalOverride(!Value);
615     setAllowApproxFuncOverride(!Value);
616     if (Value)
617       /* Precise mode implies fp_contract=on and disables ffast-math */
618       setAllowFPContractWithinStatement();
619     else
620       /* Precise mode disabled sets fp_contract=fast and enables ffast-math */
621       setAllowFPContractAcrossStatement();
622   }
623 
getAsOpaqueInt()624   storage_type getAsOpaqueInt() const {
625     return (static_cast<storage_type>(Options.getAsOpaqueInt())
626             << FPOptions::StorageBitSize) |
627            OverrideMask;
628   }
getFromOpaqueInt(storage_type I)629   static FPOptionsOverride getFromOpaqueInt(storage_type I) {
630     FPOptionsOverride Opts;
631     Opts.OverrideMask = I & OverrideMaskBits;
632     Opts.Options = FPOptions::getFromOpaqueInt(I >> FPOptions::StorageBitSize);
633     return Opts;
634   }
635 
applyOverrides(FPOptions Base)636   FPOptions applyOverrides(FPOptions Base) {
637     FPOptions Result =
638         FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) |
639                                      (Options.getAsOpaqueInt() & OverrideMask));
640     return Result;
641   }
642 
applyOverrides(const LangOptions & LO)643   FPOptions applyOverrides(const LangOptions &LO) {
644     return applyOverrides(FPOptions(LO));
645   }
646 
647   bool operator==(FPOptionsOverride other) const {
648     return Options == other.Options && OverrideMask == other.OverrideMask;
649   }
650   bool operator!=(FPOptionsOverride other) const { return !(*this == other); }
651 
652 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
653   bool has##NAME##Override() const {                                           \
654     return OverrideMask & FPOptions::NAME##Mask;                               \
655   }                                                                            \
656   TYPE get##NAME##Override() const {                                           \
657     assert(has##NAME##Override());                                             \
658     return Options.get##NAME();                                                \
659   }                                                                            \
660   void clear##NAME##Override() {                                               \
661     /* Clear the actual value so that we don't have spurious differences when  \
662      * testing equality. */                                                    \
663     Options.set##NAME(TYPE(0));                                                \
664     OverrideMask &= ~FPOptions::NAME##Mask;                                    \
665   }                                                                            \
666   void set##NAME##Override(TYPE value) {                                       \
667     Options.set##NAME(value);                                                  \
668     OverrideMask |= FPOptions::NAME##Mask;                                     \
669   }
670 #include "clang/Basic/FPOptions.def"
671   LLVM_DUMP_METHOD void dump();
672 };
673 
674 /// Describes the kind of translation unit being processed.
675 enum TranslationUnitKind {
676   /// The translation unit is a complete translation unit.
677   TU_Complete,
678 
679   /// The translation unit is a prefix to a translation unit, and is
680   /// not complete.
681   TU_Prefix,
682 
683   /// The translation unit is a module.
684   TU_Module
685 };
686 
687 } // namespace clang
688 
689 #endif // LLVM_CLANG_BASIC_LANGOPTIONS_H
690