This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG4c484f11d355: [llvm] Add a SFINAE template parameter to
DenseMapInfo (authored by rriddle).
Changed prior to commit:
https://reviews.llvm.org/D113641?vs=387386&id=387702#toc
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,7 @@
} // 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 +90,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,47 @@
EXPECT_EQ(Map.find(K2), Map.end());
EXPECT_EQ(Map.find(K3), Map.end());
}
+} // namespace
+
+namespace {
+struct A {
+ A(int value) : value(value) {}
+ int value;
+};
+struct B : public A {
+ using A::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
@@ -249,7 +249,7 @@
//===----------------------------------------------------------------------===//
// LinearPolySize - base class for fixed- or scalable sizes.
-// ^ ^
+// ^ ^
// | |
// | +----- ElementCount - Leaf class to represent an element count
// | (vscale x unsigned)
@@ -499,8 +499,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
@@ -22,7 +22,7 @@
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 +192,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,7 +39,12 @@
} // end namespace detail
-template<typename T>
+/// 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();
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;
@@ -467,7 +465,7 @@
/// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
/// DenseSets.
template <>
- struct DenseMapInfo<clang::FileID> {
+ struct DenseMapInfo<clang::FileID, void> {
static clang::FileID getEmptyKey() {
return {};
}
@@ -488,7 +486,7 @@
/// 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> {
+ template <> struct DenseMapInfo<clang::SourceLocation, void> {
static clang::SourceLocation getEmptyKey() {
constexpr clang::SourceLocation::UIntTy Zero = 0;
return clang::SourceLocation::getFromRawEncoding(~Zero);
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(); }
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits