[clang] 21cd7b7 - Use typedef to represent storage type in FPOption and FPOptionsOverride

Serge Pavlov via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 21 00:37:03 PDT 2020


Author: Serge Pavlov
Date: 2020-07-21T14:35:50+07:00
New Revision: 21cd7b72a3d4d1d5efaadc09533655090b678e57

URL: https://github.com/llvm/llvm-project/commit/21cd7b72a3d4d1d5efaadc09533655090b678e57
DIFF: https://github.com/llvm/llvm-project/commit/21cd7b72a3d4d1d5efaadc09533655090b678e57.diff

LOG: Use typedef to represent storage type in FPOption and FPOptionsOverride

Size of FPOption is now 14 bit, which is closed to the current limit
of 16 bits. Adding new properties to FPOption would require change of
the types, which represent storage of FPOption and FPOptionsOverride.
To facilitate this change, the storage types were changed from standard
integer types to typedefs defined inside the proper classes. Checks for
size of these storage types were added.

No functional changes intended.

Differential Revision: https://reviews.llvm.org/D84147

Added: 
    

Modified: 
    clang/include/clang/Basic/FPOptions.def
    clang/include/clang/Basic/LangOptions.h
    clang/include/clang/Sema/Sema.h
    clang/include/clang/Serialization/ASTReader.h

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/FPOptions.def b/clang/include/clang/Basic/FPOptions.def
index 6b6789b8ecc8..1733689775d4 100644
--- a/clang/include/clang/Basic/FPOptions.def
+++ b/clang/include/clang/Basic/FPOptions.def
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // This file defines the Floating Point language options. Users of this file
-//  must define the FPOPT macro to make use of this information.
+//  must define the OPTION macro to make use of this information.
 #ifndef OPTION
 #  error Define the OPTION macro to handle floating point language options
 #endif

diff  --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index a9213b7d8668..31e8af4589b4 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -374,6 +374,8 @@ class FPOptions {
 
   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;
@@ -385,6 +387,12 @@ class FPOptions {
                                              << 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;
 
@@ -402,8 +410,8 @@ class FPOptions {
     setFPContractMode(LO.getDefaultFPContractMode());
     setRoundingMode(LO.getFPRoundingMode());
     setFPExceptionMode(LO.getFPExceptionMode());
-    setAllowFEnvAccess(LangOptions::FPM_Off),
-        setAllowFPReassociate(LO.AllowFPReassoc);
+    setAllowFEnvAccess(LangOptions::FPM_Off);
+    setAllowFPReassociate(LO.AllowFPReassoc);
     setNoHonorNaNs(LO.NoHonorNaNs);
     setNoHonorInfs(LO.NoHonorInfs);
     setNoSignedZero(LO.NoSignedZero);
@@ -453,18 +461,45 @@ class FPOptions {
   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:
+/// Represents 
diff erence 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::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 = uint32_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(FPOptions::storage_type Value, FPOptions::storage_type Mask)
+      : Options(Value), OverrideMask(Mask) {}
+  FPOptionsOverride(const LangOptions &LO)
+      : Options(LO), OverrideMask(OverrideMaskBits) {}
 
   // Used for serializing.
-  explicit FPOptionsOverride(unsigned I) { getFromOpaqueInt(I); }
+  explicit FPOptionsOverride(storage_type I) { getFromOpaqueInt(I); }
 
   bool requiresTrailingStorage() const { return OverrideMask != 0; }
 
@@ -495,19 +530,24 @@ class FPOptionsOverride {
       setAllowFPContractAcrossStatement();
   }
 
-  unsigned getAsOpaqueInt() const {
-    return Options.getAsOpaqueInt() << 16 | OverrideMask;
+  storage_type getAsOpaqueInt() const {
+    return (static_cast<storage_type>(Options.getAsOpaqueInt())
+            << FPOptions::StorageBitSize) |
+           OverrideMask;
   }
-  void getFromOpaqueInt(unsigned I) {
-    OverrideMask = I & 0xffff;
-    Options.getFromOpaqueInt(I >> 16);
+  void getFromOpaqueInt(storage_type I) {
+    OverrideMask = I & OverrideMaskBits;
+    Options.getFromOpaqueInt(I >> FPOptions::StorageBitSize);
   }
 
-  FPOptions applyOverrides(const LangOptions &LO) {
-    FPOptions Base(LO);
-    FPOptions result((Base.getAsOpaqueInt() & ~OverrideMask) |
+  FPOptions applyOverrides(FPOptions Base) {
+    FPOptions Result((Base.getAsOpaqueInt() & ~OverrideMask) |
                      (Options.getAsOpaqueInt() & OverrideMask));
-    return result;
+    return Result;
+  }
+
+  FPOptions applyOverrides(const LangOptions &LO) {
+    return applyOverrides(FPOptions(LO));
   }
 
   bool operator==(FPOptionsOverride other) const {

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6f7ad8076718..06cb0b1b8bdc 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -587,7 +587,7 @@ class Sema final {
   PragmaStack<StringLiteral *> CodeSegStack;
 
   // This stack tracks the current state of Sema.CurFPFeatures.
-  PragmaStack<unsigned> FpPragmaStack;
+  PragmaStack<FPOptionsOverride::storage_type> FpPragmaStack;
   FPOptionsOverride CurFPFeatureOverrides() {
     FPOptionsOverride result;
     if (!FpPragmaStack.hasValue()) {
@@ -1405,12 +1405,12 @@ class Sema final {
       S.CurFPFeatures = OldFPFeaturesState;
       S.FpPragmaStack.CurrentValue = OldOverrides;
     }
-    unsigned getOverrides() { return OldOverrides; }
+    FPOptionsOverride::storage_type getOverrides() { return OldOverrides; }
 
   private:
     Sema& S;
     FPOptions OldFPFeaturesState;
-    unsigned OldOverrides;
+    FPOptionsOverride::storage_type OldOverrides;
   };
 
   void addImplicitTypedef(StringRef Name, QualType T);

diff  --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index a80366f0ee04..1d5571cd2854 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -858,10 +858,10 @@ class ASTReader
   SourceLocation PointersToMembersPragmaLocation;
 
   /// The pragma float_control state.
-  Optional<unsigned> FpPragmaCurrentValue;
+  Optional<FPOptionsOverride::storage_type> FpPragmaCurrentValue;
   SourceLocation FpPragmaCurrentLocation;
   struct FpPragmaStackEntry {
-    unsigned Value;
+    FPOptionsOverride::storage_type Value;
     SourceLocation Location;
     SourceLocation PushLocation;
     StringRef SlotLabel;


        


More information about the cfe-commits mailing list