1 //===- LangOptions.h - C Language Family Language Options -------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// Defines the clang::LangOptions interface.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H
15 #define LLVM_CLANG_BASIC_LANGOPTIONS_H
16 
17 #include "clang/Basic/CommentOptions.h"
18 #include "clang/Basic/LLVM.h"
19 #include "clang/Basic/LangStandard.h"
20 #include "clang/Basic/ObjCRuntime.h"
21 #include "clang/Basic/Sanitizers.h"
22 #include "clang/Basic/TargetCXXABI.h"
23 #include "clang/Basic/Visibility.h"
24 #include "llvm/ADT/FloatingPointMode.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/TargetParser/Triple.h"
27 #include <optional>
28 #include <string>
29 #include <vector>
30 
31 namespace clang {
32 
33 /// Bitfields of LangOptions, split out from LangOptions in order to ensure that
34 /// this large collection of bitfields is a trivial class type.
35 class LangOptionsBase {
36   friend class CompilerInvocation;
37   friend class CompilerInvocationBase;
38 
39 public:
40   // Define simple language options (with no accessors).
41 #define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits;
42 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
43 #include "clang/Basic/LangOptions.def"
44 
45 protected:
46   // Define language options of enumeration type. These are private, and will
47   // have accessors (below).
48 #define LANGOPT(Name, Bits, Default, Description)
49 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
50   unsigned Name : Bits;
51 #include "clang/Basic/LangOptions.def"
52 };
53 
54 /// In the Microsoft ABI, this controls the placement of virtual displacement
55 /// members used to implement virtual inheritance.
56 enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable };
57 
58 /// Shader programs run in specific pipeline stages.
59 /// The order of these values matters, and must be kept in sync with the
60 /// Triple Environment enum in llvm::Triple. The ordering is enforced in
61 ///  static_asserts in Triple.cpp and in clang/Basic/HLSLRuntime.h.
62 enum class ShaderStage {
63   Pixel = 0,
64   Vertex,
65   Geometry,
66   Hull,
67   Domain,
68   Compute,
69   Library,
70   RayGeneration,
71   Intersection,
72   AnyHit,
73   ClosestHit,
74   Miss,
75   Callable,
76   Mesh,
77   Amplification,
78   Invalid,
79 };
80 
81 /// Keeps track of the various options that can be
82 /// enabled, which controls the dialect of C or C++ that is accepted.
83 class LangOptions : public LangOptionsBase {
84 public:
85   using Visibility = clang::Visibility;
86   using RoundingMode = llvm::RoundingMode;
87 
88   enum GCMode { NonGC, GCOnly, HybridGC };
89   enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
90 
91   // Automatic variables live on the stack, and when trivial they're usually
92   // uninitialized because it's undefined behavior to use them without
93   // initializing them.
94   enum class TrivialAutoVarInitKind { Uninitialized, Zero, Pattern };
95 
96   enum SignedOverflowBehaviorTy {
97     // Default C standard behavior.
98     SOB_Undefined,
99 
100     // -fwrapv
101     SOB_Defined,
102 
103     // -ftrapv
104     SOB_Trapping
105   };
106 
107   // FIXME: Unify with TUKind.
108   enum CompilingModuleKind {
109     /// Not compiling a module interface at all.
110     CMK_None,
111 
112     /// Compiling a module from a module map.
113     CMK_ModuleMap,
114 
115     /// Compiling a module header unit.
116     CMK_HeaderUnit,
117 
118     /// Compiling a C++ modules interface unit.
119     CMK_ModuleInterface,
120   };
121 
122   enum PragmaMSPointersToMembersKind {
123     PPTMK_BestCase,
124     PPTMK_FullGeneralitySingleInheritance,
125     PPTMK_FullGeneralityMultipleInheritance,
126     PPTMK_FullGeneralityVirtualInheritance
127   };
128 
129   using MSVtorDispMode = clang::MSVtorDispMode;
130 
131   enum DefaultCallingConvention {
132     DCC_None,
133     DCC_CDecl,
134     DCC_FastCall,
135     DCC_StdCall,
136     DCC_VectorCall,
137     DCC_RegCall,
138     DCC_RtdCall
139   };
140 
141   enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
142 
143   // Corresponds to _MSC_VER
144   enum MSVCMajorVersion {
145     MSVC2010 = 1600,
146     MSVC2012 = 1700,
147     MSVC2013 = 1800,
148     MSVC2015 = 1900,
149     MSVC2017 = 1910,
150     MSVC2017_5 = 1912,
151     MSVC2017_7 = 1914,
152     MSVC2019 = 1920,
153     MSVC2019_5 = 1925,
154     MSVC2019_8 = 1928,
155     MSVC2022_3 = 1933,
156   };
157 
158   enum SYCLMajorVersion {
159     SYCL_None,
160     SYCL_2017,
161     SYCL_2020,
162     // The "default" SYCL version to be used when none is specified on the
163     // frontend command line.
164     SYCL_Default = SYCL_2020
165   };
166 
167   enum HLSLLangStd {
168     HLSL_Unset = 0,
169     HLSL_2015 = 2015,
170     HLSL_2016 = 2016,
171     HLSL_2017 = 2017,
172     HLSL_2018 = 2018,
173     HLSL_2021 = 2021,
174     HLSL_202x = 2029,
175   };
176 
177   /// Clang versions with different platform ABI conformance.
178   enum class ClangABI {
179     /// Attempt to be ABI-compatible with code generated by Clang 3.8.x
180     /// (SVN r257626). This causes <1 x long long> to be passed in an
181     /// integer register instead of an SSE register on x64_64.
182     Ver3_8,
183 
184     /// Attempt to be ABI-compatible with code generated by Clang 4.0.x
185     /// (SVN r291814). This causes move operations to be ignored when
186     /// determining whether a class type can be passed or returned directly.
187     Ver4,
188 
189     /// Attempt to be ABI-compatible with code generated by Clang 6.0.x
190     /// (SVN r321711). This causes determination of whether a type is
191     /// standard-layout to ignore collisions between empty base classes
192     /// and between base classes and member subobjects, which affects
193     /// whether we reuse base class tail padding in some ABIs.
194     Ver6,
195 
196     /// Attempt to be ABI-compatible with code generated by Clang 7.0.x
197     /// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be
198     /// compatible with __alignof (i.e., return the preferred alignment)
199     /// rather than returning the required alignment.
200     Ver7,
201 
202     /// Attempt to be ABI-compatible with code generated by Clang 9.0.x
203     /// (SVN r351319). This causes vectors of __int128 to be passed in memory
204     /// instead of passing in multiple scalar registers on x86_64 on Linux and
205     /// NetBSD.
206     Ver9,
207 
208     /// Attempt to be ABI-compatible with code generated by Clang 11.0.x
209     /// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit
210     /// vector member on the stack instead of using registers, to not properly
211     /// mangle substitutions for template names in some cases, and to mangle
212     /// declaration template arguments without a cast to the parameter type
213     /// even when that can lead to mangling collisions.
214     Ver11,
215 
216     /// Attempt to be ABI-compatible with code generated by Clang 12.0.x
217     /// (git 8e464dd76bef). This causes clang to mangle lambdas within
218     /// global-scope inline variables incorrectly.
219     Ver12,
220 
221     /// Attempt to be ABI-compatible with code generated by Clang 14.0.x.
222     /// This causes clang to:
223     ///   - mangle dependent nested names incorrectly.
224     ///   - make trivial only those defaulted copy constructors with a
225     ///     parameter-type-list equivalent to the parameter-type-list of an
226     ///     implicit declaration.
227     Ver14,
228 
229     /// Attempt to be ABI-compatible with code generated by Clang 15.0.x.
230     /// This causes clang to:
231     ///   - Reverse the implementation for DR692, DR1395 and DR1432.
232     ///   - pack non-POD members of packed structs.
233     ///   - consider classes with defaulted special member functions non-pod.
234     Ver15,
235 
236     /// Attempt to be ABI-compatible with code generated by Clang 17.0.x.
237     /// This causes clang to revert some fixes to its implementation of the
238     /// Itanium name mangling scheme, with the consequence that overloaded
239     /// function templates are mangled the same if they differ only by:
240     ///   - constraints
241     ///   - whether a non-type template parameter has a deduced type
242     ///   - the parameter list of a template template parameter
243     Ver17,
244 
245     /// Conform to the underlying platform's C and C++ ABIs as closely
246     /// as we can.
247     Latest
248   };
249 
250   enum class CoreFoundationABI {
251     /// No interoperability ABI has been specified
252     Unspecified,
253     /// CoreFoundation does not have any language interoperability
254     Standalone,
255     /// Interoperability with the ObjectiveC runtime
256     ObjectiveC,
257     /// Interoperability with the latest known version of the Swift runtime
258     Swift,
259     /// Interoperability with the Swift 5.0 runtime
260     Swift5_0,
261     /// Interoperability with the Swift 4.2 runtime
262     Swift4_2,
263     /// Interoperability with the Swift 4.1 runtime
264     Swift4_1,
265   };
266 
267   enum FPModeKind {
268     // Disable the floating point pragma
269     FPM_Off,
270 
271     // Enable the floating point pragma
272     FPM_On,
273 
274     // Aggressively fuse FP ops (E.g. FMA) disregarding pragmas.
275     FPM_Fast,
276 
277     // Aggressively fuse FP ops and honor pragmas.
278     FPM_FastHonorPragmas
279   };
280 
281   /// Possible floating point exception behavior.
282   enum FPExceptionModeKind {
283     /// Assume that floating-point exceptions are masked.
284     FPE_Ignore,
285     /// Transformations do not cause new exceptions but may hide some.
286     FPE_MayTrap,
287     /// Strictly preserve the floating-point exception semantics.
288     FPE_Strict,
289     /// Used internally to represent initial unspecified value.
290     FPE_Default
291   };
292 
293   /// Possible float expression evaluation method choices.
294   enum FPEvalMethodKind {
295     /// The evaluation method cannot be determined or is inconsistent for this
296     /// target.
297     FEM_Indeterminable = -1,
298     /// Use the declared type for fp arithmetic.
299     FEM_Source = 0,
300     /// Use the type double for fp arithmetic.
301     FEM_Double = 1,
302     /// Use extended type for fp arithmetic.
303     FEM_Extended = 2,
304     /// Used only for FE option processing; this is only used to indicate that
305     /// the user did not specify an explicit evaluation method on the command
306     /// line and so the target should be queried for its default evaluation
307     /// method instead.
308     FEM_UnsetOnCommandLine = 3
309   };
310 
311   enum ExcessPrecisionKind { FPP_Standard, FPP_Fast, FPP_None };
312 
313   /// Possible exception handling behavior.
314   enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm };
315 
316   enum class LaxVectorConversionKind {
317     /// Permit no implicit vector bitcasts.
318     None,
319     /// Permit vector bitcasts between integer vectors with different numbers
320     /// of elements but the same total bit-width.
321     Integer,
322     /// Permit vector bitcasts between all vectors with the same total
323     /// bit-width.
324     All,
325   };
326 
327   enum class AltivecSrcCompatKind {
328     // All vector compares produce scalars except vector pixel and vector bool.
329     // The types vector pixel and vector bool return vector results.
330     Mixed,
331     // All vector compares produce vector results as in GCC.
332     GCC,
333     // All vector compares produce scalars as in XL.
334     XL,
335     // Default clang behaviour.
336     Default = Mixed,
337   };
338 
339   enum class SignReturnAddressScopeKind {
340     /// No signing for any function.
341     None,
342     /// Sign the return address of functions that spill LR.
343     NonLeaf,
344     /// Sign the return address of all functions,
345     All
346   };
347 
348   enum class SignReturnAddressKeyKind {
349     /// Return address signing uses APIA key.
350     AKey,
351     /// Return address signing uses APIB key.
352     BKey
353   };
354 
355   enum class ThreadModelKind {
356     /// POSIX Threads.
357     POSIX,
358     /// Single Threaded Environment.
359     Single
360   };
361 
362   enum class ExtendArgsKind {
363     /// Integer arguments are sign or zero extended to 32/64 bits
364     /// during default argument promotions.
365     ExtendTo32,
366     ExtendTo64
367   };
368 
369   enum class GPUDefaultStreamKind {
370     /// Legacy default stream
371     Legacy,
372     /// Per-thread default stream
373     PerThread,
374   };
375 
376   enum class DefaultVisiblityExportMapping {
377     None,
378     /// map only explicit default visibilities to exported
379     Explicit,
380     /// map all default visibilities to exported
381     All,
382   };
383 
384   enum class VisibilityForcedKinds {
385     /// Force hidden visibility
386     ForceHidden,
387     /// Force protected visibility
388     ForceProtected,
389     /// Force default visibility
390     ForceDefault,
391     /// Don't alter the visibility
392     Source,
393   };
394 
395   enum class VisibilityFromDLLStorageClassKinds {
396     /// Keep the IR-gen assigned visibility.
397     Keep,
398     /// Override the IR-gen assigned visibility with default visibility.
399     Default,
400     /// Override the IR-gen assigned visibility with hidden visibility.
401     Hidden,
402     /// Override the IR-gen assigned visibility with protected visibility.
403     Protected,
404   };
405 
406   enum class StrictFlexArraysLevelKind {
407     /// Any trailing array member is a FAM.
408     Default = 0,
409     /// Any trailing array member of undefined, 0, or 1 size is a FAM.
410     OneZeroOrIncomplete = 1,
411     /// Any trailing array member of undefined or 0 size is a FAM.
412     ZeroOrIncomplete = 2,
413     /// Any trailing array member of undefined size is a FAM.
414     IncompleteOnly = 3,
415   };
416 
417   enum ComplexRangeKind { CX_Full, CX_Limited, CX_Fortran, CX_None };
418 
419 public:
420   /// The used language standard.
421   LangStandard::Kind LangStd;
422 
423   /// Set of enabled sanitizers.
424   SanitizerSet Sanitize;
425   /// Is at least one coverage instrumentation type enabled.
426   bool SanitizeCoverage = false;
427 
428   /// Paths to files specifying which objects
429   /// (files, functions, variables) should not be instrumented.
430   std::vector<std::string> NoSanitizeFiles;
431 
432   /// Paths to the XRay "always instrument" files specifying which
433   /// objects (files, functions, variables) should be imbued with the XRay
434   /// "always instrument" attribute.
435   /// WARNING: This is a deprecated field and will go away in the future.
436   std::vector<std::string> XRayAlwaysInstrumentFiles;
437 
438   /// Paths to the XRay "never instrument" files specifying which
439   /// objects (files, functions, variables) should be imbued with the XRay
440   /// "never instrument" attribute.
441   /// WARNING: This is a deprecated field and will go away in the future.
442   std::vector<std::string> XRayNeverInstrumentFiles;
443 
444   /// Paths to the XRay attribute list files, specifying which objects
445   /// (files, functions, variables) should be imbued with the appropriate XRay
446   /// attribute(s).
447   std::vector<std::string> XRayAttrListFiles;
448 
449   /// Paths to special case list files specifying which entities
450   /// (files, functions) should or should not be instrumented.
451   std::vector<std::string> ProfileListFiles;
452 
453   clang::ObjCRuntime ObjCRuntime;
454 
455   CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified;
456 
457   std::string ObjCConstantStringClass;
458 
459   /// The name of the handler function to be called when -ftrapv is
460   /// specified.
461   ///
462   /// If none is specified, abort (GCC-compatible behaviour).
463   std::string OverflowHandler;
464 
465   /// The module currently being compiled as specified by -fmodule-name.
466   std::string ModuleName;
467 
468   /// The name of the current module, of which the main source file
469   /// is a part. If CompilingModule is set, we are compiling the interface
470   /// of this module, otherwise we are compiling an implementation file of
471   /// it. This starts as ModuleName in case -fmodule-name is provided and
472   /// changes during compilation to reflect the current module.
473   std::string CurrentModule;
474 
475   /// The names of any features to enable in module 'requires' decls
476   /// in addition to the hard-coded list in Module.cpp and the target features.
477   ///
478   /// This list is sorted.
479   std::vector<std::string> ModuleFeatures;
480 
481   /// Options for parsing comments.
482   CommentOptions CommentOpts;
483 
484   /// A list of all -fno-builtin-* function names (e.g., memset).
485   std::vector<std::string> NoBuiltinFuncs;
486 
487   /// A prefix map for __FILE__, __BASE_FILE__ and __builtin_FILE().
488   std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap;
489 
490   /// Triples of the OpenMP targets that the host code codegen should
491   /// take into account in order to generate accurate offloading descriptors.
492   std::vector<llvm::Triple> OMPTargetTriples;
493 
494   /// Name of the IR file that contains the result of the OpenMP target
495   /// host code generation.
496   std::string OMPHostIRFile;
497 
498   /// The user provided compilation unit ID, if non-empty. This is used to
499   /// externalize static variables which is needed to support accessing static
500   /// device variables in host code for single source offloading languages
501   /// like CUDA/HIP.
502   std::string CUID;
503 
504   /// C++ ABI to compile with, if specified by the frontend through -fc++-abi=.
505   /// This overrides the default ABI used by the target.
506   std::optional<TargetCXXABI::Kind> CXXABI;
507 
508   /// Indicates whether the front-end is explicitly told that the
509   /// input is a header file (i.e. -x c-header).
510   bool IsHeaderFile = false;
511 
512   /// The default stream kind used for HIP kernel launching.
513   GPUDefaultStreamKind GPUDefaultStream;
514 
515   /// The seed used by the randomize structure layout feature.
516   std::string RandstructSeed;
517 
518   /// Indicates whether to use target's platform-specific file separator when
519   /// __FILE__ macro is used and when concatenating filename with directory or
520   /// to use build environment environment's platform-specific file separator.
521   ///
522   /// The plaform-specific path separator is the backslash(\) for Windows and
523   /// forward slash (/) elsewhere.
524   bool UseTargetPathSeparator = false;
525 
526   // Indicates whether we should keep all nullptr checks for pointers
527   // received as a result of a standard operator new (-fcheck-new)
528   bool CheckNew = false;
529 
530   // In OpenACC mode, contains a user provided override for the _OPENACC macro.
531   // This exists so that we can override the macro value and test our incomplete
532   // implementation on real-world examples.
533   std::string OpenACCMacroOverride;
534 
535   LangOptions();
536 
537   /// Set language defaults for the given input language and
538   /// language standard in the given LangOptions object.
539   ///
540   /// \param Opts - The LangOptions object to set up.
541   /// \param Lang - The input language.
542   /// \param T - The target triple.
543   /// \param Includes - If the language requires extra headers to be implicitly
544   ///                   included, they will be appended to this list.
545   /// \param LangStd - The input language standard.
546   static void
547   setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T,
548                   std::vector<std::string> &Includes,
549                   LangStandard::Kind LangStd = LangStandard::lang_unspecified);
550 
551   // Define accessors/mutators for language options of enumeration type.
552 #define LANGOPT(Name, Bits, Default, Description)
553 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
554   Type get##Name() const { return static_cast<Type>(Name); } \
555   void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
556 #include "clang/Basic/LangOptions.def"
557 
558   /// Are we compiling a module?
isCompilingModule()559   bool isCompilingModule() const {
560     return getCompilingModule() != CMK_None;
561   }
562 
563   /// Are we compiling a standard c++ module interface?
isCompilingModuleInterface()564   bool isCompilingModuleInterface() const {
565     return getCompilingModule() == CMK_ModuleInterface;
566   }
567 
568   /// Are we compiling a module implementation?
isCompilingModuleImplementation()569   bool isCompilingModuleImplementation() const {
570     return !isCompilingModule() && !ModuleName.empty();
571   }
572 
573   /// Do we need to track the owning module for a local declaration?
trackLocalOwningModule()574   bool trackLocalOwningModule() const {
575     return isCompilingModule() || ModulesLocalVisibility;
576   }
577 
isSignedOverflowDefined()578   bool isSignedOverflowDefined() const {
579     return getSignedOverflowBehavior() == SOB_Defined;
580   }
581 
isSubscriptPointerArithmetic()582   bool isSubscriptPointerArithmetic() const {
583     return ObjCRuntime.isSubscriptPointerArithmetic() &&
584            !ObjCSubscriptingLegacyRuntime;
585   }
586 
isCompatibleWithMSVC(MSVCMajorVersion MajorVersion)587   bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
588     return MSCompatibilityVersion >= MajorVersion * 100000U;
589   }
590 
591   /// Reset all of the options that are not considered when building a
592   /// module.
593   void resetNonModularOptions();
594 
595   /// Is this a libc/libm function that is no longer recognized as a
596   /// builtin because a -fno-builtin-* option has been specified?
597   bool isNoBuiltinFunc(StringRef Name) const;
598 
599   /// True if any ObjC types may have non-trivial lifetime qualifiers.
allowsNonTrivialObjCLifetimeQualifiers()600   bool allowsNonTrivialObjCLifetimeQualifiers() const {
601     return ObjCAutoRefCount || ObjCWeak;
602   }
603 
assumeFunctionsAreConvergent()604   bool assumeFunctionsAreConvergent() const {
605     return ConvergentFunctions;
606   }
607 
608   /// Return the OpenCL C or C++ version as a VersionTuple.
609   VersionTuple getOpenCLVersionTuple() const;
610 
611   /// Return the OpenCL version that kernel language is compatible with
612   unsigned getOpenCLCompatibleVersion() const;
613 
614   /// Return the OpenCL C or C++ for OpenCL language name and version
615   /// as a string.
616   std::string getOpenCLVersionString() const;
617 
618   /// Returns true if functions without prototypes or functions with an
619   /// identifier list (aka K&R C functions) are not allowed.
requiresStrictPrototypes()620   bool requiresStrictPrototypes() const {
621     return CPlusPlus || C23 || DisableKNRFunctions;
622   }
623 
624   /// Returns true if implicit function declarations are allowed in the current
625   /// language mode.
implicitFunctionsAllowed()626   bool implicitFunctionsAllowed() const {
627     return !requiresStrictPrototypes() && !OpenCL;
628   }
629 
630   /// Returns true if the language supports calling the 'atexit' function.
hasAtExit()631   bool hasAtExit() const { return !(OpenMP && OpenMPIsTargetDevice); }
632 
633   /// Returns true if implicit int is part of the language requirements.
isImplicitIntRequired()634   bool isImplicitIntRequired() const { return !CPlusPlus && !C99; }
635 
636   /// Returns true if implicit int is supported at all.
isImplicitIntAllowed()637   bool isImplicitIntAllowed() const { return !CPlusPlus && !C23; }
638 
639   /// Check if return address signing is enabled.
hasSignReturnAddress()640   bool hasSignReturnAddress() const {
641     return getSignReturnAddressScope() != SignReturnAddressScopeKind::None;
642   }
643 
644   /// Check if return address signing uses AKey.
isSignReturnAddressWithAKey()645   bool isSignReturnAddressWithAKey() const {
646     return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey;
647   }
648 
649   /// Check if leaf functions are also signed.
isSignReturnAddressScopeAll()650   bool isSignReturnAddressScopeAll() const {
651     return getSignReturnAddressScope() == SignReturnAddressScopeKind::All;
652   }
653 
hasSjLjExceptions()654   bool hasSjLjExceptions() const {
655     return getExceptionHandling() == ExceptionHandlingKind::SjLj;
656   }
657 
hasSEHExceptions()658   bool hasSEHExceptions() const {
659     return getExceptionHandling() == ExceptionHandlingKind::WinEH;
660   }
661 
hasDWARFExceptions()662   bool hasDWARFExceptions() const {
663     return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI;
664   }
665 
hasWasmExceptions()666   bool hasWasmExceptions() const {
667     return getExceptionHandling() == ExceptionHandlingKind::Wasm;
668   }
669 
isSYCL()670   bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; }
671 
hasDefaultVisibilityExportMapping()672   bool hasDefaultVisibilityExportMapping() const {
673     return getDefaultVisibilityExportMapping() !=
674            DefaultVisiblityExportMapping::None;
675   }
676 
isExplicitDefaultVisibilityExportMapping()677   bool isExplicitDefaultVisibilityExportMapping() const {
678     return getDefaultVisibilityExportMapping() ==
679            DefaultVisiblityExportMapping::Explicit;
680   }
681 
isAllDefaultVisibilityExportMapping()682   bool isAllDefaultVisibilityExportMapping() const {
683     return getDefaultVisibilityExportMapping() ==
684            DefaultVisiblityExportMapping::All;
685   }
686 
hasGlobalAllocationFunctionVisibility()687   bool hasGlobalAllocationFunctionVisibility() const {
688     return getGlobalAllocationFunctionVisibility() !=
689            VisibilityForcedKinds::Source;
690   }
691 
hasDefaultGlobalAllocationFunctionVisibility()692   bool hasDefaultGlobalAllocationFunctionVisibility() const {
693     return getGlobalAllocationFunctionVisibility() ==
694            VisibilityForcedKinds::ForceDefault;
695   }
696 
hasProtectedGlobalAllocationFunctionVisibility()697   bool hasProtectedGlobalAllocationFunctionVisibility() const {
698     return getGlobalAllocationFunctionVisibility() ==
699            VisibilityForcedKinds::ForceProtected;
700   }
701 
hasHiddenGlobalAllocationFunctionVisibility()702   bool hasHiddenGlobalAllocationFunctionVisibility() const {
703     return getGlobalAllocationFunctionVisibility() ==
704            VisibilityForcedKinds::ForceHidden;
705   }
706 
707   /// Remap path prefix according to -fmacro-prefix-path option.
708   void remapPathPrefix(SmallVectorImpl<char> &Path) const;
709 
getDefaultRoundingMode()710   RoundingMode getDefaultRoundingMode() const {
711     return RoundingMath ? RoundingMode::Dynamic
712                         : RoundingMode::NearestTiesToEven;
713   }
714 
getDefaultExceptionMode()715   FPExceptionModeKind getDefaultExceptionMode() const {
716     FPExceptionModeKind EM = getFPExceptionMode();
717     if (EM == FPExceptionModeKind::FPE_Default)
718       return FPExceptionModeKind::FPE_Ignore;
719     return EM;
720   }
721 };
722 
723 /// Floating point control options
724 class FPOptionsOverride;
725 class FPOptions {
726 public:
727   // We start by defining the layout.
728   using storage_type = uint32_t;
729 
730   using RoundingMode = llvm::RoundingMode;
731 
732   static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type);
733 
734   // Define a fake option named "First" so that we have a PREVIOUS even for the
735   // real first option.
736   static constexpr storage_type FirstShift = 0, FirstWidth = 0;
737 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
738   static constexpr storage_type NAME##Shift =                                  \
739       PREVIOUS##Shift + PREVIOUS##Width;                                       \
740   static constexpr storage_type NAME##Width = WIDTH;                           \
741   static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1)          \
742                                              << NAME##Shift;
743 #include "clang/Basic/FPOptions.def"
744 
745   static constexpr storage_type TotalWidth = 0
746 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH
747 #include "clang/Basic/FPOptions.def"
748       ;
749   static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions");
750 
751 private:
752   storage_type Value;
753 
754   FPOptionsOverride getChangesSlow(const FPOptions &Base) const;
755 
756 public:
FPOptions()757   FPOptions() : Value(0) {
758     setFPContractMode(LangOptions::FPM_Off);
759     setConstRoundingMode(RoundingMode::Dynamic);
760     setSpecifiedExceptionMode(LangOptions::FPE_Default);
761   }
FPOptions(const LangOptions & LO)762   explicit FPOptions(const LangOptions &LO) {
763     Value = 0;
764     // The language fp contract option FPM_FastHonorPragmas has the same effect
765     // as FPM_Fast in frontend. For simplicity, use FPM_Fast uniformly in
766     // frontend.
767     auto LangOptContractMode = LO.getDefaultFPContractMode();
768     if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas)
769       LangOptContractMode = LangOptions::FPM_Fast;
770     setFPContractMode(LangOptContractMode);
771     setRoundingMath(LO.RoundingMath);
772     setConstRoundingMode(LangOptions::RoundingMode::Dynamic);
773     setSpecifiedExceptionMode(LO.getFPExceptionMode());
774     setAllowFPReassociate(LO.AllowFPReassoc);
775     setNoHonorNaNs(LO.NoHonorNaNs);
776     setNoHonorInfs(LO.NoHonorInfs);
777     setNoSignedZero(LO.NoSignedZero);
778     setAllowReciprocal(LO.AllowRecip);
779     setAllowApproxFunc(LO.ApproxFunc);
780     if (getFPContractMode() == LangOptions::FPM_On &&
781         getRoundingMode() == llvm::RoundingMode::Dynamic &&
782         getExceptionMode() == LangOptions::FPE_Strict)
783       // If the FP settings are set to the "strict" model, then
784       // FENV access is set to true. (ffp-model=strict)
785       setAllowFEnvAccess(true);
786     else
787       setAllowFEnvAccess(LangOptions::FPM_Off);
788     setComplexRange(LO.getComplexRange());
789   }
790 
allowFPContractWithinStatement()791   bool allowFPContractWithinStatement() const {
792     return getFPContractMode() == LangOptions::FPM_On;
793   }
setAllowFPContractWithinStatement()794   void setAllowFPContractWithinStatement() {
795     setFPContractMode(LangOptions::FPM_On);
796   }
797 
allowFPContractAcrossStatement()798   bool allowFPContractAcrossStatement() const {
799     return getFPContractMode() == LangOptions::FPM_Fast;
800   }
setAllowFPContractAcrossStatement()801   void setAllowFPContractAcrossStatement() {
802     setFPContractMode(LangOptions::FPM_Fast);
803   }
804 
isFPConstrained()805   bool isFPConstrained() const {
806     return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven ||
807            getExceptionMode() != LangOptions::FPE_Ignore ||
808            getAllowFEnvAccess();
809   }
810 
getRoundingMode()811   RoundingMode getRoundingMode() const {
812     RoundingMode RM = getConstRoundingMode();
813     if (RM == RoundingMode::Dynamic) {
814       // C23: 7.6.2p3  If the FE_DYNAMIC mode is specified and FENV_ACCESS is
815       // "off", the translator may assume that the default rounding mode is in
816       // effect.
817       if (!getAllowFEnvAccess() && !getRoundingMath())
818         RM = RoundingMode::NearestTiesToEven;
819     }
820     return RM;
821   }
822 
getExceptionMode()823   LangOptions::FPExceptionModeKind getExceptionMode() const {
824     LangOptions::FPExceptionModeKind EM = getSpecifiedExceptionMode();
825     if (EM == LangOptions::FPExceptionModeKind::FPE_Default) {
826       if (getAllowFEnvAccess())
827         return LangOptions::FPExceptionModeKind::FPE_Strict;
828       else
829         return LangOptions::FPExceptionModeKind::FPE_Ignore;
830     }
831     return EM;
832   }
833 
834   bool operator==(FPOptions other) const { return Value == other.Value; }
835 
836   /// Return the default value of FPOptions that's used when trailing
837   /// storage isn't required.
838   static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO);
839 
getAsOpaqueInt()840   storage_type getAsOpaqueInt() const { return Value; }
getFromOpaqueInt(storage_type Value)841   static FPOptions getFromOpaqueInt(storage_type Value) {
842     FPOptions Opts;
843     Opts.Value = Value;
844     return Opts;
845   }
846 
847   /// Return difference with the given option set.
848   FPOptionsOverride getChangesFrom(const FPOptions &Base) const;
849 
850   // We can define most of the accessors automatically:
851 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
852   TYPE get##NAME() const {                                                     \
853     return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift);             \
854   }                                                                            \
855   void set##NAME(TYPE value) {                                                 \
856     Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift);      \
857   }
858 #include "clang/Basic/FPOptions.def"
859   LLVM_DUMP_METHOD void dump();
860 };
861 
862 /// Represents difference between two FPOptions values.
863 ///
864 /// The effect of language constructs changing the set of floating point options
865 /// is usually a change of some FP properties while leaving others intact. This
866 /// class describes such changes by keeping information about what FP options
867 /// are overridden.
868 ///
869 /// The integral set of FP options, described by the class FPOptions, may be
870 /// represented as a default FP option set, defined by language standard and
871 /// command line options, with the overrides introduced by pragmas.
872 ///
873 /// The is implemented as a value of the new FPOptions plus a mask showing which
874 /// fields are actually set in it.
875 class FPOptionsOverride {
876   FPOptions Options = FPOptions::getFromOpaqueInt(0);
877   FPOptions::storage_type OverrideMask = 0;
878 
879 public:
880   using RoundingMode = llvm::RoundingMode;
881 
882   /// The type suitable for storing values of FPOptionsOverride. Must be twice
883   /// as wide as bit size of FPOption.
884   using storage_type = uint64_t;
885   static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type),
886                 "Too short type for FPOptionsOverride");
887 
888   /// Bit mask selecting bits of OverrideMask in serialized representation of
889   /// FPOptionsOverride.
890   static constexpr storage_type OverrideMaskBits =
891       (static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1;
892 
FPOptionsOverride()893   FPOptionsOverride() {}
FPOptionsOverride(const LangOptions & LO)894   FPOptionsOverride(const LangOptions &LO)
895       : Options(LO), OverrideMask(OverrideMaskBits) {}
FPOptionsOverride(FPOptions FPO)896   FPOptionsOverride(FPOptions FPO)
897       : Options(FPO), OverrideMask(OverrideMaskBits) {}
FPOptionsOverride(FPOptions FPO,FPOptions::storage_type Mask)898   FPOptionsOverride(FPOptions FPO, FPOptions::storage_type Mask)
899       : Options(FPO), OverrideMask(Mask) {}
900 
requiresTrailingStorage()901   bool requiresTrailingStorage() const { return OverrideMask != 0; }
902 
setAllowFPContractWithinStatement()903   void setAllowFPContractWithinStatement() {
904     setFPContractModeOverride(LangOptions::FPM_On);
905   }
906 
setAllowFPContractAcrossStatement()907   void setAllowFPContractAcrossStatement() {
908     setFPContractModeOverride(LangOptions::FPM_Fast);
909   }
910 
setDisallowFPContract()911   void setDisallowFPContract() {
912     setFPContractModeOverride(LangOptions::FPM_Off);
913   }
914 
setFPPreciseEnabled(bool Value)915   void setFPPreciseEnabled(bool Value) {
916     setAllowFPReassociateOverride(!Value);
917     setNoHonorNaNsOverride(!Value);
918     setNoHonorInfsOverride(!Value);
919     setNoSignedZeroOverride(!Value);
920     setAllowReciprocalOverride(!Value);
921     setAllowApproxFuncOverride(!Value);
922     setMathErrnoOverride(Value);
923     if (Value)
924       /* Precise mode implies fp_contract=on and disables ffast-math */
925       setAllowFPContractWithinStatement();
926     else
927       /* Precise mode disabled sets fp_contract=fast and enables ffast-math */
928       setAllowFPContractAcrossStatement();
929   }
930 
getAsOpaqueInt()931   storage_type getAsOpaqueInt() const {
932     return (static_cast<storage_type>(Options.getAsOpaqueInt())
933             << FPOptions::StorageBitSize) |
934            OverrideMask;
935   }
getFromOpaqueInt(storage_type I)936   static FPOptionsOverride getFromOpaqueInt(storage_type I) {
937     FPOptionsOverride Opts;
938     Opts.OverrideMask = I & OverrideMaskBits;
939     Opts.Options = FPOptions::getFromOpaqueInt(I >> FPOptions::StorageBitSize);
940     return Opts;
941   }
942 
applyOverrides(FPOptions Base)943   FPOptions applyOverrides(FPOptions Base) {
944     FPOptions Result =
945         FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) |
946                                      (Options.getAsOpaqueInt() & OverrideMask));
947     return Result;
948   }
949 
applyOverrides(const LangOptions & LO)950   FPOptions applyOverrides(const LangOptions &LO) {
951     return applyOverrides(FPOptions(LO));
952   }
953 
954   bool operator==(FPOptionsOverride other) const {
955     return Options == other.Options && OverrideMask == other.OverrideMask;
956   }
957   bool operator!=(FPOptionsOverride other) const { return !(*this == other); }
958 
959 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
960   bool has##NAME##Override() const {                                           \
961     return OverrideMask & FPOptions::NAME##Mask;                               \
962   }                                                                            \
963   TYPE get##NAME##Override() const {                                           \
964     assert(has##NAME##Override());                                             \
965     return Options.get##NAME();                                                \
966   }                                                                            \
967   void clear##NAME##Override() {                                               \
968     /* Clear the actual value so that we don't have spurious differences when  \
969      * testing equality. */                                                    \
970     Options.set##NAME(TYPE(0));                                                \
971     OverrideMask &= ~FPOptions::NAME##Mask;                                    \
972   }                                                                            \
973   void set##NAME##Override(TYPE value) {                                       \
974     Options.set##NAME(value);                                                  \
975     OverrideMask |= FPOptions::NAME##Mask;                                     \
976   }
977 #include "clang/Basic/FPOptions.def"
978   LLVM_DUMP_METHOD void dump();
979 };
980 
getChangesFrom(const FPOptions & Base)981 inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const {
982   if (Value == Base.Value)
983     return FPOptionsOverride();
984   return getChangesSlow(Base);
985 }
986 
987 /// Describes the kind of translation unit being processed.
988 enum TranslationUnitKind {
989   /// The translation unit is a complete translation unit.
990   TU_Complete,
991 
992   /// The translation unit is a prefix to a translation unit, and is
993   /// not complete.
994   TU_Prefix,
995 
996   /// The translation unit is a module.
997   TU_Module,
998 
999   /// The translation unit is a is a complete translation unit that we might
1000   /// incrementally extend later.
1001   TU_Incremental
1002 };
1003 
1004 } // namespace clang
1005 
1006 #endif // LLVM_CLANG_BASIC_LANGOPTIONS_H
1007