rriddle updated this revision to Diff 387386.
rriddle added a comment.
Herald added subscribers: lldb-commits, hiraditya.
Herald added a project: LLDB.

resolve comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113641/new/

https://reviews.llvm.org/D113641

Files:
  clang/include/clang/AST/TypeOrdering.h
  clang/include/clang/Basic/SourceLocation.h
  clang/include/clang/Sema/Sema.h
  lldb/include/lldb/Utility/ConstString.h
  llvm/include/llvm/ADT/APInt.h
  llvm/include/llvm/ADT/APSInt.h
  llvm/include/llvm/ADT/ArrayRef.h
  llvm/include/llvm/ADT/DenseMapInfo.h
  llvm/include/llvm/ADT/Hashing.h
  llvm/include/llvm/ADT/ImmutableList.h
  llvm/include/llvm/ADT/PointerIntPair.h
  llvm/include/llvm/ADT/StringRef.h
  llvm/include/llvm/BinaryFormat/WasmTraits.h
  llvm/include/llvm/CodeGen/SelectionDAGNodes.h
  llvm/include/llvm/IR/Attributes.h
  llvm/include/llvm/Support/TypeSize.h
  llvm/lib/Support/APInt.cpp
  llvm/unittests/ADT/DenseMapTest.cpp
  mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.h
  mlir/include/mlir/IR/Attributes.h
  mlir/include/mlir/IR/BuiltinOps.h
  mlir/include/mlir/IR/OpDefinition.h
  mlir/include/mlir/IR/Types.h
  mlir/include/mlir/Support/LLVM.h

Index: mlir/include/mlir/Support/LLVM.h
===================================================================
--- mlir/include/mlir/Support/LLVM.h
+++ mlir/include/mlir/Support/LLVM.h
@@ -46,7 +46,8 @@
 } // namespace detail
 template <typename KeyT, typename ValueT, typename KeyInfoT, typename BucketT>
 class DenseMap;
-template <typename T> struct DenseMapInfo;
+template <typename T, typename Enable>
+struct DenseMapInfo;
 template <typename ValueT, typename ValueInfoT> class DenseSet;
 class MallocAllocator;
 template <typename T> class MutableArrayRef;
@@ -90,7 +91,8 @@
 //
 // Containers.
 using llvm::ArrayRef;
-using llvm::DenseMapInfo;
+template <typename T, typename Enable = void>
+using DenseMapInfo = llvm::DenseMapInfo<T, Enable>;
 template <typename KeyT, typename ValueT,
           typename KeyInfoT = DenseMapInfo<KeyT>,
           typename BucketT = llvm::detail::DenseMapPair<KeyT, ValueT>>
Index: mlir/include/mlir/IR/Types.h
===================================================================
--- mlir/include/mlir/IR/Types.h
+++ mlir/include/mlir/IR/Types.h
@@ -269,6 +269,18 @@
   static unsigned getHashValue(mlir::Type val) { return mlir::hash_value(val); }
   static bool isEqual(mlir::Type LHS, mlir::Type RHS) { return LHS == RHS; }
 };
+template <typename T>
+struct DenseMapInfo<T, std::enable_if_t<std::is_base_of<mlir::Type, T>::value>>
+    : public DenseMapInfo<mlir::Type> {
+  static T getEmptyKey() {
+    const void *pointer = llvm::DenseMapInfo<const void *>::getEmptyKey();
+    return T::getFromOpaquePointer(pointer);
+  }
+  static T getTombstoneKey() {
+    const void *pointer = llvm::DenseMapInfo<const void *>::getTombstoneKey();
+    return T::getFromOpaquePointer(pointer);
+  }
+};
 
 /// We align TypeStorage by 8, so allow LLVM to steal the low bits.
 template <> struct PointerLikeTypeTraits<mlir::Type> {
Index: mlir/include/mlir/IR/OpDefinition.h
===================================================================
--- mlir/include/mlir/IR/OpDefinition.h
+++ mlir/include/mlir/IR/OpDefinition.h
@@ -1906,4 +1906,25 @@
 } // namespace impl
 } // end namespace mlir
 
