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