clang 20.0.0 (based on r547379) from build 12806354. Bug: http://b/379133546 Test: N/A Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
1085 lines
37 KiB
C++
1085 lines
37 KiB
C++
//===- LangOptions.h - C Language Family Language Options -------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
/// \file
|
|
/// Defines the clang::LangOptions interface.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H
|
|
#define LLVM_CLANG_BASIC_LANGOPTIONS_H
|
|
|
|
#include "clang/Basic/CommentOptions.h"
|
|
#include "clang/Basic/LLVM.h"
|
|
#include "clang/Basic/LangStandard.h"
|
|
#include "clang/Basic/ObjCRuntime.h"
|
|
#include "clang/Basic/Sanitizers.h"
|
|
#include "clang/Basic/TargetCXXABI.h"
|
|
#include "clang/Basic/Visibility.h"
|
|
#include "llvm/ADT/FloatingPointMode.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/TargetParser/Triple.h"
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace clang {
|
|
|
|
/// In the Microsoft ABI, this controls the placement of virtual displacement
|
|
/// members used to implement virtual inheritance.
|
|
enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable };
|
|
|
|
/// Shader programs run in specific pipeline stages.
|
|
/// The order of these values matters, and must be kept in sync with the
|
|
/// Triple Environment enum in llvm::Triple. The ordering is enforced in
|
|
/// static_asserts in Triple.cpp and in clang/Basic/HLSLRuntime.h.
|
|
enum class ShaderStage {
|
|
Pixel = 0,
|
|
Vertex,
|
|
Geometry,
|
|
Hull,
|
|
Domain,
|
|
Compute,
|
|
Library,
|
|
RayGeneration,
|
|
Intersection,
|
|
AnyHit,
|
|
ClosestHit,
|
|
Miss,
|
|
Callable,
|
|
Mesh,
|
|
Amplification,
|
|
Invalid,
|
|
};
|
|
|
|
enum class PointerAuthenticationMode : unsigned {
|
|
None,
|
|
Strip,
|
|
SignAndStrip,
|
|
SignAndAuth
|
|
};
|
|
|
|
/// Bitfields of LangOptions, split out from LangOptions in order to ensure that
|
|
/// this large collection of bitfields is a trivial class type.
|
|
class LangOptionsBase {
|
|
friend class CompilerInvocation;
|
|
friend class CompilerInvocationBase;
|
|
|
|
public:
|
|
using Visibility = clang::Visibility;
|
|
using RoundingMode = llvm::RoundingMode;
|
|
|
|
enum GCMode { NonGC, GCOnly, HybridGC };
|
|
enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
|
|
|
|
// Automatic variables live on the stack, and when trivial they're usually
|
|
// uninitialized because it's undefined behavior to use them without
|
|
// initializing them.
|
|
enum class TrivialAutoVarInitKind { Uninitialized, Zero, Pattern };
|
|
|
|
enum SignedOverflowBehaviorTy {
|
|
// Default C standard behavior.
|
|
SOB_Undefined,
|
|
|
|
// -fwrapv
|
|
SOB_Defined,
|
|
|
|
// -ftrapv
|
|
SOB_Trapping
|
|
};
|
|
|
|
// FIXME: Unify with TUKind.
|
|
enum CompilingModuleKind {
|
|
/// Not compiling a module interface at all.
|
|
CMK_None,
|
|
|
|
/// Compiling a module from a module map.
|
|
CMK_ModuleMap,
|
|
|
|
/// Compiling a module header unit.
|
|
CMK_HeaderUnit,
|
|
|
|
/// Compiling a C++ modules interface unit.
|
|
CMK_ModuleInterface,
|
|
};
|
|
|
|
enum PragmaMSPointersToMembersKind {
|
|
PPTMK_BestCase,
|
|
PPTMK_FullGeneralitySingleInheritance,
|
|
PPTMK_FullGeneralityMultipleInheritance,
|
|
PPTMK_FullGeneralityVirtualInheritance
|
|
};
|
|
|
|
using MSVtorDispMode = clang::MSVtorDispMode;
|
|
|
|
enum DefaultCallingConvention {
|
|
DCC_None,
|
|
DCC_CDecl,
|
|
DCC_FastCall,
|
|
DCC_StdCall,
|
|
DCC_VectorCall,
|
|
DCC_RegCall,
|
|
DCC_RtdCall
|
|
};
|
|
|
|
enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
|
|
|
|
// Corresponds to _MSC_VER
|
|
enum MSVCMajorVersion {
|
|
MSVC2010 = 1600,
|
|
MSVC2012 = 1700,
|
|
MSVC2013 = 1800,
|
|
MSVC2015 = 1900,
|
|
MSVC2017 = 1910,
|
|
MSVC2017_5 = 1912,
|
|
MSVC2017_7 = 1914,
|
|
MSVC2019 = 1920,
|
|
MSVC2019_5 = 1925,
|
|
MSVC2019_8 = 1928,
|
|
MSVC2022_3 = 1933,
|
|
};
|
|
|
|
enum SYCLMajorVersion {
|
|
SYCL_None,
|
|
SYCL_2017,
|
|
SYCL_2020,
|
|
// The "default" SYCL version to be used when none is specified on the
|
|
// frontend command line.
|
|
SYCL_Default = SYCL_2020
|
|
};
|
|
|
|
enum HLSLLangStd {
|
|
HLSL_Unset = 0,
|
|
HLSL_2015 = 2015,
|
|
HLSL_2016 = 2016,
|
|
HLSL_2017 = 2017,
|
|
HLSL_2018 = 2018,
|
|
HLSL_2021 = 2021,
|
|
HLSL_202x = 2029,
|
|
};
|
|
|
|
/// Clang versions with different platform ABI conformance.
|
|
enum class ClangABI {
|
|
/// Attempt to be ABI-compatible with code generated by Clang 3.8.x
|
|
/// (SVN r257626). This causes <1 x long long> to be passed in an
|
|
/// integer register instead of an SSE register on x64_64.
|
|
Ver3_8,
|
|
|
|
/// Attempt to be ABI-compatible with code generated by Clang 4.0.x
|
|
/// (SVN r291814). This causes move operations to be ignored when
|
|
/// determining whether a class type can be passed or returned directly.
|
|
Ver4,
|
|
|
|
/// Attempt to be ABI-compatible with code generated by Clang 6.0.x
|
|
/// (SVN r321711). This causes determination of whether a type is
|
|
/// standard-layout to ignore collisions between empty base classes
|
|
/// and between base classes and member subobjects, which affects
|
|
/// whether we reuse base class tail padding in some ABIs.
|
|
Ver6,
|
|
|
|
/// Attempt to be ABI-compatible with code generated by Clang 7.0.x
|
|
/// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be
|
|
/// compatible with __alignof (i.e., return the preferred alignment)
|
|
/// rather than returning the required alignment.
|
|
Ver7,
|
|
|
|
/// Attempt to be ABI-compatible with code generated by Clang 9.0.x
|
|
/// (SVN r351319). This causes vectors of __int128 to be passed in memory
|
|
/// instead of passing in multiple scalar registers on x86_64 on Linux and
|
|
/// NetBSD.
|
|
Ver9,
|
|
|
|
/// Attempt to be ABI-compatible with code generated by Clang 11.0.x
|
|
/// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit
|
|
/// vector member on the stack instead of using registers, to not properly
|
|
/// mangle substitutions for template names in some cases, and to mangle
|
|
/// declaration template arguments without a cast to the parameter type
|
|
/// even when that can lead to mangling collisions.
|
|
Ver11,
|
|
|
|
/// Attempt to be ABI-compatible with code generated by Clang 12.0.x
|
|
/// (git 8e464dd76bef). This causes clang to mangle lambdas within
|
|
/// global-scope inline variables incorrectly.
|
|
Ver12,
|
|
|
|
/// Attempt to be ABI-compatible with code generated by Clang 14.0.x.
|
|
/// This causes clang to:
|
|
/// - mangle dependent nested names incorrectly.
|
|
/// - make trivial only those defaulted copy constructors with a
|
|
/// parameter-type-list equivalent to the parameter-type-list of an
|
|
/// implicit declaration.
|
|
Ver14,
|
|
|
|
/// Attempt to be ABI-compatible with code generated by Clang 15.0.x.
|
|
/// This causes clang to:
|
|
/// - Reverse the implementation for DR692, DR1395 and DR1432.
|
|
/// - pack non-POD members of packed structs.
|
|
/// - consider classes with defaulted special member functions non-pod.
|
|
Ver15,
|
|
|
|
/// Attempt to be ABI-compatible with code generated by Clang 17.0.x.
|
|
/// This causes clang to revert some fixes to its implementation of the
|
|
/// Itanium name mangling scheme, with the consequence that overloaded
|
|
/// function templates are mangled the same if they differ only by:
|
|
/// - constraints
|
|
/// - whether a non-type template parameter has a deduced type
|
|
/// - the parameter list of a template template parameter
|
|
Ver17,
|
|
|
|
/// Attempt to be ABI-compatible with code generated by Clang 18.0.x.
|
|
/// This causes clang to revert some fixes to the mangling of lambdas
|
|
/// in the initializers of members of local classes.
|
|
Ver18,
|
|
|
|
/// Conform to the underlying platform's C and C++ ABIs as closely
|
|
/// as we can.
|
|
Latest
|
|
};
|
|
|
|
enum class CoreFoundationABI {
|
|
/// No interoperability ABI has been specified
|
|
Unspecified,
|
|
/// CoreFoundation does not have any language interoperability
|
|
Standalone,
|
|
/// Interoperability with the ObjectiveC runtime
|
|
ObjectiveC,
|
|
/// Interoperability with the latest known version of the Swift runtime
|
|
Swift,
|
|
/// Interoperability with the Swift 5.0 runtime
|
|
Swift5_0,
|
|
/// Interoperability with the Swift 4.2 runtime
|
|
Swift4_2,
|
|
/// Interoperability with the Swift 4.1 runtime
|
|
Swift4_1,
|
|
};
|
|
|
|
enum FPModeKind {
|
|
// Disable the floating point pragma
|
|
FPM_Off,
|
|
|
|
// Enable the floating point pragma
|
|
FPM_On,
|
|
|
|
// Aggressively fuse FP ops (E.g. FMA) disregarding pragmas.
|
|
FPM_Fast,
|
|
|
|
// Aggressively fuse FP ops and honor pragmas.
|
|
FPM_FastHonorPragmas
|
|
};
|
|
|
|
/// Possible floating point exception behavior.
|
|
enum FPExceptionModeKind {
|
|
/// Assume that floating-point exceptions are masked.
|
|
FPE_Ignore,
|
|
/// Transformations do not cause new exceptions but may hide some.
|
|
FPE_MayTrap,
|
|
/// Strictly preserve the floating-point exception semantics.
|
|
FPE_Strict,
|
|
/// Used internally to represent initial unspecified value.
|
|
FPE_Default
|
|
};
|
|
|
|
/// Possible float expression evaluation method choices.
|
|
enum FPEvalMethodKind {
|
|
/// The evaluation method cannot be determined or is inconsistent for this
|
|
/// target.
|
|
FEM_Indeterminable = -1,
|
|
/// Use the declared type for fp arithmetic.
|
|
FEM_Source = 0,
|
|
/// Use the type double for fp arithmetic.
|
|
FEM_Double = 1,
|
|
/// Use extended type for fp arithmetic.
|
|
FEM_Extended = 2,
|
|
/// Used only for FE option processing; this is only used to indicate that
|
|
/// the user did not specify an explicit evaluation method on the command
|
|
/// line and so the target should be queried for its default evaluation
|
|
/// method instead.
|
|
FEM_UnsetOnCommandLine = 3
|
|
};
|
|
|
|
enum ExcessPrecisionKind { FPP_Standard, FPP_Fast, FPP_None };
|
|
|
|
/// Possible exception handling behavior.
|
|
enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm };
|
|
|
|
enum class LaxVectorConversionKind {
|
|
/// Permit no implicit vector bitcasts.
|
|
None,
|
|
/// Permit vector bitcasts between integer vectors with different numbers
|
|
/// of elements but the same total bit-width.
|
|
Integer,
|
|
/// Permit vector bitcasts between all vectors with the same total
|
|
/// bit-width.
|
|
All,
|
|
};
|
|
|
|
enum class AltivecSrcCompatKind {
|
|
// All vector compares produce scalars except vector pixel and vector bool.
|
|
// The types vector pixel and vector bool return vector results.
|
|
Mixed,
|
|
// All vector compares produce vector results as in GCC.
|
|
GCC,
|
|
// All vector compares produce scalars as in XL.
|
|
XL,
|
|
// Default clang behaviour.
|
|
Default = Mixed,
|
|
};
|
|
|
|
enum class SignReturnAddressScopeKind {
|
|
/// No signing for any function.
|
|
None,
|
|
/// Sign the return address of functions that spill LR.
|
|
NonLeaf,
|
|
/// Sign the return address of all functions,
|
|
All
|
|
};
|
|
|
|
enum class SignReturnAddressKeyKind {
|
|
/// Return address signing uses APIA key.
|
|
AKey,
|
|
/// Return address signing uses APIB key.
|
|
BKey
|
|
};
|
|
|
|
enum class ThreadModelKind {
|
|
/// POSIX Threads.
|
|
POSIX,
|
|
/// Single Threaded Environment.
|
|
Single
|
|
};
|
|
|
|
enum class ExtendArgsKind {
|
|
/// Integer arguments are sign or zero extended to 32/64 bits
|
|
/// during default argument promotions.
|
|
ExtendTo32,
|
|
ExtendTo64
|
|
};
|
|
|
|
enum class GPUDefaultStreamKind {
|
|
/// Legacy default stream
|
|
Legacy,
|
|
/// Per-thread default stream
|
|
PerThread,
|
|
};
|
|
|
|
/// Exclude certain code patterns from being instrumented by arithmetic
|
|
/// overflow sanitizers
|
|
enum OverflowPatternExclusionKind {
|
|
/// Don't exclude any overflow patterns from sanitizers
|
|
None = 1 << 0,
|
|
/// Exclude all overflow patterns (below)
|
|
All = 1 << 1,
|
|
/// if (a + b < a)
|
|
AddOverflowTest = 1 << 2,
|
|
/// -1UL
|
|
NegUnsignedConst = 1 << 3,
|
|
/// while (count--)
|
|
PostDecrInWhile = 1 << 4,
|
|
};
|
|
|
|
enum class DefaultVisiblityExportMapping {
|
|
None,
|
|
/// map only explicit default visibilities to exported
|
|
Explicit,
|
|
/// map all default visibilities to exported
|
|
All,
|
|
};
|
|
|
|
enum class VisibilityForcedKinds {
|
|
/// Force hidden visibility
|
|
ForceHidden,
|
|
/// Force protected visibility
|
|
ForceProtected,
|
|
/// Force default visibility
|
|
ForceDefault,
|
|
/// Don't alter the visibility
|
|
Source,
|
|
};
|
|
|
|
enum class VisibilityFromDLLStorageClassKinds {
|
|
/// Keep the IR-gen assigned visibility.
|
|
Keep,
|
|
/// Override the IR-gen assigned visibility with default visibility.
|
|
Default,
|
|
/// Override the IR-gen assigned visibility with hidden visibility.
|
|
Hidden,
|
|
/// Override the IR-gen assigned visibility with protected visibility.
|
|
Protected,
|
|
};
|
|
|
|
enum class StrictFlexArraysLevelKind {
|
|
/// Any trailing array member is a FAM.
|
|
Default = 0,
|
|
/// Any trailing array member of undefined, 0, or 1 size is a FAM.
|
|
OneZeroOrIncomplete = 1,
|
|
/// Any trailing array member of undefined or 0 size is a FAM.
|
|
ZeroOrIncomplete = 2,
|
|
/// Any trailing array member of undefined size is a FAM.
|
|
IncompleteOnly = 3,
|
|
};
|
|
|
|
/// Controls the various implementations for complex multiplication and
|
|
// division.
|
|
enum ComplexRangeKind {
|
|
/// Implementation of complex division and multiplication using a call to
|
|
/// runtime library functions(generally the case, but the BE might
|
|
/// sometimes replace the library call if it knows enough about the
|
|
/// potential range of the inputs). Overflow and non-finite values are
|
|
/// handled by the library implementation. This is the default value.
|
|
CX_Full,
|
|
|
|
/// Implementation of complex division offering an improved handling
|
|
/// for overflow in intermediate calculations with no special handling for
|
|
/// NaN and infinite values.
|
|
CX_Improved,
|
|
|
|
/// Implementation of complex division using algebraic formulas at
|
|
/// higher precision. Overflow is handled. Non-finite values are handled in
|
|
/// some cases. If the target hardware does not have native support for a
|
|
/// higher precision data type, an implementation for the complex operation
|
|
/// will be used to provide improved guards against intermediate overflow,
|
|
/// but overflow and underflow may still occur in some cases. NaN and
|
|
/// infinite values are not handled.
|
|
CX_Promoted,
|
|
|
|
/// Implementation of complex division and multiplication using
|
|
/// algebraic formulas at source precision. No special handling to avoid
|
|
/// overflow. NaN and infinite values are not handled.
|
|
CX_Basic,
|
|
|
|
/// No range rule is enabled.
|
|
CX_None
|
|
};
|
|
|
|
// Define simple language options (with no accessors).
|
|
#define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits;
|
|
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
|
|
#include "clang/Basic/LangOptions.def"
|
|
|
|
protected:
|
|
// Define language options of enumeration type. These are private, and will
|
|
// have accessors (below).
|
|
#define LANGOPT(Name, Bits, Default, Description)
|
|
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
|
|
LLVM_PREFERRED_TYPE(Type) \
|
|
unsigned Name : Bits;
|
|
#include "clang/Basic/LangOptions.def"
|
|
};
|
|
|
|
/// Keeps track of the various options that can be
|
|
/// enabled, which controls the dialect of C or C++ that is accepted.
|
|
class LangOptions : public LangOptionsBase {
|
|
public:
|
|
/// The used language standard.
|
|
LangStandard::Kind LangStd;
|
|
|
|
/// Set of enabled sanitizers.
|
|
SanitizerSet Sanitize;
|
|
/// Is at least one coverage instrumentation type enabled.
|
|
bool SanitizeCoverage = false;
|
|
|
|
/// Paths to files specifying which objects
|
|
/// (files, functions, variables) should not be instrumented.
|
|
std::vector<std::string> NoSanitizeFiles;
|
|
|
|
/// Paths to the XRay "always instrument" files specifying which
|
|
/// objects (files, functions, variables) should be imbued with the XRay
|
|
/// "always instrument" attribute.
|
|
/// WARNING: This is a deprecated field and will go away in the future.
|
|
std::vector<std::string> XRayAlwaysInstrumentFiles;
|
|
|
|
/// Paths to the XRay "never instrument" files specifying which
|
|
/// objects (files, functions, variables) should be imbued with the XRay
|
|
/// "never instrument" attribute.
|
|
/// WARNING: This is a deprecated field and will go away in the future.
|
|
std::vector<std::string> XRayNeverInstrumentFiles;
|
|
|
|
/// Paths to the XRay attribute list files, specifying which objects
|
|
/// (files, functions, variables) should be imbued with the appropriate XRay
|
|
/// attribute(s).
|
|
std::vector<std::string> XRayAttrListFiles;
|
|
|
|
/// Paths to special case list files specifying which entities
|
|
/// (files, functions) should or should not be instrumented.
|
|
std::vector<std::string> ProfileListFiles;
|
|
|
|
clang::ObjCRuntime ObjCRuntime;
|
|
|
|
CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified;
|
|
|
|
std::string ObjCConstantStringClass;
|
|
|
|
/// The name of the handler function to be called when -ftrapv is
|
|
/// specified.
|
|
///
|
|
/// If none is specified, abort (GCC-compatible behaviour).
|
|
std::string OverflowHandler;
|
|
|
|
/// The module currently being compiled as specified by -fmodule-name.
|
|
std::string ModuleName;
|
|
|
|
/// The name of the current module, of which the main source file
|
|
/// is a part. If CompilingModule is set, we are compiling the interface
|
|
/// of this module, otherwise we are compiling an implementation file of
|
|
/// it. This starts as ModuleName in case -fmodule-name is provided and
|
|
/// changes during compilation to reflect the current module.
|
|
std::string CurrentModule;
|
|
|
|
/// The names of any features to enable in module 'requires' decls
|
|
/// in addition to the hard-coded list in Module.cpp and the target features.
|
|
///
|
|
/// This list is sorted.
|
|
std::vector<std::string> ModuleFeatures;
|
|
|
|
/// Options for parsing comments.
|
|
CommentOptions CommentOpts;
|
|
|
|
/// A list of all -fno-builtin-* function names (e.g., memset).
|
|
std::vector<std::string> NoBuiltinFuncs;
|
|
|
|
/// A prefix map for __FILE__, __BASE_FILE__ and __builtin_FILE().
|
|
std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap;
|
|
|
|
/// Triples of the OpenMP targets that the host code codegen should
|
|
/// take into account in order to generate accurate offloading descriptors.
|
|
std::vector<llvm::Triple> OMPTargetTriples;
|
|
|
|
/// Name of the IR file that contains the result of the OpenMP target
|
|
/// host code generation.
|
|
std::string OMPHostIRFile;
|
|
|
|
/// The user provided compilation unit ID, if non-empty. This is used to
|
|
/// externalize static variables which is needed to support accessing static
|
|
/// device variables in host code for single source offloading languages
|
|
/// like CUDA/HIP.
|
|
std::string CUID;
|
|
|
|
/// C++ ABI to compile with, if specified by the frontend through -fc++-abi=.
|
|
/// This overrides the default ABI used by the target.
|
|
std::optional<TargetCXXABI::Kind> CXXABI;
|
|
|
|
/// Indicates whether the front-end is explicitly told that the
|
|
/// input is a header file (i.e. -x c-header).
|
|
bool IsHeaderFile = false;
|
|
|
|
/// The default stream kind used for HIP kernel launching.
|
|
GPUDefaultStreamKind GPUDefaultStream;
|
|
|
|
/// Which overflow patterns should be excluded from sanitizer instrumentation
|
|
unsigned OverflowPatternExclusionMask = 0;
|
|
|
|
std::vector<std::string> OverflowPatternExclusionValues;
|
|
|
|
/// The seed used by the randomize structure layout feature.
|
|
std::string RandstructSeed;
|
|
|
|
/// Indicates whether to use target's platform-specific file separator when
|
|
/// __FILE__ macro is used and when concatenating filename with directory or
|
|
/// to use build environment environment's platform-specific file separator.
|
|
///
|
|
/// The plaform-specific path separator is the backslash(\) for Windows and
|
|
/// forward slash (/) elsewhere.
|
|
bool UseTargetPathSeparator = false;
|
|
|
|
// Indicates whether we should keep all nullptr checks for pointers
|
|
// received as a result of a standard operator new (-fcheck-new)
|
|
bool CheckNew = false;
|
|
|
|
// In OpenACC mode, contains a user provided override for the _OPENACC macro.
|
|
// This exists so that we can override the macro value and test our incomplete
|
|
// implementation on real-world examples.
|
|
std::string OpenACCMacroOverride;
|
|
|
|
// Indicates if the wasm-opt binary must be ignored in the case of a
|
|
// WebAssembly target.
|
|
bool NoWasmOpt = false;
|
|
|
|
LangOptions();
|
|
|
|
/// Set language defaults for the given input language and
|
|
/// language standard in the given LangOptions object.
|
|
///
|
|
/// \param Opts - The LangOptions object to set up.
|
|
/// \param Lang - The input language.
|
|
/// \param T - The target triple.
|
|
/// \param Includes - If the language requires extra headers to be implicitly
|
|
/// included, they will be appended to this list.
|
|
/// \param LangStd - The input language standard.
|
|
static void
|
|
setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T,
|
|
std::vector<std::string> &Includes,
|
|
LangStandard::Kind LangStd = LangStandard::lang_unspecified);
|
|
|
|
// Define accessors/mutators for language options of enumeration type.
|
|
#define LANGOPT(Name, Bits, Default, Description)
|
|
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
|
|
Type get##Name() const { return static_cast<Type>(Name); } \
|
|
void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
|
|
#include "clang/Basic/LangOptions.def"
|
|
|
|
/// Are we compiling a module?
|
|
bool isCompilingModule() const {
|
|
return getCompilingModule() != CMK_None;
|
|
}
|
|
|
|
/// Are we compiling a module implementation?
|
|
bool isCompilingModuleImplementation() const {
|
|
return !isCompilingModule() && !ModuleName.empty();
|
|
}
|
|
|
|
/// Do we need to track the owning module for a local declaration?
|
|
bool trackLocalOwningModule() const {
|
|
return isCompilingModule() || ModulesLocalVisibility;
|
|
}
|
|
|
|
bool isSignedOverflowDefined() const {
|
|
return getSignedOverflowBehavior() == SOB_Defined;
|
|
}
|
|
|
|
bool isSubscriptPointerArithmetic() const {
|
|
return ObjCRuntime.isSubscriptPointerArithmetic() &&
|
|
!ObjCSubscriptingLegacyRuntime;
|
|
}
|
|
|
|
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
|
|
return MSCompatibilityVersion >= MajorVersion * 100000U;
|
|
}
|
|
|
|
bool isOverflowPatternExcluded(OverflowPatternExclusionKind Kind) const {
|
|
if (OverflowPatternExclusionMask & OverflowPatternExclusionKind::None)
|
|
return false;
|
|
if (OverflowPatternExclusionMask & OverflowPatternExclusionKind::All)
|
|
return true;
|
|
return OverflowPatternExclusionMask & Kind;
|
|
}
|
|
|
|
/// Reset all of the options that are not considered when building a
|
|
/// module.
|
|
void resetNonModularOptions();
|
|
|
|
/// Is this a libc/libm function that is no longer recognized as a
|
|
/// builtin because a -fno-builtin-* option has been specified?
|
|
bool isNoBuiltinFunc(StringRef Name) const;
|
|
|
|
/// True if any ObjC types may have non-trivial lifetime qualifiers.
|
|
bool allowsNonTrivialObjCLifetimeQualifiers() const {
|
|
return ObjCAutoRefCount || ObjCWeak;
|
|
}
|
|
|
|
bool assumeFunctionsAreConvergent() const {
|
|
return ConvergentFunctions;
|
|
}
|
|
|
|
/// Return the OpenCL C or C++ version as a VersionTuple.
|
|
VersionTuple getOpenCLVersionTuple() const;
|
|
|
|
/// Return the OpenCL version that kernel language is compatible with
|
|
unsigned getOpenCLCompatibleVersion() const;
|
|
|
|
/// Return the OpenCL C or C++ for OpenCL language name and version
|
|
/// as a string.
|
|
std::string getOpenCLVersionString() const;
|
|
|
|
/// Returns true if functions without prototypes or functions with an
|
|
/// identifier list (aka K&R C functions) are not allowed.
|
|
bool requiresStrictPrototypes() const {
|
|
return CPlusPlus || C23 || DisableKNRFunctions;
|
|
}
|
|
|
|
/// Returns true if implicit function declarations are allowed in the current
|
|
/// language mode.
|
|
bool implicitFunctionsAllowed() const {
|
|
return !requiresStrictPrototypes() && !OpenCL;
|
|
}
|
|
|
|
/// Returns true if the language supports calling the 'atexit' function.
|
|
bool hasAtExit() const { return !(OpenMP && OpenMPIsTargetDevice); }
|
|
|
|
/// Returns true if implicit int is part of the language requirements.
|
|
bool isImplicitIntRequired() const { return !CPlusPlus && !C99; }
|
|
|
|
/// Returns true if implicit int is supported at all.
|
|
bool isImplicitIntAllowed() const { return !CPlusPlus && !C23; }
|
|
|
|
/// Check if return address signing is enabled.
|
|
bool hasSignReturnAddress() const {
|
|
return getSignReturnAddressScope() != SignReturnAddressScopeKind::None;
|
|
}
|
|
|
|
/// Check if return address signing uses AKey.
|
|
bool isSignReturnAddressWithAKey() const {
|
|
return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey;
|
|
}
|
|
|
|
/// Check if leaf functions are also signed.
|
|
bool isSignReturnAddressScopeAll() const {
|
|
return getSignReturnAddressScope() == SignReturnAddressScopeKind::All;
|
|
}
|
|
|
|
bool hasSjLjExceptions() const {
|
|
return getExceptionHandling() == ExceptionHandlingKind::SjLj;
|
|
}
|
|
|
|
bool hasSEHExceptions() const {
|
|
return getExceptionHandling() == ExceptionHandlingKind::WinEH;
|
|
}
|
|
|
|
bool hasDWARFExceptions() const {
|
|
return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI;
|
|
}
|
|
|
|
bool hasWasmExceptions() const {
|
|
return getExceptionHandling() == ExceptionHandlingKind::Wasm;
|
|
}
|
|
|
|
bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; }
|
|
|
|
bool hasDefaultVisibilityExportMapping() const {
|
|
return getDefaultVisibilityExportMapping() !=
|
|
DefaultVisiblityExportMapping::None;
|
|
}
|
|
|
|
bool isExplicitDefaultVisibilityExportMapping() const {
|
|
return getDefaultVisibilityExportMapping() ==
|
|
DefaultVisiblityExportMapping::Explicit;
|
|
}
|
|
|
|
bool isAllDefaultVisibilityExportMapping() const {
|
|
return getDefaultVisibilityExportMapping() ==
|
|
DefaultVisiblityExportMapping::All;
|
|
}
|
|
|
|
bool hasGlobalAllocationFunctionVisibility() const {
|
|
return getGlobalAllocationFunctionVisibility() !=
|
|
VisibilityForcedKinds::Source;
|
|
}
|
|
|
|
bool hasDefaultGlobalAllocationFunctionVisibility() const {
|
|
return getGlobalAllocationFunctionVisibility() ==
|
|
VisibilityForcedKinds::ForceDefault;
|
|
}
|
|
|
|
bool hasProtectedGlobalAllocationFunctionVisibility() const {
|
|
return getGlobalAllocationFunctionVisibility() ==
|
|
VisibilityForcedKinds::ForceProtected;
|
|
}
|
|
|
|
bool hasHiddenGlobalAllocationFunctionVisibility() const {
|
|
return getGlobalAllocationFunctionVisibility() ==
|
|
VisibilityForcedKinds::ForceHidden;
|
|
}
|
|
|
|
/// Remap path prefix according to -fmacro-prefix-path option.
|
|
void remapPathPrefix(SmallVectorImpl<char> &Path) const;
|
|
|
|
RoundingMode getDefaultRoundingMode() const {
|
|
return RoundingMath ? RoundingMode::Dynamic
|
|
: RoundingMode::NearestTiesToEven;
|
|
}
|
|
|
|
FPExceptionModeKind getDefaultExceptionMode() const {
|
|
FPExceptionModeKind EM = getFPExceptionMode();
|
|
if (EM == FPExceptionModeKind::FPE_Default)
|
|
return FPExceptionModeKind::FPE_Ignore;
|
|
return EM;
|
|
}
|
|
};
|
|
|
|
/// Floating point control options
|
|
class FPOptionsOverride;
|
|
class FPOptions {
|
|
public:
|
|
// We start by defining the layout.
|
|
using storage_type = uint32_t;
|
|
|
|
using RoundingMode = llvm::RoundingMode;
|
|
|
|
static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type);
|
|
|
|
// Define a fake option named "First" so that we have a PREVIOUS even for the
|
|
// real first option.
|
|
static constexpr storage_type FirstShift = 0, FirstWidth = 0;
|
|
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
|
|
static constexpr storage_type NAME##Shift = \
|
|
PREVIOUS##Shift + PREVIOUS##Width; \
|
|
static constexpr storage_type NAME##Width = WIDTH; \
|
|
static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1) \
|
|
<< NAME##Shift;
|
|
#include "clang/Basic/FPOptions.def"
|
|
|
|
static constexpr storage_type TotalWidth = 0
|
|
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH
|
|
#include "clang/Basic/FPOptions.def"
|
|
;
|
|
static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions");
|
|
|
|
private:
|
|
storage_type Value;
|
|
|
|
FPOptionsOverride getChangesSlow(const FPOptions &Base) const;
|
|
|
|
public:
|
|
FPOptions() : Value(0) {
|
|
setFPContractMode(LangOptions::FPM_Off);
|
|
setConstRoundingMode(RoundingMode::Dynamic);
|
|
setSpecifiedExceptionMode(LangOptions::FPE_Default);
|
|
}
|
|
explicit FPOptions(const LangOptions &LO) {
|
|
Value = 0;
|
|
// The language fp contract option FPM_FastHonorPragmas has the same effect
|
|
// as FPM_Fast in frontend. For simplicity, use FPM_Fast uniformly in
|
|
// frontend.
|
|
auto LangOptContractMode = LO.getDefaultFPContractMode();
|
|
if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas)
|
|
LangOptContractMode = LangOptions::FPM_Fast;
|
|
setFPContractMode(LangOptContractMode);
|
|
setRoundingMath(LO.RoundingMath);
|
|
setConstRoundingMode(LangOptions::RoundingMode::Dynamic);
|
|
setSpecifiedExceptionMode(LO.getFPExceptionMode());
|
|
setAllowFPReassociate(LO.AllowFPReassoc);
|
|
setNoHonorNaNs(LO.NoHonorNaNs);
|
|
setNoHonorInfs(LO.NoHonorInfs);
|
|
setNoSignedZero(LO.NoSignedZero);
|
|
setAllowReciprocal(LO.AllowRecip);
|
|
setAllowApproxFunc(LO.ApproxFunc);
|
|
if (getFPContractMode() == LangOptions::FPM_On &&
|
|
getRoundingMode() == llvm::RoundingMode::Dynamic &&
|
|
getExceptionMode() == LangOptions::FPE_Strict)
|
|
// If the FP settings are set to the "strict" model, then
|
|
// FENV access is set to true. (ffp-model=strict)
|
|
setAllowFEnvAccess(true);
|
|
else
|
|
setAllowFEnvAccess(LangOptions::FPM_Off);
|
|
setComplexRange(LO.getComplexRange());
|
|
}
|
|
|
|
bool allowFPContractWithinStatement() const {
|
|
return getFPContractMode() == LangOptions::FPM_On;
|
|
}
|
|
void setAllowFPContractWithinStatement() {
|
|
setFPContractMode(LangOptions::FPM_On);
|
|
}
|
|
|
|
bool allowFPContractAcrossStatement() const {
|
|
return getFPContractMode() == LangOptions::FPM_Fast;
|
|
}
|
|
void setAllowFPContractAcrossStatement() {
|
|
setFPContractMode(LangOptions::FPM_Fast);
|
|
}
|
|
|
|
bool isFPConstrained() const {
|
|
return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven ||
|
|
getExceptionMode() != LangOptions::FPE_Ignore ||
|
|
getAllowFEnvAccess();
|
|
}
|
|
|
|
RoundingMode getRoundingMode() const {
|
|
RoundingMode RM = getConstRoundingMode();
|
|
if (RM == RoundingMode::Dynamic) {
|
|
// C23: 7.6.2p3 If the FE_DYNAMIC mode is specified and FENV_ACCESS is
|
|
// "off", the translator may assume that the default rounding mode is in
|
|
// effect.
|
|
if (!getAllowFEnvAccess() && !getRoundingMath())
|
|
RM = RoundingMode::NearestTiesToEven;
|
|
}
|
|
return RM;
|
|
}
|
|
|
|
LangOptions::FPExceptionModeKind getExceptionMode() const {
|
|
LangOptions::FPExceptionModeKind EM = getSpecifiedExceptionMode();
|
|
if (EM == LangOptions::FPExceptionModeKind::FPE_Default) {
|
|
if (getAllowFEnvAccess())
|
|
return LangOptions::FPExceptionModeKind::FPE_Strict;
|
|
else
|
|
return LangOptions::FPExceptionModeKind::FPE_Ignore;
|
|
}
|
|
return EM;
|
|
}
|
|
|
|
bool operator==(FPOptions other) const { return Value == other.Value; }
|
|
|
|
/// Return the default value of FPOptions that's used when trailing
|
|
/// storage isn't required.
|
|
static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO);
|
|
|
|
storage_type getAsOpaqueInt() const { return Value; }
|
|
static FPOptions getFromOpaqueInt(storage_type Value) {
|
|
FPOptions Opts;
|
|
Opts.Value = Value;
|
|
return Opts;
|
|
}
|
|
|
|
/// Return difference with the given option set.
|
|
FPOptionsOverride getChangesFrom(const FPOptions &Base) const;
|
|
|
|
void applyChanges(FPOptionsOverride FPO);
|
|
|
|
// We can define most of the accessors automatically:
|
|
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
|
|
TYPE get##NAME() const { \
|
|
return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift); \
|
|
} \
|
|
void set##NAME(TYPE value) { \
|
|
Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \
|
|
}
|
|
#include "clang/Basic/FPOptions.def"
|
|
LLVM_DUMP_METHOD void dump();
|
|
};
|
|
|
|
/// Represents difference between two FPOptions values.
|
|
///
|
|
/// The effect of language constructs changing the set of floating point options
|
|
/// is usually a change of some FP properties while leaving others intact. This
|
|
/// class describes such changes by keeping information about what FP options
|
|
/// are overridden.
|
|
///
|
|
/// The integral set of FP options, described by the class FPOptions, may be
|
|
/// represented as a default FP option set, defined by language standard and
|
|
/// command line options, with the overrides introduced by pragmas.
|
|
///
|
|
/// The is implemented as a value of the new FPOptions plus a mask showing which
|
|
/// fields are actually set in it.
|
|
class FPOptionsOverride {
|
|
FPOptions Options = FPOptions::getFromOpaqueInt(0);
|
|
FPOptions::storage_type OverrideMask = 0;
|
|
|
|
public:
|
|
using RoundingMode = llvm::RoundingMode;
|
|
|
|
/// The type suitable for storing values of FPOptionsOverride. Must be twice
|
|
/// as wide as bit size of FPOption.
|
|
using storage_type = uint64_t;
|
|
static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type),
|
|
"Too short type for FPOptionsOverride");
|
|
|
|
/// Bit mask selecting bits of OverrideMask in serialized representation of
|
|
/// FPOptionsOverride.
|
|
static constexpr storage_type OverrideMaskBits =
|
|
(static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1;
|
|
|
|
FPOptionsOverride() {}
|
|
FPOptionsOverride(const LangOptions &LO)
|
|
: Options(LO), OverrideMask(OverrideMaskBits) {}
|
|
FPOptionsOverride(FPOptions FPO)
|
|
: Options(FPO), OverrideMask(OverrideMaskBits) {}
|
|
FPOptionsOverride(FPOptions FPO, FPOptions::storage_type Mask)
|
|
: Options(FPO), OverrideMask(Mask) {}
|
|
|
|
bool requiresTrailingStorage() const { return OverrideMask != 0; }
|
|
|
|
void setAllowFPContractWithinStatement() {
|
|
setFPContractModeOverride(LangOptions::FPM_On);
|
|
}
|
|
|
|
void setAllowFPContractAcrossStatement() {
|
|
setFPContractModeOverride(LangOptions::FPM_Fast);
|
|
}
|
|
|
|
void setDisallowFPContract() {
|
|
setFPContractModeOverride(LangOptions::FPM_Off);
|
|
}
|
|
|
|
void setFPPreciseEnabled(bool Value) {
|
|
setAllowFPReassociateOverride(!Value);
|
|
setNoHonorNaNsOverride(!Value);
|
|
setNoHonorInfsOverride(!Value);
|
|
setNoSignedZeroOverride(!Value);
|
|
setAllowReciprocalOverride(!Value);
|
|
setAllowApproxFuncOverride(!Value);
|
|
setMathErrnoOverride(Value);
|
|
if (Value)
|
|
/* Precise mode implies fp_contract=on and disables ffast-math */
|
|
setAllowFPContractWithinStatement();
|
|
else
|
|
/* Precise mode disabled sets fp_contract=fast and enables ffast-math */
|
|
setAllowFPContractAcrossStatement();
|
|
}
|
|
|
|
void setDisallowOptimizations() { setFPPreciseEnabled(true); }
|
|
|
|
storage_type getAsOpaqueInt() const {
|
|
return (static_cast<storage_type>(Options.getAsOpaqueInt())
|
|
<< FPOptions::StorageBitSize) |
|
|
OverrideMask;
|
|
}
|
|
static FPOptionsOverride getFromOpaqueInt(storage_type I) {
|
|
FPOptionsOverride Opts;
|
|
Opts.OverrideMask = I & OverrideMaskBits;
|
|
Opts.Options = FPOptions::getFromOpaqueInt(I >> FPOptions::StorageBitSize);
|
|
return Opts;
|
|
}
|
|
|
|
FPOptions applyOverrides(FPOptions Base) {
|
|
FPOptions Result =
|
|
FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) |
|
|
(Options.getAsOpaqueInt() & OverrideMask));
|
|
return Result;
|
|
}
|
|
|
|
FPOptions applyOverrides(const LangOptions &LO) {
|
|
return applyOverrides(FPOptions(LO));
|
|
}
|
|
|
|
bool operator==(FPOptionsOverride other) const {
|
|
return Options == other.Options && OverrideMask == other.OverrideMask;
|
|
}
|
|
bool operator!=(FPOptionsOverride other) const { return !(*this == other); }
|
|
|
|
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
|
|
bool has##NAME##Override() const { \
|
|
return OverrideMask & FPOptions::NAME##Mask; \
|
|
} \
|
|
TYPE get##NAME##Override() const { \
|
|
assert(has##NAME##Override()); \
|
|
return Options.get##NAME(); \
|
|
} \
|
|
void clear##NAME##Override() { \
|
|
/* Clear the actual value so that we don't have spurious differences when \
|
|
* testing equality. */ \
|
|
Options.set##NAME(TYPE(0)); \
|
|
OverrideMask &= ~FPOptions::NAME##Mask; \
|
|
} \
|
|
void set##NAME##Override(TYPE value) { \
|
|
Options.set##NAME(value); \
|
|
OverrideMask |= FPOptions::NAME##Mask; \
|
|
}
|
|
#include "clang/Basic/FPOptions.def"
|
|
LLVM_DUMP_METHOD void dump();
|
|
};
|
|
|
|
inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const {
|
|
if (Value == Base.Value)
|
|
return FPOptionsOverride();
|
|
return getChangesSlow(Base);
|
|
}
|
|
|
|
inline void FPOptions::applyChanges(FPOptionsOverride FPO) {
|
|
*this = FPO.applyOverrides(*this);
|
|
}
|
|
|
|
/// Describes the kind of translation unit being processed.
|
|
enum TranslationUnitKind {
|
|
/// The translation unit is a complete translation unit.
|
|
TU_Complete,
|
|
|
|
/// The translation unit is a prefix to a translation unit, and is
|
|
/// not complete.
|
|
TU_Prefix,
|
|
|
|
/// The translation unit is a clang module.
|
|
TU_ClangModule,
|
|
|
|
/// The translation unit is a is a complete translation unit that we might
|
|
/// incrementally extend later.
|
|
TU_Incremental
|
|
};
|
|
|
|
} // namespace clang
|
|
|
|
#endif // LLVM_CLANG_BASIC_LANGOPTIONS_H
|