PointerLikeTypeTraits: Standardize NumLowBitsAvailable on static constexpr rather...
authorDavid Blaikie <dblaikie@gmail.com>
Wed, 15 Jan 2020 20:36:20 +0000 (12:36 -0800)
committerDavid Blaikie <dblaikie@gmail.com>
Thu, 16 Jan 2020 23:30:50 +0000 (15:30 -0800)
This is (more?) usable by GDB pretty printers and seems nicer to write.

There's one tricky caveat that in C++14 (LLVM's codebase today) the
static constexpr member declaration is not a definition - so odr use of
this constant requires an out of line definition, which won't be
provided (that'd make all these trait classes more annoyidng/expensive
to maintain). But the use of this constant in the library implementation
is/should always be in a non-odr context - only two unit tests needed to
be touched to cope with this/avoid odr using these constants.

Based on/expanded from D72590 by Christian Sigg.

26 files changed:
clang/include/clang/AST/CanonicalType.h
clang/include/clang/AST/DeclGroup.h
clang/include/clang/AST/ExternalASTSource.h
clang/include/clang/AST/TemplateName.h
clang/include/clang/AST/Type.h
clang/include/clang/Basic/IdentifierTable.h
clang/include/clang/Basic/SourceLocation.h
clang/include/clang/CodeGen/ConstantInitFuture.h
clang/include/clang/Sema/Ownership.h
llvm/include/llvm/ADT/IntervalMap.h
llvm/include/llvm/ADT/PointerEmbeddedInt.h
llvm/include/llvm/ADT/PointerIntPair.h
llvm/include/llvm/IR/Use.h
llvm/include/llvm/Support/PointerLikeTypeTraits.h
llvm/lib/Analysis/GlobalsModRef.cpp
llvm/unittests/ADT/PointerEmbeddedIntTest.cpp
llvm/unittests/ADT/PointerIntPairTest.cpp
mlir/include/mlir/IR/Attributes.h
mlir/include/mlir/IR/Function.h
mlir/include/mlir/IR/Identifier.h
mlir/include/mlir/IR/Location.h
mlir/include/mlir/IR/Module.h
mlir/include/mlir/IR/OperationSupport.h
mlir/include/mlir/IR/Types.h
mlir/include/mlir/IR/Value.h
polly/include/polly/CodeGen/IslExprBuilder.h

index 2e00d34..64ec1c0 100644 (file)
@@ -384,7 +384,7 @@ struct PointerLikeTypeTraits<clang::CanQual<T>> {
   }
 
   // qualifier information is encoded in the low bits.
-  enum { NumLowBitsAvailable = 0 };
+  static constexpr int NumLowBitsAvailable = 0;
 };
 
 } // namespace llvm
index 2be9dae..672b7b0 100644 (file)
@@ -147,7 +147,7 @@ namespace llvm {
       return clang::DeclGroupRef::getFromOpaquePtr(P);
     }
 
-    enum { NumLowBitsAvailable = 0 };
+    static constexpr int NumLowBitsAvailable = 0;
   };
 
 } // namespace llvm
index 899ac3f..75671f7 100644 (file)
@@ -504,9 +504,8 @@ struct PointerLikeTypeTraits<
   static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
   static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
 
-  enum {
-    NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
-  };
+  static constexpr int NumLowBitsAvailable =
+      PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1;
 };
 
 } // namespace llvm
index cbbcbf6..e1315fa 100644 (file)
@@ -559,7 +559,7 @@ struct PointerLikeTypeTraits<clang::TemplateName> {
   }
 
   // No bits are available!
-  enum { NumLowBitsAvailable = 0 };
+  static constexpr int NumLowBitsAvailable = 0;
 };
 
 } // namespace llvm.
index f5955c4..2291d77 100644 (file)
@@ -85,7 +85,7 @@ namespace llvm {
       return static_cast< ::clang::Type*>(P);
     }
 
-    enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
+    static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits;
   };
 
   template<>
@@ -96,7 +96,7 @@ namespace llvm {
       return static_cast< ::clang::ExtQuals*>(P);
     }
 
