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