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 AltivecSrcCompatKind {
248     // All vector compares produce scalars except vector pixel and vector bool.
249     // The types vector pixel and vector bool return vector results.
250     Mixed,
251     // All vector compares produce vector results as in GCC.
252     GCC,
253     // All vector compares produce scalars as in XL.
254     XL,
255     // Default clang behaviour.
256     Default = Mixed,
257   };
258 
259   enum class SignReturnAddressScopeKind {
260     /// No signing for any function.
261     None,
262     /// Sign the return address of functions that spill LR.
263     NonLeaf,
264     /// Sign the return address of all functions,
265     All
266   };
267 
268   enum class SignReturnAddressKeyKind {
269     /// Return address signing uses APIA key.
270     AKey,
271     /// Return address signing uses APIB key.
272     BKey
273   };
274 
275   enum class ThreadModelKind {
276     /// POSIX Threads.
277     POSIX,
278     /// Single Threaded Environment.
279     Single
280   };
281 
282   enum class ExtendArgsKind {
283     /// Integer arguments are sign or zero extended to 32/64 bits
284     /// during default argument promotions.
285     ExtendTo32,
286     ExtendTo64
287   };
288 
289 public:
290   /// The used language standard.
291   LangStandard::Kind LangStd;
292 
293   /// Set of enabled sanitizers.
294   SanitizerSet Sanitize;
295   /// Is at least one coverage instrumentation type enabled.
296   bool SanitizeCoverage = false;
297 
298   /// Paths to files specifying which objects
299   /// (files, functions, variables) should not be instrumented.
300   std::vector<std::string> NoSanitizeFiles;
301 
302   /// Paths to the XRay "always instrument" files specifying which
303   /// objects (files, functions, variables) should be imbued with the XRay
304   /// "always instrument" attribute.
305   /// WARNING: This is a deprecated field and will go away in the future.
306   std::vector<std::string> XRayAlwaysInstrumentFiles;
307 
308   /// Paths to the XRay "never instrument" files specifying which
309   /// objects (files, functions, variables) should be imbued with the XRay
310   /// "never instrument" attribute.
311   /// WARNING: This is a deprecated field and will go away in the future.
312   std::vector<std::string> XRayNeverInstrumentFiles;
313 
314   /// Paths to the XRay attribute list files, specifying which objects
315   /// (files, functions, variables) should be imbued with the appropriate XRay
316   /// attribute(s).
317   std::vector<std::string> XRayAttrListFiles;
318 
319   /// Paths to special case list files specifying which entities
320   /// (files, functions) should or should not be instrumented.
321   std::vector<std::string> ProfileListFiles;
322 
323   clang::ObjCRuntime ObjCRuntime;
324 
325   CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified;
326 
327   std::string ObjCConstantStringClass;
328 
329   /// The name of the handler function to be called when -ftrapv is
330   /// specified.
331   ///
332   /// If none is specified, abort (GCC-compatible behaviour).
333   std::string OverflowHandler;
334 
335   /// The module currently being compiled as specified by -fmodule-name.
336   std::string ModuleName;
337 
338   /// The name of the current module, of which the main source file
339   /// is a part. If CompilingModule is set, we are compiling the interface
340   /// of this module, otherwise we are compiling an implementation file of
341   /// it. This starts as ModuleName in case -fmodule-name is provided and
342   /// changes during compilation to reflect the current module.
343   std::string CurrentModule;
344 
345   /// The names of any features to enable in module 'requires' decls
346   /// in addition to the hard-coded list in Module.cpp and the target features.
347   ///
348   /// This list is sorted.
349   std::vector<std::string> ModuleFeatures;
350 
351   /// Options for parsing comments.
352   CommentOptions CommentOpts;
353 
354   /// A list of all -fno-builtin-* function names (e.g., memset).
355   std::vector<std::string> NoBuiltinFuncs;
356 
357   /// A prefix map for __FILE__, __BASE_FILE__ and __builtin_FILE().
358   std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap;
359 
360   /// Triples of the OpenMP targets that the host code codegen should
361   /// take into account in order to generate accurate offloading descriptors.
362   std::vector<llvm::Triple> OMPTargetTriples;
363 
364   /// Name of the IR file that contains the result of the OpenMP target
365   /// host code generation.
366   std::string OMPHostIRFile;
367 
368   /// The user provided compilation unit ID, if non-empty. This is used to
369   /// externalize static variables which is needed to support accessing static
370   /// device variables in host code for single source offloading languages
371   /// like CUDA/HIP.
372   std::string CUID;
373 
374   /// C++ ABI to compile with, if specified by the frontend through -fc++-abi=.
375   /// This overrides the default ABI used by the target.
376   llvm::Optional<TargetCXXABI::Kind> CXXABI;
377 
378   /// Indicates whether the front-end is explicitly told that the
379   /// input is a header file (i.e. -x c-header).
380   bool IsHeaderFile = false;
381 
382   LangOptions();
383 
384   // Define accessors/mutators for language options of enumeration type.
385 #define LANGOPT(Name, Bits, Default, Description)
386 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
387   Type get##Name() const { return static_cast<Type>(Name); } \
388   void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
389 #include "clang/Basic/LangOptions.def"
390 
391   /// Are we compiling a module interface (.cppm or module map)?
isCompilingModule()392   bool isCompilingModule() const {
393     return getCompilingModule() != CMK_None;
394   }
395 
396   /// Do we need to track the owning module for a local declaration?
trackLocalOwningModule()397   bool trackLocalOwningModule() const {
398     return isCompilingModule() || ModulesLocalVisibility;
399   }
400 
isSignedOverflowDefined()401   bool isSignedOverflowDefined() const {
402     return getSignedOverflowBehavior() == SOB_Defined;
403   }
404 
isSubscriptPointerArithmetic()405   bool isSubscriptPointerArithmetic() const {
406     return ObjCRuntime.isSubscriptPointerArithmetic() &&
407            !ObjCSubscriptingLegacyRuntime;
408   }
409 
isCompatibleWithMSVC(MSVCMajorVersion MajorVersion)410   bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
411     return MSCompatibilityVersion >= MajorVersion * 100000U;
412   }
413 
414   /// Reset all of the options that are not considered when building a
415   /// module.
416   void resetNonModularOptions();
417 
418   /// Is this a libc/libm function that is no longer recognized as a
419   /// builtin because a -fno-builtin-* option has been specified?
420   bool isNoBuiltinFunc(StringRef Name) const;
421 
422   /// True if any ObjC types may have non-trivial lifetime qualifiers.
allowsNonTrivialObjCLifetimeQualifiers()423   bool allowsNonTrivialObjCLifetimeQualifiers() const {
424     return ObjCAutoRefCount || ObjCWeak;
425   }
426 
assumeFunctionsAreConvergent()427   bool assumeFunctionsAreConvergent() const {
428     return ConvergentFunctions;
429   }
430 
431   /// Return the OpenCL C or C++ version as a VersionTuple.
432   VersionTuple getOpenCLVersionTuple() const;
433 
434   /// Return the OpenCL version that kernel language is compatible with
435   unsigned getOpenCLCompatibleVersion() const;
436 
437   /// Return the OpenCL C or C++ for OpenCL language name and version
438   /// as a string.
439   std::string getOpenCLVersionString() const;
440 
441   /// Check if return address signing is enabled.
hasSignReturnAddress()442   bool hasSignReturnAddress() const {
443     return getSignReturnAddressScope() != SignReturnAddressScopeKind::None;
444   }
445 
446   /// Check if return address signing uses AKey.
isSignReturnAddressWithAKey()447   bool isSignReturnAddressWithAKey() const {
448     return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey;
449   }
450 
451   /// Check if leaf functions are also signed.
isSignReturnAddressScopeAll()452   bool isSignReturnAddressScopeAll() const {
453     return getSignReturnAddressScope() == SignReturnAddressScopeKind::All;
454   }
455 
hasSjLjExceptions()456   bool hasSjLjExceptions() const {
457     return getExceptionHandling() == ExceptionHandlingKind::SjLj;
458   }
459 
hasSEHExceptions()460   bool hasSEHExceptions() const {
461     return getExceptionHandling() == ExceptionHandlingKind::WinEH;
462   }
463 
hasDWARFExceptions()464   bool hasDWARFExceptions() const {
465     return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI;
466   }
467 
hasWasmExceptions()468   bool hasWasmExceptions() const {
469     return getExceptionHandling() == ExceptionHandlingKind::Wasm;
470   }
471 
isSYCL()472   bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; }
473 
474   /// Remap path prefix according to -fmacro-prefix-path option.
475   void remapPathPrefix(SmallString<256> &Path) const;
476 };
477 
478 /// Floating point control options
479 class FPOptionsOverride;
480 class FPOptions {
481 public:
482   // We start by defining the layout.
483   using storage_type = uint16_t;
484 
485   using RoundingMode = llvm::RoundingMode;
486 
487   static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type);
488 
489   // Define a fake option named "First" so that we have a PREVIOUS even for the
490   // real first option.
491   static constexpr storage_type FirstShift = 0, FirstWidth = 0;
492 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
493   static constexpr storage_type NAME##Shift =                                  \
494       PREVIOUS##Shift + PREVIOUS##Width;                                       \
495   static constexpr storage_type NAME##Width = WIDTH;                           \
496   static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1)          \
497                                              << NAME##Shift;
498 #include "clang/Basic/FPOptions.def"
499 
500   static constexpr storage_type TotalWidth = 0
501 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH
502 #include "clang/Basic/FPOptions.def"
503       ;
504   static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions");
505 
506 private:
507   storage_type Value;
508 
509 public:
FPOptions()510   FPOptions() : Value(0) {
511     setFPContractMode(LangOptions::FPM_Off);
512     setRoundingMode(static_cast<RoundingMode>(LangOptions::FPR_ToNearest));
513     setFPExceptionMode(LangOptions::FPE_Ignore);
514   }
FPOptions(const LangOptions & LO)515   explicit FPOptions(const LangOptions &LO) {
516     Value = 0;
517     // The language fp contract option FPM_FastHonorPragmas has the same effect
518     // as FPM_Fast in frontend. For simplicity, use FPM_Fast uniformly in
519     // frontend.
520     auto LangOptContractMode = LO.getDefaultFPContractMode();
521     if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas)
522       LangOptContractMode = LangOptions::FPM_Fast;
523     setFPContractMode(LangOptContractMode);
524     setRoundingMode(LO.getFPRoundingMode());
525     setFPExceptionMode(LO.getFPExceptionMode());
526     setAllowFPReassociate(LO.AllowFPReassoc);
527     setNoHonorNaNs(LO.NoHonorNaNs);
528     setNoHonorInfs(LO.NoHonorInfs);
529     setNoSignedZero(LO.NoSignedZero);
530     setAllowReciprocal(LO.AllowRecip);
531     setAllowApproxFunc(LO.ApproxFunc);
532     if (getFPContractMode() == LangOptions::FPM_On &&
533         getRoundingMode() == llvm::RoundingMode::Dynamic &&
534         getFPExceptionMode() == LangOptions::FPE_Strict)
535       // If the FP settings are set to the "strict" model, then
536       // FENV access is set to true. (ffp-model=strict)
537       setAllowFEnvAccess(true);
538     else
539       setAllowFEnvAccess(LangOptions::FPM_Off);
540   }
541 
allowFPContractWithinStatement()542   bool allowFPContractWithinStatement() const {
543     return getFPContractMode() == LangOptions::FPM_On;
544   }
setAllowFPContractWithinStatement()545   void setAllowFPContractWithinStatement() {
546     setFPContractMode(LangOptions::FPM_On);
547   }
548 
allowFPContractAcrossStatement()549   bool allowFPContractAcrossStatement() const {
550     return getFPContractMode() == LangOptions::FPM_Fast;
551   }
setAllowFPContractAcrossStatement()552   void setAllowFPContractAcrossStatement() {
553     setFPContractMode(LangOptions::FPM_Fast);
554   }
555 
isFPConstrained()556   bool isFPConstrained() const {
557     return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven ||
558            getFPExceptionMode() != LangOptions::FPE_Ignore ||
559            getAllowFEnvAccess();
560   }
561 
562   bool operator==(FPOptions other) const { return Value == other.Value; }
563 
564   /// Return the default value of FPOptions that's used when trailing
565   /// storage isn't required.
566   static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO);
567 
getAsOpaqueInt()568   storage_type getAsOpaqueInt() const { return Value; }
getFromOpaqueInt(storage_type Value)569   static FPOptions getFromOpaqueInt(storage_type Value) {
570     FPOptions Opts;
571     Opts.Value = Value;
572     return Opts;
573   }
574 
575   // We can define most of the accessors automatically:
576 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
577   TYPE get##NAME() const {                                                     \
578     return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift);             \
579   }                                                                            \
580   void set##NAME(TYPE value) {                                                 \
581     Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift);      \
582   }
583 #include "clang/Basic/FPOptions.def"
584   LLVM_DUMP_METHOD void dump();
585 };
586 
587 /// Represents difference between two FPOptions values.
588 ///
589 /// The effect of language constructs changing the set of floating point options
590 /// is usually a change of some FP properties while leaving others intact. This
591 /// class describes such changes by keeping information about what FP options
592 /// are overridden.
593 ///
594 /// The integral set of FP options, described by the class FPOptions, may be
595 /// represented as a default FP option set, defined by language standard and
596 /// command line options, with the overrides introduced by pragmas.
597 ///
598 /// The is implemented as a value of the new FPOptions plus a mask showing which
599 /// fields are actually set in it.
600 class FPOptionsOverride {
601   FPOptions Options = FPOptions::getFromOpaqueInt(0);
602   FPOptions::storage_type OverrideMask = 0;
603 
604 public:
605   using RoundingMode = llvm::RoundingMode;
606 
607   /// The type suitable for storing values of FPOptionsOverride. Must be twice
608   /// as wide as bit size of FPOption.
609   using storage_type = uint32_t;
610   static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type),
611                 "Too short type for FPOptionsOverride");
612 
613   /// Bit mask selecting bits of OverrideMask in serialized representation of
614   /// FPOptionsOverride.
615   static constexpr storage_type OverrideMaskBits =
616       (static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1;
617 
FPOptionsOverride()618   FPOptionsOverride() {}
FPOptionsOverride(const LangOptions & LO)619   FPOptionsOverride(const LangOptions &LO)
620       : Options(LO), OverrideMask(OverrideMaskBits) {}
FPOptionsOverride(FPOptions FPO)621   FPOptionsOverride(FPOptions FPO)
622       : Options(FPO), OverrideMask(OverrideMaskBits) {}
623 
requiresTrailingStorage()624   bool requiresTrailingStorage() const { return OverrideMask != 0; }
625 
setAllowFPContractWithinStatement()626   void setAllowFPContractWithinStatement() {
627     setFPContractModeOverride(LangOptions::FPM_On);
628   }
629 
setAllowFPContractAcrossStatement()630   void setAllowFPContractAcrossStatement() {
631     setFPContractModeOverride(LangOptions::FPM_Fast);
632   }
633 
setDisallowFPContract()634   void setDisallowFPContract() {
635     setFPContractModeOverride(LangOptions::FPM_Off);
636   }
637 
setFPPreciseEnabled(bool Value)638   void setFPPreciseEnabled(bool Value) {
639     setAllowFPReassociateOverride(!Value);
640     setNoHonorNaNsOverride(!Value);
641     setNoHonorInfsOverride(!Value);
642     setNoSignedZeroOverride(!Value);
643     setAllowReciprocalOverride(!Value);
644     setAllowApproxFuncOverride(!Value);
645     if (Value)
646       /* Precise mode implies fp_contract=on and disables ffast-math */
647       setAllowFPContractWithinStatement();
648     else
649       /* Precise mode disabled sets fp_contract=fast and enables ffast-math */
650       setAllowFPContractAcrossStatement();
651   }
652 
getAsOpaqueInt()653   storage_type getAsOpaqueInt() const {
654     return (static_cast<storage_type>(Options.getAsOpaqueInt())
655             << FPOptions::StorageBitSize) |
656            OverrideMask;
657   }
getFromOpaqueInt(storage_type I)658   static FPOptionsOverride getFromOpaqueInt(storage_type I) {
659     FPOptionsOverride Opts;
660     Opts.OverrideMask = I & OverrideMaskBits;
661     Opts.Options = FPOptions::getFromOpaqueInt(I >> FPOptions::StorageBitSize);
662     return Opts;
663   }
664 
applyOverrides(FPOptions Base)665   FPOptions applyOverrides(FPOptions Base) {
666     FPOptions Result =
667         FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) |
668                                      (Options.getAsOpaqueInt() & OverrideMask));
669     return Result;
670   }
671 
applyOverrides(const LangOptions & LO)672   FPOptions applyOverrides(const LangOptions &LO) {
673     return applyOverrides(FPOptions(LO));
674   }
675 
676   bool operator==(FPOptionsOverride other) const {
677     return Options == other.Options && OverrideMask == other.OverrideMask;
678   }
679   bool operator!=(FPOptionsOverride other) const { return !(*this == other); }
680 
681 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
682   bool has##NAME##Override() const {                                           \
683     return OverrideMask & FPOptions::NAME##Mask;                               \
684   }                                                                            \
685   TYPE get##NAME##Override() const {                                           \
686     assert(has##NAME##Override());                                             \
687     return Options.get##NAME();                                                \
688   }                                                                            \
689   void clear##NAME##Override() {                                               \
690     /* Clear the actual value so that we don't have spurious differences when  \
691      * testing equality. */                                                    \
692     Options.set##NAME(TYPE(0));                                                \
693     OverrideMask &= ~FPOptions::NAME##Mask;                                    \
694   }                                                                            \
695   void set##NAME##Override(TYPE value) {                                       \
696     Options.set##NAME(value);                                                  \
697     OverrideMask |= FPOptions::NAME##Mask;                                     \
698   }
699 #include "clang/Basic/FPOptions.def"
700   LLVM_DUMP_METHOD void dump();
701 };
702 
703 /// Describes the kind of translation unit being processed.
704 enum TranslationUnitKind {
705   /// The translation unit is a complete translation unit.
706   TU_Complete,
707 
708   /// The translation unit is a prefix to a translation unit, and is
709   /// not complete.
710   TU_Prefix,
711 
712   /// The translation unit is a module.
713   TU_Module,
714 
715   /// The translation unit is a is a complete translation unit that we might
716   /// incrementally extend later.
717   TU_Incremental
718 };
719 
720 } // namespace clang
721 
722 #endif // LLVM_CLANG_BASIC_LANGOPTIONS_H
723