-    enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
+    static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits;
   };
 
 } // namespace llvm
@@ -1295,7 +1295,7 @@ struct PointerLikeTypeTraits<clang::QualType> {
   }
 
   // Various qualifiers go in low bits.
-  enum { NumLowBitsAvailable = 0 };
+  static constexpr int NumLowBitsAvailable = 0;
 };
 
 } // namespace llvm
index ea5d7ad..e5ae833 100644 (file)
@@ -967,7 +967,7 @@ struct PointerLikeTypeTraits<clang::Selector> {
     return clang::Selector(reinterpret_cast<uintptr_t>(P));
   }
 
-  enum { NumLowBitsAvailable = 0 };
+  static constexpr int NumLowBitsAvailable = 0;
 };
 
 // Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
@@ -982,7 +982,7 @@ struct PointerLikeTypeTraits<clang::IdentifierInfo*> {
     return static_cast<clang::IdentifierInfo*>(P);
   }
 
-  enum { NumLowBitsAvailable = 1 };
+  static constexpr int NumLowBitsAvailable = 1;
 };
 
 template<>
@@ -995,7 +995,7 @@ struct PointerLikeTypeTraits<const clang::IdentifierInfo*> {
     return static_cast<const clang::IdentifierInfo*>(P);
   }
 
-  enum { NumLowBitsAvailable = 1 };
+  static constexpr int NumLowBitsAvailable = 1;
 };
 
 } // namespace llvm
index d3d1853..3735b90 100644 (file)
@@ -482,7 +482,7 @@ namespace llvm {
   // Teach SmallPtrSet how to handle SourceLocation.
   template<>
   struct PointerLikeTypeTraits<clang::SourceLocation> {
-    enum { NumLowBitsAvailable = 0 };
+    static constexpr int NumLowBitsAvailable = 0;
 
     static void *getAsVoidPointer(clang::SourceLocation L) {
       return L.getPtrEncoding();
index b08f528..452ba36 100644 (file)
@@ -35,7 +35,7 @@ struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> {
 
   static inline void *getAsVoidPointer(T p) { return p; }
   static inline T getFromVoidPointer(void *p) {return static_cast<T>(p);}
-  enum { NumLowBitsAvailable = 2 };
+  static constexpr int NumLowBitsAvailable = 2;
 };
 }
 
@@ -79,10 +79,8 @@ public:
     result.Data = PairTy::getFromOpaqueValue(value);
     return result;
   }
-  enum {
-    NumLowBitsAvailable =
-      llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable
-  };
+  static constexpr int NumLowBitsAvailable =
+      llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable;
 };
 
 }  // end namespace CodeGen
@@ -100,7 +98,7 @@ struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> {
   static inline T getFromVoidPointer(void *p) {
     return T::getFromOpaqueValue(p);
   }
-  enum { NumLowBitsAvailable = T::NumLowBitsAvailable };
+  static constexpr int NumLowBitsAvailable = T::NumLowBitsAvailable;
 };
 
 } // end namespace llvm
index f395282..4de3397 100644 (file)
@@ -116,7 +116,7 @@ namespace llvm {
 
   template <class T>
   struct PointerLikeTypeTraits<clang::OpaquePtr<T>> {
-    enum { NumLowBitsAvailable = 0 };
+    static constexpr int NumLowBitsAvailable = 0;
 
     static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) {
       // FIXME: Doesn't work? return P.getAs< void >();
index a02876e..e9e6c54 100644 (file)
@@ -491,7 +491,7 @@ class NodeRef {
   struct CacheAlignedPointerTraits {
     static inline void *getAsVoidPointer(void *P) { return P; }
     static inline void *getFromVoidPointer(void *P) { return P; }
-    enum { NumLowBitsAvailable = Log2CacheLine };
+    static constexpr int NumLowBitsAvailable = Log2CacheLine;
   };
   PointerIntPair<void*, Log2CacheLine, unsigned, CacheAlignedPointerTraits> pip;
 
index 3eb6edb..fbc48af 100644 (file)
@@ -94,7 +94,7 @@ struct PointerLikeTypeTraits<PointerEmbeddedInt<IntT, Bits>> {
     return T(reinterpret_cast<uintptr_t>(P), typename T::RawValueTag());
   }
 
-  enum { NumLowBitsAvailable = T::Shift };
+  static constexpr int NumLowBitsAvailable = T::Shift;
 };
 
 // Teach DenseMap how to use PointerEmbeddedInt objects as keys if the Int type
index fa6bf15..bcd7941 100644 (file)
@@ -235,7 +235,8 @@ struct PointerLikeTypeTraits<
     return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
   }
 
-  enum { NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits };
+  static constexpr int NumLowBitsAvailable =
+      PtrTraits::NumLowBitsAvailable - IntBits;
 };
 
 } // end namespace llvm