+namespace llvm {
+
+template <typename T>
+struct DenseMapInfo<
+    T, std::enable_if_t<std::is_base_of<mlir::OpState, T>::value>> {
+  static inline T getEmptyKey() {
+    auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
+    return T::getFromOpaquePointer(pointer);
+  }
+  static inline T getTombstoneKey() {
+    auto *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
+    return T::getFromOpaquePointer(pointer);
+  }
+  static unsigned getHashValue(T val) {
+    return hash_value(val.getAsOpaquePointer());
+  }
+  static bool isEqual(T lhs, T rhs) { return lhs == rhs; }
+};
+
+} // end namespace llvm
+
 #endif
Index: mlir/include/mlir/IR/BuiltinOps.h
===================================================================
--- mlir/include/mlir/IR/BuiltinOps.h
+++ mlir/include/mlir/IR/BuiltinOps.h
@@ -49,23 +49,6 @@
 } // end namespace mlir
 
 namespace llvm {
-// Functions hash just like pointers.
-template <>
-struct DenseMapInfo<mlir::FuncOp> {
-  static mlir::FuncOp getEmptyKey() {
-    auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
-    return mlir::FuncOp::getFromOpaquePointer(pointer);
-  }
-  static mlir::FuncOp getTombstoneKey() {
-    auto *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
-    return mlir::FuncOp::getFromOpaquePointer(pointer);
-  }
-  static unsigned getHashValue(mlir::FuncOp val) {
-    return hash_value(val.getAsOpaquePointer());
-  }
-  static bool isEqual(mlir::FuncOp lhs, mlir::FuncOp rhs) { return lhs == rhs; }
-};
-
 /// Allow stealing the low bits of FuncOp.
 template <>
 struct PointerLikeTypeTraits<mlir::FuncOp> {
Index: mlir/include/mlir/IR/Attributes.h
===================================================================
--- mlir/include/mlir/IR/Attributes.h
+++ mlir/include/mlir/IR/Attributes.h
@@ -201,6 +201,19 @@
     return LHS == RHS;
   }
 };
