summaryrefslogtreecommitdiff
path: root/clang/include/clang/Basic/LangOptions.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang/Basic/LangOptions.h')
-rw-r--r--clang/include/clang/Basic/LangOptions.h247
1 files changed, 188 insertions, 59 deletions
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index ae4a4b2b9e877..a9213b7d86680 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -19,6 +19,7 @@
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/Visibility.h"
+#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include <string>
@@ -53,6 +54,7 @@ enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable };
class LangOptions : public LangOptionsBase {
public:
using Visibility = clang::Visibility;
+ using RoundingMode = llvm::RoundingMode;
enum GCMode { NonGC, GCOnly, HybridGC };
enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
@@ -172,41 +174,20 @@ public:
Swift4_1,
};
- enum FPContractModeKind {
- // Form fused FP ops only where result will not be affected.
- FPC_Off,
+ enum FPModeKind {
+ // Disable the floating point pragma
+ FPM_Off,
- // Form fused FP ops according to FP_CONTRACT rules.
- FPC_On,
+ // Enable the floating point pragma
+ FPM_On,
// Aggressively fuse FP ops (E.g. FMA).
- FPC_Fast
+ FPM_Fast
};
- // TODO: merge FEnvAccessModeKind and FPContractModeKind
- enum FEnvAccessModeKind {
- FEA_Off,
-
- FEA_On
- };
-
- // Values of the following enumerations correspond to metadata arguments
- // specified for constrained floating-point intrinsics:
- // http://llvm.org/docs/LangRef.html#constrained-floating-point-intrinsics.
-
- /// Possible rounding modes.
- enum FPRoundingModeKind {
- /// Rounding to nearest, corresponds to "round.tonearest".
- FPR_ToNearest,
- /// Rounding toward -Inf, corresponds to "round.downward".
- FPR_Downward,
- /// Rounding toward +Inf, corresponds to "round.upward".
- FPR_Upward,
- /// Rounding toward zero, corresponds to "round.towardzero".
- FPR_TowardZero,
- /// Is determined by runtime environment, corresponds to "round.dynamic".
- FPR_Dynamic
- };
+ /// Alias for RoundingMode::NearestTiesToEven.
+ static constexpr unsigned FPR_ToNearest =
+ static_cast<unsigned>(llvm::RoundingMode::NearestTiesToEven);
/// Possible floating point exception behavior.
enum FPExceptionModeKind {
@@ -229,6 +210,22 @@ public:
All,
};
+ 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
+ };
+
public:
/// Set of enabled sanitizers.
SanitizerSet Sanitize;
@@ -351,61 +348,193 @@ public:
/// Return the OpenCL C or C++ version as a VersionTuple.
VersionTuple getOpenCLVersionTuple() const;
+
+ /// 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;
+ }
};
/// Floating point control options
+class FPOptionsOverride;
class FPOptions {
public:
- FPOptions() : fp_contract(LangOptions::FPC_Off),
- fenv_access(LangOptions::FEA_Off) {}
+ // We start by defining the layout.
+ using storage_type = uint16_t;
+
+ using RoundingMode = llvm::RoundingMode;
+
+ // 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"
- // Used for serializing.
- explicit FPOptions(unsigned I)
- : fp_contract(static_cast<LangOptions::FPContractModeKind>(I & 3)),
- fenv_access(static_cast<LangOptions::FEnvAccessModeKind>((I >> 2) & 1))
- {}
+private:
+ storage_type Value;
- explicit FPOptions(const LangOptions &LangOpts)
- : fp_contract(LangOpts.getDefaultFPContractMode()),
- fenv_access(LangOptions::FEA_Off) {}
- // FIXME: Use getDefaultFEnvAccessMode() when available.
+public:
+ FPOptions() : Value(0) {
+ setFPContractMode(LangOptions::FPM_Off);
+ setRoundingMode(static_cast<RoundingMode>(LangOptions::FPR_ToNearest));
+ setFPExceptionMode(LangOptions::FPE_Ignore);
+ }
+ // Used for serializing.
+ explicit FPOptions(unsigned I) { getFromOpaqueInt(I); }
+
+ explicit FPOptions(const LangOptions &LO) {
+ Value = 0;
+ setFPContractMode(LO.getDefaultFPContractMode());
+ setRoundingMode(LO.getFPRoundingMode());
+ setFPExceptionMode(LO.getFPExceptionMode());
+ setAllowFEnvAccess(LangOptions::FPM_Off),
+ setAllowFPReassociate(LO.AllowFPReassoc);
+ setNoHonorNaNs(LO.NoHonorNaNs);
+ setNoHonorInfs(LO.NoHonorInfs);
+ setNoSignedZero(LO.NoSignedZero);
+ setAllowReciprocal(LO.AllowRecip);
+ setAllowApproxFunc(LO.ApproxFunc);
+ }
bool allowFPContractWithinStatement() const {
- return fp_contract == LangOptions::FPC_On;
+ return getFPContractMode() == LangOptions::FPM_On;
+ }
+ void setAllowFPContractWithinStatement() {
+ setFPContractMode(LangOptions::FPM_On);
}
bool allowFPContractAcrossStatement() const {
- return fp_contract == LangOptions::FPC_Fast;
+ return getFPContractMode() == LangOptions::FPM_Fast;
}
+ void setAllowFPContractAcrossStatement() {
+ setFPContractMode(LangOptions::FPM_Fast);
+ }
+
+ bool isFPConstrained() const {
+ return getRoundingMode() !=
+ static_cast<unsigned>(RoundingMode::NearestTiesToEven) ||
+ getFPExceptionMode() != LangOptions::FPE_Ignore ||
+ getAllowFEnvAccess();
+ }
+
+ 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; }
+ void getFromOpaqueInt(storage_type value) { Value = value; }
+
+ // We can define most of the accessors automatically:
+#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
+ unsigned get##NAME() const { \
+ return static_cast<unsigned>(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();
+};
+
+/// The FPOptions override type is value of the new FPOptions
+/// plus a mask showing which fields are actually set in it:
+class FPOptionsOverride {
+ FPOptions Options;
+ FPOptions::storage_type OverrideMask = 0;
+
+public:
+ using RoundingMode = llvm::RoundingMode;
+ FPOptionsOverride() {}
+
+ // Used for serializing.
+ explicit FPOptionsOverride(unsigned I) { getFromOpaqueInt(I); }
+
+ bool requiresTrailingStorage() const { return OverrideMask != 0; }
void setAllowFPContractWithinStatement() {
- fp_contract = LangOptions::FPC_On;
+ setFPContractModeOverride(LangOptions::FPM_On);
}
void setAllowFPContractAcrossStatement() {
- fp_contract = LangOptions::FPC_Fast;
+ setFPContractModeOverride(LangOptions::FPM_Fast);
}
- void setDisallowFPContract() { fp_contract = LangOptions::FPC_Off; }
-
- bool allowFEnvAccess() const {
- return fenv_access == LangOptions::FEA_On;
+ void setDisallowFPContract() {
+ setFPContractModeOverride(LangOptions::FPM_Off);
}
- void setAllowFEnvAccess() {
- fenv_access = LangOptions::FEA_On;
+ void setFPPreciseEnabled(bool Value) {
+ setAllowFPReassociateOverride(!Value);
+ setNoHonorNaNsOverride(!Value);
+ setNoHonorInfsOverride(!Value);
+ setNoSignedZeroOverride(!Value);
+ setAllowReciprocalOverride(!Value);
+ setAllowApproxFuncOverride(!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 setDisallowFEnvAccess() { fenv_access = LangOptions::FEA_Off; }
+ unsigned getAsOpaqueInt() const {
+ return Options.getAsOpaqueInt() << 16 | OverrideMask;
+ }
+ void getFromOpaqueInt(unsigned I) {
+ OverrideMask = I & 0xffff;
+ Options.getFromOpaqueInt(I >> 16);
+ }
- /// Used to serialize this.
- unsigned getInt() const { return fp_contract | (fenv_access << 2); }
+ FPOptions applyOverrides(const LangOptions &LO) {
+ FPOptions Base(LO);
+ FPOptions result((Base.getAsOpaqueInt() & ~OverrideMask) |
+ (Options.getAsOpaqueInt() & OverrideMask));
+ return result;
+ }
-private:
- /// Adjust BinaryOperator::FPFeatures to match the total bit-field size
- /// of these two.
- unsigned fp_contract : 2;
- unsigned fenv_access : 1;
+ 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; \
+ } \
+ unsigned 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();
};
/// Describes the kind of translation unit being processed.