index 034ca2c..6c5dd60 100644 (file)
@@ -69,7 +69,7 @@ public:
       return (User *)P;
     }
 
-    enum { NumLowBitsAvailable = 1 };
+    static constexpr int NumLowBitsAvailable = 1;
   };
 
   // A type for the word following an array of hung-off Uses in memory, which is
@@ -85,7 +85,7 @@ public:
       return (Use **)P;
     }
 
-    enum { NumLowBitsAvailable = 2 };
+    static constexpr int NumLowBitsAvailable = 2;
   };
 
 private:
index 1e7e5b5..71ec818 100644 (file)
@@ -56,7 +56,8 @@ template <typename T> struct PointerLikeTypeTraits<T *> {
   static inline void *getAsVoidPointer(T *P) { return P; }
   static inline T *getFromVoidPointer(void *P) { return static_cast<T *>(P); }
 
-  enum { NumLowBitsAvailable = detail::ConstantLog2<alignof(T)>::value };
+  static constexpr int NumLowBitsAvailable =
+      detail::ConstantLog2<alignof(T)>::value;
 };
 
 template <> struct PointerLikeTypeTraits<void *> {
@@ -70,7 +71,7 @@ template <> struct PointerLikeTypeTraits<void *> {
   ///
   /// All clients should use assertions to do a run-time check to ensure that
   /// this is actually true.
-  enum { NumLowBitsAvailable = 2 };
+  static constexpr int NumLowBitsAvailable = 2;
 };
 
 // Provide PointerLikeTypeTraits for const things.
@@ -83,7 +84,7 @@ template <typename T> struct PointerLikeTypeTraits<const T> {
   static inline const T getFromVoidPointer(const void *P) {
     return NonConst::getFromVoidPointer(const_cast<void *>(P));
   }
-  enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable };
+  static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable;
 };
 
 // Provide PointerLikeTypeTraits for const pointers.
@@ -96,7 +97,7 @@ template <typename T> struct PointerLikeTypeTraits<const T *> {
   static inline const T *getFromVoidPointer(const void *P) {
     return NonConst::getFromVoidPointer(const_cast<void *>(P));
   }
-  enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable };
+  static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable;
 };
 
 // Provide PointerLikeTypeTraits for uintptr_t.
@@ -108,7 +109,7 @@ template <> struct PointerLikeTypeTraits<uintptr_t> {
     return reinterpret_cast<uintptr_t>(P);
   }
   // No bits are available!
-  enum { NumLowBitsAvailable = 0 };
+  static constexpr int NumLowBitsAvailable = 0;
 };
 
 /// Provide suitable custom traits struct for function pointers.