+template <typename T>
+struct DenseMapInfo<
+    T, std::enable_if_t<std::is_base_of<mlir::Attribute, T>::value>>
+    : public DenseMapInfo<mlir::Attribute> {
+  static T getEmptyKey() {
+    const void *pointer = llvm::DenseMapInfo<const void *>::getEmptyKey();
+    return T::getFromOpaquePointer(pointer);
+  }
+  static T getTombstoneKey() {
+    const void *pointer = llvm::DenseMapInfo<const void *>::getTombstoneKey();
+    return T::getFromOpaquePointer(pointer);
+  }
+};
 
 /// Allow LLVM to steal the low bits of Attributes.
 template <> struct PointerLikeTypeTraits<mlir::Attribute> {
Index: mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.h
===================================================================
--- mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.h
+++ mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.h
@@ -40,25 +40,6 @@
 
 namespace llvm {
 
-/// spirv::Function ops hash just like pointers.
-template <>
-struct DenseMapInfo<mlir::spirv::FuncOp> {
-  static mlir::spirv::FuncOp getEmptyKey() {
-    auto pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
-    return mlir::spirv::FuncOp::getFromOpaquePointer(pointer);
-  }
-  static mlir::spirv::FuncOp getTombstoneKey() {
-    auto pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
-    return mlir::spirv::FuncOp::getFromOpaquePointer(pointer);
-  }
-  static unsigned getHashValue(mlir::spirv::FuncOp val) {
-    return hash_value(val.getAsOpaquePointer());
-  }
-  static bool isEqual(mlir::spirv::FuncOp LHS, mlir::spirv::FuncOp RHS) {
-    return LHS == RHS;
-  }
-};
-
 /// Allow stealing the low bits of spirv::Function ops.
 template <>
 struct PointerLikeTypeTraits<mlir::spirv::FuncOp> {
Index: llvm/unittests/ADT/DenseMapTest.cpp
===================================================================
--- llvm/unittests/ADT/DenseMapTest.cpp
+++ llvm/unittests/ADT/DenseMapTest.cpp
@@ -655,4 +655,44 @@
   EXPECT_EQ(Map.find(K2), Map.end());
   EXPECT_EQ(Map.find(K3), Map.end());
 }
+} // namespace
+
+namespace {
+struct A {
+  int value;
+};
+struct B : public A {};
+} // namespace
+
+namespace llvm {
+template <typename T>
+struct DenseMapInfo<T, std::enable_if_t<std::is_base_of<A, T>::value>> {
+  static inline T getEmptyKey() { return {static_cast<int>(~0)}; }
+  static inline T getTombstoneKey() { return {static_cast<int>(~0U - 1)}; }
+  static unsigned getHashValue(const T &Val) { return Val.value; }
+  static bool isEqual(const T &LHS, const T &RHS) {
+    return LHS.value == RHS.value;
+  }
+};
+} // namespace llvm
+
+namespace {
+TEST(DenseMapCustomTest, SFINAEMapInfo) {
+  // Test that we can use a pointer to an incomplete type as a DenseMap key.
+  // This is an important build time optimization, since many classes have
+  // DenseMap members.
+  DenseMap<B, int> Map;
+  B Keys[3] = {{0}, {1}, {2}};
+  Map.insert({Keys[0], 1});
+  Map.insert({Keys[1], 2});
+  Map.insert({Keys[2], 3});
+  EXPECT_EQ(Map.count(Keys[0]), 1u);
+  EXPECT_EQ(Map[Keys[0]], 1);
+  EXPECT_EQ(Map[Keys[1]], 2);
+  EXPECT_EQ(Map[Keys[2]], 3);
+  Map.clear();
+  EXPECT_EQ(Map.find(Keys[0]), Map.end());
+  EXPECT_EQ(Map.find(Keys[1]), Map.end());
+  EXPECT_EQ(Map.find(Keys[2]), Map.end());
 }
+} // namespace
Index: llvm/lib/Support/APInt.cpp
===================================================================
--- llvm/lib/Support/APInt.cpp
+++ llvm/lib/Support/APInt.cpp
@@ -569,7 +569,7 @@
       hash_combine_range(Arg.U.pVal, Arg.U.pVal + Arg.getNumWords()));
 }
 
-unsigned DenseMapInfo<APInt>::getHashValue(const APInt &Key) {
+unsigned DenseMapInfo<APInt, void>::getHashValue(const APInt &Key) {
   return static_cast<unsigned>(hash_value(Key));
 }
 
Index: llvm/include/llvm/Support/TypeSize.h
===================================================================
--- llvm/include/llvm/Support/TypeSize.h
+++ llvm/include/llvm/Support/TypeSize.h
@@ -246,10 +246,9 @@
   }
 };
 
-
 //===----------------------------------------------------------------------===//
 // LinearPolySize - base class for fixed- or scalable sizes.
-//  ^  ^ 
+//  ^  ^
 //  |  |
 //  |  +----- ElementCount - Leaf class to represent an element count
 //  |                        (vscale x unsigned)
@@ -499,8 +498,7 @@
   return OS;
 }
 