@@ -121,7 +122,8 @@ template <> struct PointerLikeTypeTraits<uintptr_t> {
 /// potentially use alignment attributes on functions to satisfy that.
 template <int Alignment, typename FunctionPointerT>
 struct FunctionPointerLikeTypeTraits {
-  enum { NumLowBitsAvailable = detail::ConstantLog2<Alignment>::value };
+  static constexpr int NumLowBitsAvailable =
+      detail::ConstantLog2<Alignment>::value;
   static inline void *getAsVoidPointer(FunctionPointerT P) {
     assert((reinterpret_cast<uintptr_t>(P) &
             ~((uintptr_t)-1 << NumLowBitsAvailable)) == 0 &&
index 4361e0d..11005c4 100644 (file)
@@ -77,7 +77,7 @@ class GlobalsAAResult::FunctionInfo {
     static inline AlignedMap *getFromVoidPointer(void *P) {
       return (AlignedMap *)P;
     }
-    enum { NumLowBitsAvailable = 3 };
+    static constexpr int NumLowBitsAvailable = 3;
     static_assert(alignof(AlignedMap) >= (1 << NumLowBitsAvailable),
                   "AlignedMap insufficiently aligned to have enough low bits.");
   };
index d24c8b8..12096e4 100644 (file)
@@ -17,8 +17,8 @@ TEST(PointerEmbeddedIntTest, Basic) {
 
   EXPECT_EQ(42, I);
   EXPECT_EQ(43, I + 1);
-  EXPECT_EQ(sizeof(uintptr_t) * CHAR_BIT - CHAR_BIT,
-            PointerLikeTypeTraits<decltype(I)>::NumLowBitsAvailable);
+  EXPECT_EQ((int)sizeof(uintptr_t) * CHAR_BIT - CHAR_BIT,
+            (int)PointerLikeTypeTraits<decltype(I)>::NumLowBitsAvailable);
 
   EXPECT_FALSE(I == J);
   EXPECT_TRUE(I != J);
index 6b3a4c0..b8ba3e3 100644 (file)
@@ -72,22 +72,22 @@ TEST(PointerIntPairTest, DefaultInitialize) {
   EXPECT_EQ(0U, Pair.getInt());
 }
 
+// In real code this would be a word-sized integer limited to 31 bits.
+struct Fixnum31 {
+  uintptr_t Value;
+};
+struct FixnumPointerTraits {
+  static inline void *getAsVoidPointer(Fixnum31 Num) {
+    return reinterpret_cast<void *>(Num.Value << NumLowBitsAvailable);
+  }
+  static inline Fixnum31 getFromVoidPointer(void *P) {
+    // In real code this would assert that the value is in range.
+    return {reinterpret_cast<uintptr_t>(P) >> NumLowBitsAvailable};
+  }
+  static constexpr int NumLowBitsAvailable =
+      std::numeric_limits<uintptr_t>::digits - 31;
+};
 TEST(PointerIntPairTest, ManyUnusedBits) {
-  // In real code this would be a word-sized integer limited to 31 bits.
-  struct Fixnum31 {
-    uintptr_t Value;
-  };
-  class FixnumPointerTraits {
-  public:
-    static inline void *getAsVoidPointer(Fixnum31 Num) {
-      return reinterpret_cast<void *>(Num.Value << NumLowBitsAvailable);
-    }
-    static inline Fixnum31 getFromVoidPointer(void *P) {
-      // In real code this would assert that the value is in range.
-      return { reinterpret_cast<uintptr_t>(P) >> NumLowBitsAvailable };
-    }
-    enum { NumLowBitsAvailable = std::numeric_limits<uintptr_t>::digits - 31 };
-  };
 
   PointerIntPair<Fixnum31, 1, bool, FixnumPointerTraits> pair;
   EXPECT_EQ((uintptr_t)0, pair.getPointer().Value);
@@ -98,7 +98,7 @@ TEST(PointerIntPairTest, ManyUnusedBits) {
   EXPECT_TRUE(pair.getInt());
 
   EXPECT_EQ(FixnumPointerTraits::NumLowBitsAvailable - 1,
-            PointerLikeTypeTraits<decltype(pair)>::NumLowBitsAvailable);
+            (int)PointerLikeTypeTraits<decltype(pair)>::NumLowBitsAvailable);
 
   static_assert(
       is_trivially_copyable<
index 49f42af..4db7489 100644 (file)
@@ -622,7 +622,7 @@ public:
   }
 
   // Note: We could steal more bits if the need arises.
-  enum { NumLowBitsAvailable = 1 };
+  static constexpr int NumLowBitsAvailable = 1;
 };
 
 /// Pair of raw pointer and a boolean flag of whether the pointer holds a splat,
@@ -1442,7 +1442,7 @@ template <> struct PointerLikeTypeTraits<mlir::Attribute> {
   static inline mlir::Attribute getFromVoidPointer(void *ptr) {
     return mlir::Attribute::getFromOpaquePointer(ptr);
   }
-  enum { NumLowBitsAvailable = 3 };
+  static constexpr int NumLowBitsAvailable = 3;
 };
 
 template <>
index 5323b35..8783c82 100644 (file)
@@ -180,7 +180,7 @@ public:
   static inline mlir::FuncOp getFromVoidPointer(void *P) {
     return mlir::FuncOp::getFromOpaquePointer(P);
   }
-  enum { NumLowBitsAvailable = 3 };
+  static constexpr int NumLowBitsAvailable = 3;
 };
 
 } // namespace llvm
index 604eebf..46fb640 100644 (file)
@@ -127,7 +127,7 @@ public:
   static inline mlir::Identifier getFromVoidPointer(void *P) {
     return mlir::Identifier::getFromOpaquePointer(P);
   }
-  enum { NumLowBitsAvailable = 2 };
+  static constexpr int NumLowBitsAvailable = 2;
 };
 
 } // end namespace llvm
index c36bcb3..0cd89a4 100644 (file)
@@ -321,10 +321,8 @@ public:
   static inline mlir::Location getFromVoidPointer(void *P) {
     return mlir::Location::getFromOpaquePointer(P);
   }
-  enum {
-    NumLowBitsAvailable =
-        PointerLikeTypeTraits<mlir::Attribute>::NumLowBitsAvailable
-  };
+  static constexpr int NumLowBitsAvailable =
+      PointerLikeTypeTraits<mlir::Attribute>::NumLowBitsAvailable;
 };
 
 } // namespace llvm
index fb7c61f..5387813 100644 (file)
@@ -161,7 +161,7 @@ public:
   static inline mlir::ModuleOp getFromVoidPointer(void *P) {
     return mlir::ModuleOp::getFromOpaquePointer(P);
   }
-  enum { NumLowBitsAvailable = 3 };
+  static constexpr int NumLowBitsAvailable = 3;
 };
 
 } // end namespace llvm
index d06131d..11d6821 100644 (file)
@@ -706,10 +706,8 @@ public:
   static inline mlir::OperationName getFromVoidPointer(void *P) {
     return mlir::OperationName::getFromOpaquePointer(P);
   }
-  enum {
-    NumLowBitsAvailable = PointerLikeTypeTraits<
-        mlir::OperationName::RepresentationUnion>::NumLowBitsAvailable
-  };
+  static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<
+      mlir::OperationName::RepresentationUnion>::NumLowBitsAvailable;
 };
 
 } // end namespace llvm
index 21d6493..00bbfd5 100644 (file)
@@ -293,7 +293,7 @@ public:
   static inline mlir::Type getFromVoidPointer(void *P) {
     return mlir::Type::getFromOpaquePointer(P);
   }
-  enum { NumLowBitsAvailable = 3 };
+  static constexpr int NumLowBitsAvailable = 3;
 };
 
 } // namespace llvm
index 6354156..ec19b7d 100644 (file)
@@ -66,7 +66,7 @@ public:
   struct ImplTypeTraits : public llvm::PointerLikeTypeTraits<void *> {
     // We know that all pointers within the ImplType are aligned by 8-bytes,
     // meaning that we can steal up to 3 bits for the different values.
-    enum { NumLowBitsAvailable = 3 };
+    static constexpr int NumLowBitsAvailable = 3;
   };
   using ImplType = llvm::PointerIntPair<void *, 2, Kind, ImplTypeTraits>;
 
index fe727cd..998f8f6 100644 (file)
@@ -24,7 +24,7 @@ public:
   static inline const Region *getFromVoidPointer(void *P) {
     return (Region *)P;
   }
-  enum { NumLowBitsAvailable = 0 };
+  static constexpr int NumLowBitsAvailable = 0;
 };
 } // namespace llvm