-template <typename T> struct DenseMapInfo;
-template <> struct DenseMapInfo<ElementCount> {
+template <> struct DenseMapInfo<ElementCount, void> {
   static inline ElementCount getEmptyKey() {
     return ElementCount::getScalable(~0U);
   }
Index: llvm/include/llvm/IR/Attributes.h
===================================================================
--- llvm/include/llvm/IR/Attributes.h
+++ llvm/include/llvm/IR/Attributes.h
@@ -37,7 +37,6 @@
 class AttributeImpl;
 class AttributeListImpl;
 class AttributeSetNode;
-template<typename T> struct DenseMapInfo;
 class FoldingSetNodeID;
 class Function;
 class LLVMContext;
@@ -266,7 +265,7 @@
 /// and removing string or integer attributes involves a FoldingSet lookup.
 class AttributeSet {
   friend AttributeListImpl;
-  template <typename Ty> friend struct DenseMapInfo;
+  template <typename Ty, typename Enable> friend struct DenseMapInfo;
 
   // TODO: Extract AvailableAttrs from AttributeSetNode and store them here.
   // This will allow an efficient implementation of addAttribute and
@@ -367,7 +366,7 @@
 //===----------------------------------------------------------------------===//
 /// \class
 /// Provide DenseMapInfo for AttributeSet.
-template <> struct DenseMapInfo<AttributeSet> {
+template <> struct DenseMapInfo<AttributeSet, void> {
   static AttributeSet getEmptyKey() {
     auto Val = static_cast<uintptr_t>(-1);
     Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
@@ -409,7 +408,7 @@
   friend class AttributeListImpl;
   friend class AttributeSet;
   friend class AttributeSetNode;
-  template <typename Ty> friend struct DenseMapInfo;
+  template <typename Ty, typename Enable> friend struct DenseMapInfo;
 
   /// The attributes that we are managing. This can be null to represent
   /// the empty attributes list.
@@ -899,7 +898,7 @@
 //===----------------------------------------------------------------------===//
 /// \class
 /// Provide DenseMapInfo for AttributeList.
-template <> struct DenseMapInfo<AttributeList> {
+template <> struct DenseMapInfo<AttributeList, void> {
   static AttributeList getEmptyKey() {
     auto Val = static_cast<uintptr_t>(-1);
     Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h
===================================================================
--- llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -58,7 +58,6 @@
 
 class APInt;
 class Constant;
-template <typename T> struct DenseMapInfo;
 class GlobalValue;
 class MachineBasicBlock;
 class MachineConstantPoolValue;
Index: llvm/include/llvm/BinaryFormat/WasmTraits.h
===================================================================
--- llvm/include/llvm/BinaryFormat/WasmTraits.h
+++ llvm/include/llvm/BinaryFormat/WasmTraits.h
@@ -18,10 +18,8 @@
 
 namespace llvm {
 
-template <typename T> struct DenseMapInfo;
-
 // Traits for using WasmSignature in a DenseMap.
-template <> struct DenseMapInfo<wasm::WasmSignature> {
+template <> struct DenseMapInfo<wasm::WasmSignature, void> {
   static wasm::WasmSignature getEmptyKey() {
     wasm::WasmSignature Sig;
     Sig.State = wasm::WasmSignature::Empty;
@@ -47,7 +45,7 @@
 };
 
 // Traits for using WasmGlobalType in a DenseMap
-template <> struct DenseMapInfo<wasm::WasmGlobalType> {
+template <> struct DenseMapInfo<wasm::WasmGlobalType, void> {
   static wasm::WasmGlobalType getEmptyKey() {
     return wasm::WasmGlobalType{1, true};
   }
@@ -64,7 +62,7 @@
 };
 
 // Traits for using WasmLimits in a DenseMap
-template <> struct DenseMapInfo<wasm::WasmLimits> {
+template <> struct DenseMapInfo<wasm::WasmLimits, void> {
   static wasm::WasmLimits getEmptyKey() {
     return wasm::WasmLimits{0xff, 0xff, 0xff};
   }
@@ -86,19 +84,19 @@
 };
 
 // Traits for using WasmTableType in a DenseMap
-template <> struct DenseMapInfo<wasm::WasmTableType> {
+template <> struct DenseMapInfo<wasm::WasmTableType, void> {
   static wasm::WasmTableType getEmptyKey() {
-    return wasm::WasmTableType{0,
-                               DenseMapInfo<wasm::WasmLimits>::getEmptyKey()};
+    return wasm::WasmTableType{
+        0, DenseMapInfo<wasm::WasmLimits, void>::getEmptyKey()};
   }
   static wasm::WasmTableType getTombstoneKey() {
     return wasm::WasmTableType{
-        1, DenseMapInfo<wasm::WasmLimits>::getTombstoneKey()};
+        1, DenseMapInfo<wasm::WasmLimits, void>::getTombstoneKey()};
   }
   static unsigned getHashValue(const wasm::WasmTableType &TableType) {
     return hash_combine(
         TableType.ElemType,
-        DenseMapInfo<wasm::WasmLimits>::getHashValue(TableType.Limits));
+        DenseMapInfo<wasm::WasmLimits, void>::getHashValue(TableType.Limits));
   }
   static bool isEqual(const wasm::WasmTableType &LHS,
                       const wasm::WasmTableType &RHS) {
Index: llvm/include/llvm/ADT/StringRef.h
===================================================================
--- llvm/include/llvm/ADT/StringRef.h
+++ llvm/include/llvm/ADT/StringRef.h
@@ -35,7 +35,6 @@
   class APInt;
   class hash_code;
   template <typename T> class SmallVectorImpl;
-  template <typename T> struct DenseMapInfo;
   class StringRef;
 
   /// Helper functions for StringRef::getAsInteger.
@@ -949,7 +948,7 @@
   hash_code hash_value(StringRef S);
 
   // Provide DenseMapInfo for StringRefs.
-  template <> struct DenseMapInfo<StringRef> {
+  template <> struct DenseMapInfo<StringRef, void> {
     static inline StringRef getEmptyKey() {
       return StringRef(
           reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)), 0);
Index: llvm/include/llvm/ADT/PointerIntPair.h
===================================================================
--- llvm/include/llvm/ADT/PointerIntPair.h
+++ llvm/include/llvm/ADT/PointerIntPair.h
@@ -21,8 +21,7 @@
 #include <limits>
 
 namespace llvm {
-
-template <typename T> struct DenseMapInfo;
+template <typename T, typename Enable> struct DenseMapInfo;
 template <typename PointerT, unsigned IntBits, typename PtrTraits>
 struct PointerIntPairInfo;
 
@@ -192,7 +191,7 @@
 
 // Provide specialization of DenseMapInfo for PointerIntPair.
 template <typename PointerTy, unsigned IntBits, typename IntType>
-struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>> {
+struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>, void> {
   using Ty = PointerIntPair<PointerTy, IntBits, IntType>;
 
   static Ty getEmptyKey() {
Index: llvm/include/llvm/ADT/ImmutableList.h
===================================================================
--- llvm/include/llvm/ADT/ImmutableList.h
+++ llvm/include/llvm/ADT/ImmutableList.h
@@ -220,8 +220,7 @@
 // Partially-specialized Traits.
 //===----------------------------------------------------------------------===//
 
-template<typename T> struct DenseMapInfo;
-template<typename T> struct DenseMapInfo<ImmutableList<T>> {
+template <typename T> struct DenseMapInfo<ImmutableList<T>, void> {
   static inline ImmutableList<T> getEmptyKey() {
     return reinterpret_cast<ImmutableListImpl<T>*>(-1);
   }
Index: llvm/include/llvm/ADT/Hashing.h
===================================================================
--- llvm/include/llvm/ADT/Hashing.h
+++ llvm/include/llvm/ADT/Hashing.h
@@ -56,7 +56,7 @@
 #include <utility>
 
 namespace llvm {
-template <typename T> struct DenseMapInfo;
+template <typename T, typename Enable> struct DenseMapInfo;
 
 /// An opaque object representing a hash code.
 ///
@@ -678,7 +678,7 @@
   return hash_combine_range(arg.begin(), arg.end());
 }
 
-template <> struct DenseMapInfo<hash_code> {
+template <> struct DenseMapInfo<hash_code, void> {
   static inline hash_code getEmptyKey() { return hash_code(-1); }
   static inline hash_code getTombstoneKey() { return hash_code(-2); }
   static unsigned getHashValue(hash_code val) { return val; }
Index: llvm/include/llvm/ADT/DenseMapInfo.h
===================================================================
--- llvm/include/llvm/ADT/DenseMapInfo.h
+++ llvm/include/llvm/ADT/DenseMapInfo.h
@@ -39,8 +39,12 @@
 
 } // end namespace detail
 
-template<typename T>
-struct DenseMapInfo {
+/// An information struct used to provide DenseMap with the various necessary
+/// components for a given value type `T`. `Enable` is an optional additional
+/// parameter that is used to support SFINAE (generally using std::enable_if_t)
+/// in derived DenseMapInfo specializations; in non-SFINAE use cases this should
+/// just be `void`.
+template <typename T, typename Enable = void> struct DenseMapInfo {
   //static inline T getEmptyKey();
   //static inline T getTombstoneKey();
   //static unsigned getHashValue(const T &Val);
Index: llvm/include/llvm/ADT/ArrayRef.h
===================================================================
--- llvm/include/llvm/ADT/ArrayRef.h
+++ llvm/include/llvm/ADT/ArrayRef.h
@@ -26,8 +26,6 @@
 
 namespace llvm {
 
-  template<typename T> struct DenseMapInfo;
-
   /// ArrayRef - Represent a constant reference to an array (0 or more elements
   /// consecutively in memory), i.e. a start pointer and a length.  It allows
   /// various APIs to take consecutive elements easily and conveniently.
@@ -572,7 +570,7 @@
   }
 
   // Provide DenseMapInfo for ArrayRefs.
-  template <typename T> struct DenseMapInfo<ArrayRef<T>> {
+  template <typename T> struct DenseMapInfo<ArrayRef<T>, void> {
     static inline ArrayRef<T> getEmptyKey() {
       return ArrayRef<T>(
           reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)), size_t(0));
Index: llvm/include/llvm/ADT/APSInt.h
===================================================================
--- llvm/include/llvm/ADT/APSInt.h
+++ llvm/include/llvm/ADT/APSInt.h
@@ -344,17 +344,17 @@
 }
 
 /// Provide DenseMapInfo for APSInt, using the DenseMapInfo for APInt.
-template <> struct DenseMapInfo<APSInt> {
+template <> struct DenseMapInfo<APSInt, void> {
   static inline APSInt getEmptyKey() {
-    return APSInt(DenseMapInfo<APInt>::getEmptyKey());
+    return APSInt(DenseMapInfo<APInt, void>::getEmptyKey());
   }
 
   static inline APSInt getTombstoneKey() {
-    return APSInt(DenseMapInfo<APInt>::getTombstoneKey());
+    return APSInt(DenseMapInfo<APInt, void>::getTombstoneKey());
   }
 
   static unsigned getHashValue(const APSInt &Key) {
-    return DenseMapInfo<APInt>::getHashValue(Key);
+    return DenseMapInfo<APInt, void>::getHashValue(Key);
   }
 
   static bool isEqual(const APSInt &LHS, const APSInt &RHS) {
Index: llvm/include/llvm/ADT/APInt.h
===================================================================
--- llvm/include/llvm/ADT/APInt.h
+++ llvm/include/llvm/ADT/APInt.h
@@ -31,7 +31,7 @@
 template <typename T> class SmallVectorImpl;
 template <typename T> class ArrayRef;
 template <typename T> class Optional;
-template <typename T> struct DenseMapInfo;
+template <typename T, typename Enable> struct DenseMapInfo;
 
 class APInt;
 
@@ -1817,7 +1817,7 @@
 
   unsigned BitWidth; ///< The number of bits in this APInt.
 
-  friend struct DenseMapInfo<APInt>;
+  friend struct DenseMapInfo<APInt, void>;
   friend class APSInt;
 
   /// This constructor is used only internally for speed of construction of
@@ -2251,7 +2251,7 @@
 void LoadIntFromMemory(APInt &IntVal, const uint8_t *Src, unsigned LoadBytes);
 
 /// Provide DenseMapInfo for APInt.
-template <> struct DenseMapInfo<APInt> {
+template <> struct DenseMapInfo<APInt, void> {
   static inline APInt getEmptyKey() {
     APInt V(nullptr, 0);
     V.U.VAL = 0;
Index: lldb/include/lldb/Utility/ConstString.h
===================================================================
--- lldb/include/lldb/Utility/ConstString.h
+++ lldb/include/lldb/Utility/ConstString.h
@@ -409,7 +409,7 @@
   static size_t StaticMemorySize();
 
 protected:
-  template <typename T> friend struct ::llvm::DenseMapInfo;
+  template <typename T, typename Enable> friend struct ::llvm::DenseMapInfo;
   /// Only used by DenseMapInfo.
   static ConstString FromStringPoolPointer(const char *ptr) {
     ConstString s;
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -74,7 +74,6 @@
 
 namespace llvm {
   class APSInt;
-  template <typename ValueT> struct DenseMapInfo;
   template <typename ValueT, typename ValueInfoT> class DenseSet;
   class SmallBitVector;
   struct InlineAsmIdentifierInfo;
Index: clang/include/clang/Basic/SourceLocation.h
===================================================================
--- clang/include/clang/Basic/SourceLocation.h
+++ clang/include/clang/Basic/SourceLocation.h
@@ -23,8 +23,6 @@
 
 namespace llvm {
 
-template <typename T> struct DenseMapInfo;
-
 class FoldingSetNodeID;
 template <typename T> struct FoldingSetTrait;
 
@@ -466,47 +464,42 @@
 
   /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
   /// DenseSets.
-  template <>
-  struct DenseMapInfo<clang::FileID> {
-    static clang::FileID getEmptyKey() {
-      return {};
-    }
+template <> struct DenseMapInfo<clang::FileID, void> {
+  static clang::FileID getEmptyKey() { return {}; }
 
-    static clang::FileID getTombstoneKey() {
-      return clang::FileID::getSentinel();
-    }
+  static clang::FileID getTombstoneKey() {
+    return clang::FileID::getSentinel();
+  }
 
-    static unsigned getHashValue(clang::FileID S) {
-      return S.getHashValue();
-    }
+  static unsigned getHashValue(clang::FileID S) { return S.getHashValue(); }
 
-    static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
-      return LHS == RHS;
-    }
-  };
+  static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
+    return LHS == RHS;
+  }
+};
 
   /// Define DenseMapInfo so that SourceLocation's can be used as keys in
   /// DenseMap and DenseSet. This trait class is eqivalent to
   /// DenseMapInfo<unsigned> which uses SourceLocation::ID is used as a key.
-  template <> struct DenseMapInfo<clang::SourceLocation> {
-    static clang::SourceLocation getEmptyKey() {
-      constexpr clang::SourceLocation::UIntTy Zero = 0;
-      return clang::SourceLocation::getFromRawEncoding(~Zero);
-    }
+template <> struct DenseMapInfo<clang::SourceLocation, void> {
+  static clang::SourceLocation getEmptyKey() {
+    constexpr clang::SourceLocation::UIntTy Zero = 0;
+    return clang::SourceLocation::getFromRawEncoding(~Zero);
+  }
 
-    static clang::SourceLocation getTombstoneKey() {
-      constexpr clang::SourceLocation::UIntTy Zero = 0;
-      return clang::SourceLocation::getFromRawEncoding(~Zero - 1);
-    }
+  static clang::SourceLocation getTombstoneKey() {
+    constexpr clang::SourceLocation::UIntTy Zero = 0;
+    return clang::SourceLocation::getFromRawEncoding(~Zero - 1);
+  }
 
-    static unsigned getHashValue(clang::SourceLocation Loc) {
-      return Loc.getHashValue();
-    }
+  static unsigned getHashValue(clang::SourceLocation Loc) {
+    return Loc.getHashValue();
+  }
 
-    static bool isEqual(clang::SourceLocation LHS, clang::SourceLocation RHS) {
-      return LHS == RHS;
-    }
-  };
+  static bool isEqual(clang::SourceLocation LHS, clang::SourceLocation RHS) {
+    return LHS == RHS;
+  }
+};
 
   // Allow calling FoldingSetNodeID::Add with SourceLocation object as parameter
   template <> struct FoldingSetTrait<clang::SourceLocation> {
Index: clang/include/clang/AST/TypeOrdering.h
===================================================================
--- clang/include/clang/AST/TypeOrdering.h
+++ clang/include/clang/AST/TypeOrdering.h
@@ -34,7 +34,6 @@
 }
 
 namespace llvm {
-  template<class> struct DenseMapInfo;
 
   template<> struct DenseMapInfo<clang::QualType> {
     static inline clang::QualType getEmptyKey() { return clang::QualType(); }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to