https://github.com/MaskRay updated 
https://github.com/llvm/llvm-project/pull/201987

>From 21be584b731d91919610e45f71bc4925211e92a9 Mon Sep 17 00:00:00 2001
From: Fangrui Song <[email protected]>
Date: Fri, 5 Jun 2026 19:08:12 -0700
Subject: [PATCH 1/2] [clang][clang-tools-extra] Remove unused
 DenseMapInfo::getEmptyKey

After #201281 DenseMapInfo<T>::getEmptyKey() is no longer used by
DenseMap. Remove the unused getEmptyKey definitions and dead sentinel
uses.
---
 .../SpecialMemberFunctionsCheck.h             |  8 -------
 .../utils/RenamerClangTidyCheck.cpp           |  8 -------
 clang-tools-extra/clangd/Config.h             |  3 ---
 clang-tools-extra/clangd/Headers.h            |  4 ----
 clang-tools-extra/clangd/Protocol.h           |  5 -----
 .../clangd/SystemIncludeExtractor.cpp         |  5 -----
 clang-tools-extra/clangd/index/Ref.h          |  4 ----
 clang-tools-extra/clangd/index/SymbolID.h     |  4 ----
 clang-tools-extra/clangd/index/dex/Token.h    |  4 ----
 clang-tools-extra/clangd/index/dex/Trigram.h  |  3 ---
 .../include/clang-include-cleaner/Types.h     |  7 ------
 clang/include/clang/AST/APValue.h             |  1 -
 clang/include/clang/AST/ASTContext.h          |  5 -----
 clang/include/clang/AST/ASTTypeTraits.h       | 11 +---------
 clang/include/clang/AST/BaseSubobject.h       |  6 -----
 clang/include/clang/AST/CharUnits.h           |  7 ------
 clang/include/clang/AST/DeclID.h              |  8 -------
 clang/include/clang/AST/DeclarationName.h     |  4 ----
 clang/include/clang/AST/GlobalDecl.h          |  4 ----
 clang/include/clang/AST/NestedNameSpecifier.h |  7 ------
 clang/include/clang/AST/Redeclarable.h        |  8 -------
 clang/include/clang/AST/TypeOrdering.h        |  6 -----
 .../Analysis/Analyses/LifetimeSafety/Utils.h  |  4 ----
 clang/include/clang/Analysis/CallGraph.h      |  6 -----
 .../FlowSensitive/DataflowAnalysisContext.h   |  5 -----
 .../clang/Analysis/FlowSensitive/Formula.h    |  1 -
 clang/include/clang/Analysis/ProgramPoint.h   |  7 ------
 .../clang/Analysis/RetainSummaryManager.h     |  5 -----
 clang/include/clang/Basic/DirectoryEntry.h    | 20 -----------------
 clang/include/clang/Basic/FileEntry.h         | 21 ------------------
 clang/include/clang/Basic/IdentifierTable.h   |  4 ----
 clang/include/clang/Basic/Module.h            |  4 ----
 clang/include/clang/Basic/SourceLocation.h    | 13 -----------
 clang/include/clang/Basic/TokenKinds.h        |  3 ---
 .../DependencyScanning/DependencyGraph.h      |  1 -
 clang/include/clang/Sema/ScopeInfo.h          |  4 ----
 clang/include/clang/Sema/SemaCUDA.h           |  4 ----
 clang/include/clang/Sema/Weak.h               |  3 ---
 .../include/clang/Serialization/ASTBitCodes.h |  8 -------
 .../Tooling/Inclusions/StandardLibrary.h      |  8 -------
 clang/lib/APINotes/APINotesFormat.h           | 13 -----------
 clang/lib/AST/APValue.cpp                     |  7 ------
 clang/lib/AST/ExprConstant.cpp                |  3 ---
 clang/lib/AST/ItaniumCXXABI.cpp               | 22 -------------------
 .../CodeGen/CGObjCMacConstantLiteralUtil.h    |  8 -------
 clang/lib/CodeGen/CodeGenTBAA.h               | 10 ---------
 clang/lib/Sema/SemaStmt.cpp                   |  9 --------
 clang/lib/StaticAnalyzer/Core/CallEvent.cpp   |  4 ----
 .../ClangLinkerWrapper.cpp                    |  1 -
 clang/tools/libclang/CXCursor.cpp             |  3 ---
 clang/tools/libclang/Indexing.cpp             |  4 ----
 51 files changed, 1 insertion(+), 326 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h
index e3ed12de4fd3e..78447df5a1b36 100644
--- 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h
+++ 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h
@@ -83,20 +83,12 @@ struct DenseMapInfo<
   using ClassDefId =
       clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId;
 
-  static ClassDefId getEmptyKey() {
-    return {DenseMapInfo<clang::SourceLocation>::getEmptyKey(), "EMPTY"};
-  }
-
   static unsigned getHashValue(const ClassDefId &Val) {
-    assert(Val != getEmptyKey() && "Cannot hash the empty key!");
-
     const std::hash<ClassDefId::second_type> SecondHash;
     return Val.first.getHashValue() + SecondHash(Val.second);
   }
 
   static bool isEqual(const ClassDefId &LHS, const ClassDefId &RHS) {
-    if (RHS == getEmptyKey())
-      return LHS == getEmptyKey();
     return LHS == RHS;
   }
 };
diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp 
b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index c4b800d2c9e19..cb7ef19827675 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -30,20 +30,12 @@ template <>
 struct DenseMapInfo<clang::tidy::RenamerClangTidyCheck::NamingCheckId> {
   using NamingCheckId = clang::tidy::RenamerClangTidyCheck::NamingCheckId;
 
-  static NamingCheckId getEmptyKey() {
-    return {DenseMapInfo<clang::SourceLocation>::getEmptyKey(), "EMPTY"};
-  }
-
   static unsigned getHashValue(NamingCheckId Val) {
-    assert(Val != getEmptyKey() && "Cannot hash the empty key!");
-
     return DenseMapInfo<clang::SourceLocation>::getHashValue(Val.first) +
            DenseMapInfo<StringRef>::getHashValue(Val.second);
   }
 
   static bool isEqual(const NamingCheckId &LHS, const NamingCheckId &RHS) {
-    if (RHS == getEmptyKey())
-      return LHS == getEmptyKey();
     return LHS == RHS;
   }
 };
diff --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index 450ca6ea93ddc..a94a1727199bd 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -229,9 +229,6 @@ struct Config {
 namespace llvm {
 template <> struct DenseMapInfo<clang::clangd::Config::ExternalIndexSpec> {
   using ExternalIndexSpec = clang::clangd::Config::ExternalIndexSpec;
-  static inline ExternalIndexSpec getEmptyKey() {
-    return {ExternalIndexSpec::File, "", ""};
-  }
   static unsigned getHashValue(const ExternalIndexSpec &Val) {
     return llvm::hash_combine(Val.Kind, Val.Location, Val.MountPoint);
   }
diff --git a/clang-tools-extra/clangd/Headers.h 
b/clang-tools-extra/clangd/Headers.h
index 05536529b22b9..050d972f24a29 100644
--- a/clang-tools-extra/clangd/Headers.h
+++ b/clang-tools-extra/clangd/Headers.h
@@ -273,10 +273,6 @@ namespace llvm {
 
 // Support HeaderIDs as DenseMap keys.
 template <> struct DenseMapInfo<clang::clangd::IncludeStructure::HeaderID> {
-  static inline clang::clangd::IncludeStructure::HeaderID getEmptyKey() {
-    return static_cast<clang::clangd::IncludeStructure::HeaderID>(-1);
-  }
-
   static unsigned
   getHashValue(const clang::clangd::IncludeStructure::HeaderID &Tag) {
     return hash_value(static_cast<unsigned>(Tag));
diff --git a/clang-tools-extra/clangd/Protocol.h 
b/clang-tools-extra/clangd/Protocol.h
index 67aea52ef43d4..b511ca495e47f 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -2108,11 +2108,6 @@ namespace llvm {
 
 template <> struct DenseMapInfo<clang::clangd::Range> {
   using Range = clang::clangd::Range;
-  static inline Range getEmptyKey() {
-    static clang::clangd::Position Tomb{-1, -1};
-    static Range R{Tomb, Tomb};
-    return R;
-  }
   static unsigned getHashValue(const Range &Val) {
     return llvm::hash_combine(Val.start.line, Val.start.character, 
Val.end.line,
                               Val.end.character);
diff --git a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp 
b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
index 8809426f8130a..b4dbc1df1d636 100644
--- a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
+++ b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
@@ -217,11 +217,6 @@ struct DriverArgs {
 namespace llvm {
 using DriverArgs = clang::clangd::DriverArgs;
 template <> struct DenseMapInfo<DriverArgs> {
-  static DriverArgs getEmptyKey() {
-    auto Driver = DriverArgs::getEmpty();
-    Driver.Driver = "EMPTY_KEY";
-    return Driver;
-  }
   static unsigned getHashValue(const DriverArgs &Val) {
     unsigned FixedFieldsHash = llvm::hash_value(std::tuple{
         Val.Driver,
diff --git a/clang-tools-extra/clangd/index/Ref.h 
b/clang-tools-extra/clangd/index/Ref.h
index aa7c88443e909..b71f09611fed1 100644
--- a/clang-tools-extra/clangd/index/Ref.h
+++ b/clang-tools-extra/clangd/index/Ref.h
@@ -171,10 +171,6 @@ class RefSlab {
 namespace llvm {
 template <> struct DenseMapInfo<clang::clangd::RefSlab::Builder::Entry> {
   using Entry = clang::clangd::RefSlab::Builder::Entry;
-  static inline Entry getEmptyKey() {
-    static Entry E{clang::clangd::SymbolID(""), {}};
-    return E;
-  }
   static unsigned getHashValue(const Entry &Val) {
     return llvm::hash_combine(
         Val.Symbol, 
reinterpret_cast<uintptr_t>(Val.Reference.Location.FileURI),
diff --git a/clang-tools-extra/clangd/index/SymbolID.h 
b/clang-tools-extra/clangd/index/SymbolID.h
index 929004aa70a25..d13eea1a9028b 100644
--- a/clang-tools-extra/clangd/index/SymbolID.h
+++ b/clang-tools-extra/clangd/index/SymbolID.h
@@ -81,10 +81,6 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const 
SymbolID &ID);
 namespace llvm {
 // Support SymbolIDs as DenseMap keys.
 template <> struct DenseMapInfo<clang::clangd::SymbolID> {
-  static inline clang::clangd::SymbolID getEmptyKey() {
-    static clang::clangd::SymbolID EmptyKey("EMPTYKEY");
-    return EmptyKey;
-  }
   static unsigned getHashValue(const clang::clangd::SymbolID &Sym) {
     return hash_value(Sym);
   }
diff --git a/clang-tools-extra/clangd/index/dex/Token.h 
b/clang-tools-extra/clangd/index/dex/Token.h
index f69d8f1f117ef..98a504c4c3fa2 100644
--- a/clang-tools-extra/clangd/index/dex/Token.h
+++ b/clang-tools-extra/clangd/index/dex/Token.h
@@ -115,10 +115,6 @@ namespace llvm {
 
 // Support Tokens as DenseMap keys.
 template <> struct DenseMapInfo<clang::clangd::dex::Token> {
-  static inline clang::clangd::dex::Token getEmptyKey() {
-    return {clang::clangd::dex::Token::Kind::Sentinel, "EmptyKey"};
-  }
-
   static unsigned getHashValue(const clang::clangd::dex::Token &Tag) {
     return hash_value(Tag);
   }
diff --git a/clang-tools-extra/clangd/index/dex/Trigram.h 
b/clang-tools-extra/clangd/index/dex/Trigram.h
index 6bdb72f0caf7e..bad3c4378598f 100644
--- a/clang-tools-extra/clangd/index/dex/Trigram.h
+++ b/clang-tools-extra/clangd/index/dex/Trigram.h
@@ -90,9 +90,6 @@ std::vector<Token> generateQueryTrigrams(llvm::StringRef 
Query);
 namespace llvm {
 template <> struct DenseMapInfo<clang::clangd::dex::Trigram> {
   using Trigram = clang::clangd::dex::Trigram;
-  static inline Trigram getEmptyKey() {
-    return Trigram(Trigram::Sentinel::Empty);
-  }
   static unsigned getHashValue(Trigram V) {
     // Finalize step from MurmurHash3.
     uint32_t X = V.id();
diff --git 
a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h 
b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
index 99d65266bf53d..341cf1851142b 100644
--- a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
+++ b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
@@ -219,9 +219,6 @@ template <> struct 
DenseMapInfo<clang::include_cleaner::Symbol> {
   using Outer = clang::include_cleaner::Symbol;
   using Base = DenseMapInfo<decltype(Outer::Storage)>;
 
-  static Outer getEmptyKey() {
-    return {Outer::SentinelTag{}, Base::getEmptyKey()};
-  }
   static unsigned getHashValue(const Outer &Val) {
     return Base::getHashValue(Val.Storage);
   }
@@ -233,7 +230,6 @@ template <> struct 
DenseMapInfo<clang::include_cleaner::Macro> {
   using Outer = clang::include_cleaner::Macro;
   using Base = DenseMapInfo<decltype(Outer::Definition)>;
 
-  static Outer getEmptyKey() { return {nullptr, Base::getEmptyKey()}; }
   static unsigned getHashValue(const Outer &Val) {
     return Base::getHashValue(Val.Definition);
   }
@@ -245,9 +241,6 @@ template <> struct 
DenseMapInfo<clang::include_cleaner::Header> {
   using Outer = clang::include_cleaner::Header;
   using Base = DenseMapInfo<decltype(Outer::Storage)>;
 
-  static Outer getEmptyKey() {
-    return {Outer::SentinelTag{}, Base::getEmptyKey()};
-  }
   static unsigned getHashValue(const Outer &Val) {
     return Base::getHashValue(Val.Storage);
   }
diff --git a/clang/include/clang/AST/APValue.h 
b/clang/include/clang/AST/APValue.h
index 22f0ad18caee4..acbd922ba5319 100644
--- a/clang/include/clang/AST/APValue.h
+++ b/clang/include/clang/AST/APValue.h
@@ -838,7 +838,6 @@ class APValue {
 
 namespace llvm {
 template<> struct DenseMapInfo<clang::APValue::LValueBase> {
-  static clang::APValue::LValueBase getEmptyKey();
   static unsigned getHashValue(const clang::APValue::LValueBase &Base);
   static bool isEqual(const clang::APValue::LValueBase &LHS,
                       const clang::APValue::LValueBase &RHS);
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 54c046f5fab4a..6cdcb0ec1eb0b 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -70,9 +70,6 @@ struct ScalableVecTyKey {
 // Provide a DenseMapInfo specialization so that ScalableVecTyKey can be used
 // as a key in DenseMap.
 template <> struct DenseMapInfo<ScalableVecTyKey> {
-  static inline ScalableVecTyKey getEmptyKey() {
-    return {DenseMapInfo<clang::QualType>::getEmptyKey(), ~0U, ~0U};
-  }
   static unsigned getHashValue(const ScalableVecTyKey &Val) {
     return hash_combine(DenseMapInfo<clang::QualType>::getHashValue(Val.EltTy),
                         Val.NumElts, Val.NumFields);
@@ -4005,8 +4002,6 @@ typename clang::LazyGenerationalUpdatePtr<Owner, T, 
Update>::ValueType
   return Value;
 }
 template <> struct llvm::DenseMapInfo<llvm::FoldingSetNodeID> {
-  static FoldingSetNodeID getEmptyKey() { return FoldingSetNodeID{}; }
-
   static unsigned getHashValue(const FoldingSetNodeID &Val) {
     return Val.ComputeHash();
   }
diff --git a/clang/include/clang/AST/ASTTypeTraits.h 
b/clang/include/clang/AST/ASTTypeTraits.h
index e8a18725645c0..40d715390e757 100644
--- a/clang/include/clang/AST/ASTTypeTraits.h
+++ b/clang/include/clang/AST/ASTTypeTraits.h
@@ -109,7 +109,6 @@ class ASTNodeKind {
   /// Hooks for using ASTNodeKind as a key in a DenseMap.
   struct DenseMapInfo {
     // ASTNodeKind() is a good empty key because it is represented as a 0.
-    static inline ASTNodeKind getEmptyKey() { return ASTNodeKind(); }
     static unsigned getHashValue(const ASTNodeKind &Val) { return Val.KindId; }
     static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS) {
       return LHS.KindId == RHS.KindId;
@@ -369,11 +368,6 @@ class DynTypedNode {
 
   /// Hooks for using DynTypedNode as a key in a DenseMap.
   struct DenseMapInfo {
-    static inline DynTypedNode getEmptyKey() {
-      DynTypedNode Node;
-      Node.NodeKind = ASTNodeKind::DenseMapInfo::getEmptyKey();
-      return Node;
-    }
     static unsigned getHashValue(const DynTypedNode &Val) {
       // FIXME: Add hashing support for the remaining types.
       if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(Val.NodeKind)) {
@@ -394,10 +388,7 @@ class DynTypedNode {
       return llvm::hash_value(Val.getMemoizationData());
     }
     static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
-      auto Empty = ASTNodeKind::DenseMapInfo::getEmptyKey();
-      return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) &&
-              ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, Empty)) ||
-             LHS == RHS;
+      return LHS == RHS;
     }
   };
 
diff --git a/clang/include/clang/AST/BaseSubobject.h 
b/clang/include/clang/AST/BaseSubobject.h
index f98c323a0b110..328572802d582 100644
--- a/clang/include/clang/AST/BaseSubobject.h
+++ b/clang/include/clang/AST/BaseSubobject.h
@@ -55,12 +55,6 @@ class BaseSubobject {
 namespace llvm {
 
 template<> struct DenseMapInfo<clang::BaseSubobject> {
-  static clang::BaseSubobject getEmptyKey() {
-    return clang::BaseSubobject(
-      DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
-      clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getEmptyKey()));
-  }
-
   static unsigned getHashValue(const clang::BaseSubobject &Base) {
     using PairTy = std::pair<const clang::CXXRecordDecl *, clang::CharUnits>;
 
diff --git a/clang/include/clang/AST/CharUnits.h 
b/clang/include/clang/AST/CharUnits.h
index e6e6b93e0c192..aee838e60f948 100644
--- a/clang/include/clang/AST/CharUnits.h
+++ b/clang/include/clang/AST/CharUnits.h
@@ -230,13 +230,6 @@ inline clang::CharUnits operator* 
(clang::CharUnits::QuantityType Scale,
 namespace llvm {
 
 template<> struct DenseMapInfo<clang::CharUnits> {
-  static clang::CharUnits getEmptyKey() {
-    clang::CharUnits::QuantityType Quantity =
-      DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
-
-    return clang::CharUnits::fromQuantity(Quantity);
-  }
-
   static unsigned getHashValue(const clang::CharUnits &CU) {
     clang::CharUnits::QuantityType Quantity = CU.getQuantity();
     return 
DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h
index 8a173e3d96349..dab8ddc601843 100644
--- a/clang/include/clang/AST/DeclID.h
+++ b/clang/include/clang/AST/DeclID.h
@@ -248,10 +248,6 @@ template <> struct DenseMapInfo<clang::GlobalDeclID> {
   using GlobalDeclID = clang::GlobalDeclID;
   using DeclID = GlobalDeclID::DeclID;
 
-  static GlobalDeclID getEmptyKey() {
-    return GlobalDeclID(DenseMapInfo<DeclID>::getEmptyKey());
-  }
-
   static unsigned getHashValue(const GlobalDeclID &Key) {
     return DenseMapInfo<DeclID>::getHashValue(Key.getRawValue());
   }
@@ -265,10 +261,6 @@ template <> struct DenseMapInfo<clang::LocalDeclID> {
   using LocalDeclID = clang::LocalDeclID;
   using DeclID = LocalDeclID::DeclID;
 
-  static LocalDeclID getEmptyKey() {
-    return LocalDeclID(DenseMapInfo<DeclID>::getEmptyKey());
-  }
-
   static unsigned getHashValue(const LocalDeclID &Key) {
     return DenseMapInfo<DeclID>::getHashValue(Key.getRawValue());
   }
diff --git a/clang/include/clang/AST/DeclarationName.h 
b/clang/include/clang/AST/DeclarationName.h
index 2cd7efcae5088..3a272c506ca8d 100644
--- a/clang/include/clang/AST/DeclarationName.h
+++ b/clang/include/clang/AST/DeclarationName.h
@@ -924,10 +924,6 @@ namespace llvm {
 /// in DenseMap and DenseSets.
 template<>
 struct DenseMapInfo<clang::DeclarationName> {
-  static inline clang::DeclarationName getEmptyKey() {
-    return clang::DeclarationName::getEmptyMarker();
-  }
-
   static unsigned getHashValue(clang::DeclarationName Name) {
     return DenseMapInfo<void*>::getHashValue(Name.getAsOpaquePtr());
   }
diff --git a/clang/include/clang/AST/GlobalDecl.h 
b/clang/include/clang/AST/GlobalDecl.h
index b9a06afc271ca..0f9ff9496ff88 100644
--- a/clang/include/clang/AST/GlobalDecl.h
+++ b/clang/include/clang/AST/GlobalDecl.h
@@ -215,10 +215,6 @@ class GlobalDecl {
 namespace llvm {
 
   template<> struct DenseMapInfo<clang::GlobalDecl> {
-    static inline clang::GlobalDecl getEmptyKey() {
-      return clang::GlobalDecl();
-    }
-
     static unsigned getHashValue(clang::GlobalDecl GD) {
       return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
     }
diff --git a/clang/include/clang/AST/NestedNameSpecifier.h 
b/clang/include/clang/AST/NestedNameSpecifier.h
index ac1439c70ce7b..b7d24d5397077 100644
--- a/clang/include/clang/AST/NestedNameSpecifier.h
+++ b/clang/include/clang/AST/NestedNameSpecifier.h
@@ -253,8 +253,6 @@ SourceRange NestedNameSpecifierLocBuilder::getSourceRange() 
const {
 namespace llvm {
 
 template <> struct DenseMapInfo<clang::NestedNameSpecifier> {
-  static clang::NestedNameSpecifier getEmptyKey() { return std::nullopt; }
-
   static unsigned getHashValue(const clang::NestedNameSpecifier &V) {
     return hash_combine(V.getAsVoidPointer());
   }
@@ -264,11 +262,6 @@ template <> struct 
DenseMapInfo<clang::NestedNameSpecifierLoc> {
   using FirstInfo = DenseMapInfo<clang::NestedNameSpecifier>;
   using SecondInfo = DenseMapInfo<void *>;
 
-  static clang::NestedNameSpecifierLoc getEmptyKey() {
-    return clang::NestedNameSpecifierLoc(FirstInfo::getEmptyKey(),
-                                         SecondInfo::getEmptyKey());
-  }
-
   static unsigned getHashValue(const clang::NestedNameSpecifierLoc &PairVal) {
     return hash_combine(
         FirstInfo::getHashValue(PairVal.getNestedNameSpecifier()),
diff --git a/clang/include/clang/AST/Redeclarable.h 
b/clang/include/clang/AST/Redeclarable.h
index 6a3f485a5f5da..28fff4f43823c 100644
--- a/clang/include/clang/AST/Redeclarable.h
+++ b/clang/include/clang/AST/Redeclarable.h
@@ -383,14 +383,6 @@ struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> {
   using CanonicalDeclPtr = clang::CanonicalDeclPtr<decl_type>;
   using BaseInfo = DenseMapInfo<decl_type *>;
 
-  static CanonicalDeclPtr getEmptyKey() {
-    // Construct our CanonicalDeclPtr this way because the regular constructor
-    // would dereference P.Ptr, which is not allowed.
-    CanonicalDeclPtr P;
-    P.Ptr = BaseInfo::getEmptyKey();
-    return P;
-  }
-
   static unsigned getHashValue(const CanonicalDeclPtr &P) {
     return BaseInfo::getHashValue(P);
   }
diff --git a/clang/include/clang/AST/TypeOrdering.h 
b/clang/include/clang/AST/TypeOrdering.h
index 0626cb97217f2..dd858c8c0b0ca 100644
--- a/clang/include/clang/AST/TypeOrdering.h
+++ b/clang/include/clang/AST/TypeOrdering.h
@@ -36,8 +36,6 @@ struct QualTypeOrdering {
 namespace llvm {
 
   template<> struct DenseMapInfo<clang::QualType> {
-    static inline clang::QualType getEmptyKey() { return clang::QualType(); }
-
     static unsigned getHashValue(clang::QualType Val) {
       return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
             ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
@@ -49,10 +47,6 @@ namespace llvm {
   };
 
   template<> struct DenseMapInfo<clang::CanQualType> {
-    static inline clang::CanQualType getEmptyKey() {
-      return clang::CanQualType();
-    }
-
     static unsigned getHashValue(clang::CanQualType Val) {
       return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
       ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Utils.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Utils.h
index 0a89de4dcfeb1..61e01787e3db8 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Utils.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Utils.h
@@ -99,10 +99,6 @@ template <typename Tag>
 struct DenseMapInfo<clang::lifetimes::internal::utils::ID<Tag>> {
   using ID = clang::lifetimes::internal::utils::ID<Tag>;
 
-  static inline ID getEmptyKey() {
-    return {DenseMapInfo<uint32_t>::getEmptyKey()};
-  }
-
   static unsigned getHashValue(const ID &Val) {
     return DenseMapInfo<uint32_t>::getHashValue(Val.Value);
   }
diff --git a/clang/include/clang/Analysis/CallGraph.h 
b/clang/include/clang/Analysis/CallGraph.h
index 4c4b940ef110a..76d1bd1dc9f34 100644
--- a/clang/include/clang/Analysis/CallGraph.h
+++ b/clang/include/clang/Analysis/CallGraph.h
@@ -214,12 +214,6 @@ namespace llvm {
 
 // Specialize DenseMapInfo for clang::CallGraphNode::CallRecord.
 template <> struct DenseMapInfo<clang::CallGraphNode::CallRecord> {
-  static inline clang::CallGraphNode::CallRecord getEmptyKey() {
-    return clang::CallGraphNode::CallRecord(
-        DenseMapInfo<clang::CallGraphNode *>::getEmptyKey(),
-        DenseMapInfo<clang::Expr *>::getEmptyKey());
-  }
-
   static unsigned getHashValue(const clang::CallGraphNode::CallRecord &Val) {
     // NOTE: we are comparing based on the callee only.
     // Different call records with the same callee will compare equal!
diff --git 
a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
index 3d51a07599fd4..36d735db46b19 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
@@ -242,11 +242,6 @@ class DataflowAnalysisContext {
   friend class Environment;
 
   struct NullableQualTypeDenseMapInfo : private llvm::DenseMapInfo<QualType> {
-    static QualType getEmptyKey() {
-      // Allow a NULL `QualType` by using a different value as the empty key.
-      return QualType::getFromOpaquePtr(reinterpret_cast<Type *>(1));
-    }
-
     using DenseMapInfo::getHashValue;
     using DenseMapInfo::isEqual;
   };
diff --git a/clang/include/clang/Analysis/FlowSensitive/Formula.h 
b/clang/include/clang/Analysis/FlowSensitive/Formula.h
index 4bd2b28e7567a..be18270375df8 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Formula.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Formula.h
@@ -137,7 +137,6 @@ template <> struct DenseMapInfo<clang::dataflow::Atom> {
   using Atom = clang::dataflow::Atom;
   using Underlying = std::underlying_type_t<Atom>;
 
-  static inline Atom getEmptyKey() { return Atom(Underlying(-1)); }
   static unsigned getHashValue(const Atom &Val) {
     return DenseMapInfo<Underlying>::getHashValue(Underlying(Val));
   }
diff --git a/clang/include/clang/Analysis/ProgramPoint.h 
b/clang/include/clang/Analysis/ProgramPoint.h
index b0fedea2fd8ee..c098160c68b56 100644
--- a/clang/include/clang/Analysis/ProgramPoint.h
+++ b/clang/include/clang/Analysis/ProgramPoint.h
@@ -751,13 +751,6 @@ namespace llvm { // Traits specialization for DenseMap
 
 template <> struct DenseMapInfo<clang::ProgramPoint> {
 
-static inline clang::ProgramPoint getEmptyKey() {
-  uintptr_t x =
-   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
-  return clang::BlockEntrance(nullptr, reinterpret_cast<clang::CFGBlock *>(x),
-                              nullptr);
-}
-
 static unsigned getHashValue(const clang::ProgramPoint &Loc) {
   return Loc.getHashValue();
 }
diff --git a/clang/include/clang/Analysis/RetainSummaryManager.h 
b/clang/include/clang/Analysis/RetainSummaryManager.h
index 868c916ccc803..797685ac7f2ef 100644
--- a/clang/include/clang/Analysis/RetainSummaryManager.h
+++ b/clang/include/clang/Analysis/RetainSummaryManager.h
@@ -246,11 +246,6 @@ template <> struct FoldingSetTrait<RetEffect> {
 };
 
 template <> struct DenseMapInfo<ObjCSummaryKey> {
-  static inline ObjCSummaryKey getEmptyKey() {
-    return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(),
-                          DenseMapInfo<Selector>::getEmptyKey());
-  }
-
   static unsigned getHashValue(const ObjCSummaryKey &V) {
     typedef std::pair<IdentifierInfo*, Selector> PairTy;
     return DenseMapInfo<PairTy>::getHashValue(PairTy(V.getIdentifier(),
diff --git a/clang/include/clang/Basic/DirectoryEntry.h 
b/clang/include/clang/Basic/DirectoryEntry.h
index 4502789439776..6079e8a4e37e6 100644
--- a/clang/include/clang/Basic/DirectoryEntry.h
+++ b/clang/include/clang/Basic/DirectoryEntry.h
@@ -95,14 +95,6 @@ class DirectoryEntryRef {
   bool hasOptionalValue() const { return ME; }
 
   friend struct llvm::DenseMapInfo<DirectoryEntryRef>;
-  struct dense_map_empty_tag {};
-
-  // Private constructor for use by DenseMapInfo.
-  DirectoryEntryRef(dense_map_empty_tag)
-      : ME(llvm::DenseMapInfo<const MapEntry *>::getEmptyKey()) {}
-  bool isSpecialDenseMapKey() const {
-    return isSameRef(DirectoryEntryRef(dense_map_empty_tag()));
-  }
 
   const MapEntry *ME;
 };
@@ -199,26 +191,14 @@ template <> struct 
PointerLikeTypeTraits<clang::DirectoryEntryRef> {
 
 /// Specialisation of DenseMapInfo for DirectoryEntryRef.
 template <> struct DenseMapInfo<clang::DirectoryEntryRef> {
-  static inline clang::DirectoryEntryRef getEmptyKey() {
-    return clang::DirectoryEntryRef(
-        clang::DirectoryEntryRef::dense_map_empty_tag());
-  }
-
   static unsigned getHashValue(clang::DirectoryEntryRef Val) {
     return hash_value(Val);
   }
 
   static bool isEqual(clang::DirectoryEntryRef LHS,
                       clang::DirectoryEntryRef RHS) {
-    // Catch the easy cases: both empty or the same ref.
     if (LHS.isSameRef(RHS))
       return true;
-
-    // Confirm LHS and RHS are valid.
-    if (LHS.isSpecialDenseMapKey() || RHS.isSpecialDenseMapKey())
-      return false;
-
-    // It's safe to use operator==.
     return LHS == RHS;
   }
 };
diff --git a/clang/include/clang/Basic/FileEntry.h 
b/clang/include/clang/Basic/FileEntry.h
index 481ef32d7d27d..b22b6c00bb6ce 100644
--- a/clang/include/clang/Basic/FileEntry.h
+++ b/clang/include/clang/Basic/FileEntry.h
@@ -183,14 +183,6 @@ class FileEntryRef {
   bool hasOptionalValue() const { return ME; }
 
   friend struct llvm::DenseMapInfo<FileEntryRef>;
-  struct dense_map_empty_tag {};
-
-  // Private constructor for use by DenseMapInfo.
-  FileEntryRef(dense_map_empty_tag)
-      : ME(llvm::DenseMapInfo<const MapEntry *>::getEmptyKey()) {}
-  bool isSpecialDenseMapKey() const {
-    return isSameRef(FileEntryRef(dense_map_empty_tag()));
-  }
 
   const MapEntry *ME;
 };
@@ -235,24 +227,13 @@ namespace llvm {
 
 /// Specialisation of DenseMapInfo for FileEntryRef.
 template <> struct DenseMapInfo<clang::FileEntryRef> {
-  static inline clang::FileEntryRef getEmptyKey() {
-    return clang::FileEntryRef(clang::FileEntryRef::dense_map_empty_tag());
-  }
-
   static unsigned getHashValue(clang::FileEntryRef Val) {
     return hash_value(Val);
   }
 
   static bool isEqual(clang::FileEntryRef LHS, clang::FileEntryRef RHS) {
-    // Catch the easy cases: both empty or the same ref.
     if (LHS.isSameRef(RHS))
       return true;
-
-    // Confirm LHS and RHS are valid.
-    if (LHS.isSpecialDenseMapKey() || RHS.isSpecialDenseMapKey())
-      return false;
-
-    // It's safe to use operator==.
     return LHS == RHS;
   }
 
@@ -262,8 +243,6 @@ template <> struct DenseMapInfo<clang::FileEntryRef> {
     return llvm::hash_value(Val);
   }
   static bool isEqual(const clang::FileEntry *LHS, clang::FileEntryRef RHS) {
-    if (RHS.isSpecialDenseMapKey())
-      return false;
     return LHS == RHS;
   }
   /// @}
diff --git a/clang/include/clang/Basic/IdentifierTable.h 
b/clang/include/clang/Basic/IdentifierTable.h
index 41420ece94bf4..ebb5015bb4ef7 100644
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ b/clang/include/clang/Basic/IdentifierTable.h
@@ -1269,10 +1269,6 @@ namespace llvm {
 /// DenseSets.
 template <>
 struct DenseMapInfo<clang::Selector> {
-  static clang::Selector getEmptyKey() {
-    return clang::Selector::getEmptyMarker();
-  }
-
   static unsigned getHashValue(clang::Selector S);
 
   static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
diff --git a/clang/include/clang/Basic/Module.h 
b/clang/include/clang/Basic/Module.h
index c239f02dc6867..453ad2b7e7600 100644
--- a/clang/include/clang/Basic/Module.h
+++ b/clang/include/clang/Basic/Module.h
@@ -1156,10 +1156,6 @@ class VisibleModuleSet {
 } // namespace clang
 
 template <> struct llvm::DenseMapInfo<clang::ModuleFileKey> {
-  static clang::ModuleFileKey getEmptyKey() {
-    return DenseMapInfo<const void *>::getEmptyKey();
-  }
-
   static unsigned getHashValue(const clang::ModuleFileKey &Val) {
     return hash_combine(Val.Ptr, Val.ImplicitModulePathSuffix);
   }
diff --git a/clang/include/clang/Basic/SourceLocation.h 
b/clang/include/clang/Basic/SourceLocation.h
index 37ed9a3bd4f40..b42b7e78622c6 100644
--- a/clang/include/clang/Basic/SourceLocation.h
+++ b/clang/include/clang/Basic/SourceLocation.h
@@ -494,10 +494,6 @@ namespace llvm {
   /// DenseSets.
   template <>
   struct DenseMapInfo<clang::FileID, void> {
-    static clang::FileID getEmptyKey() {
-      return {};
-    }
-
     static unsigned getHashValue(clang::FileID S) {
       return S.getHashValue();
     }
@@ -511,11 +507,6 @@ namespace llvm {
   /// 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, void> {
-    static clang::SourceLocation getEmptyKey() {
-      constexpr clang::SourceLocation::UIntTy Zero = 0;
-      return clang::SourceLocation::getFromRawEncoding(~Zero);
-    }
-
     static unsigned getHashValue(clang::SourceLocation Loc) {
       return Loc.getHashValue();
     }
@@ -531,10 +522,6 @@ namespace llvm {
   };
 
   template <> struct DenseMapInfo<clang::SourceRange> {
-    static clang::SourceRange getEmptyKey() {
-      return DenseMapInfo<clang::SourceLocation>::getEmptyKey();
-    }
-
     static unsigned getHashValue(clang::SourceRange Range) {
       return detail::combineHashValue(Range.getBegin().getHashValue(),
                                       Range.getEnd().getHashValue());
diff --git a/clang/include/clang/Basic/TokenKinds.h 
b/clang/include/clang/Basic/TokenKinds.h
index 37181b9533422..e5e7efb4d4387 100644
--- a/clang/include/clang/Basic/TokenKinds.h
+++ b/clang/include/clang/Basic/TokenKinds.h
@@ -133,9 +133,6 @@ inline constexpr bool isRegularKeywordAttribute(TokenKind 
K) {
 
 namespace llvm {
 template <> struct DenseMapInfo<clang::tok::PPKeywordKind> {
-  static inline clang::tok::PPKeywordKind getEmptyKey() {
-    return clang::tok::PPKeywordKind::pp_not_keyword;
-  }
   static unsigned getHashValue(const clang::tok::PPKeywordKind &Val) {
     return static_cast<unsigned>(Val);
   }
diff --git a/clang/include/clang/DependencyScanning/DependencyGraph.h 
b/clang/include/clang/DependencyScanning/DependencyGraph.h
index 331fe5d6fbb3b..aea33c78b0436 100644
--- a/clang/include/clang/DependencyScanning/DependencyGraph.h
+++ b/clang/include/clang/DependencyScanning/DependencyGraph.h
@@ -206,7 +206,6 @@ inline hash_code hash_value(const 
clang::dependencies::ModuleID &ID) {
 
 template <> struct DenseMapInfo<clang::dependencies::ModuleID> {
   using ModuleID = clang::dependencies::ModuleID;
-  static inline ModuleID getEmptyKey() { return ModuleID{"", ""}; }
   static unsigned getHashValue(const ModuleID &ID) { return hash_value(ID); }
   static bool isEqual(const ModuleID &LHS, const ModuleID &RHS) {
     return LHS == RHS;
diff --git a/clang/include/clang/Sema/ScopeInfo.h 
b/clang/include/clang/Sema/ScopeInfo.h
index 3545f9ce1e4aa..7e4d3f2e0d1cb 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -328,10 +328,6 @@ class FunctionScopeInfo {
     // instantiated.
     class DenseMapInfo {
     public:
-      static inline WeakObjectProfileTy getEmptyKey() {
-        return WeakObjectProfileTy();
-      }
-
       static unsigned getHashValue(const WeakObjectProfileTy &Val) {
         using Pair = std::pair<BaseInfoTy, const NamedDecl *>;
 
diff --git a/clang/include/clang/Sema/SemaCUDA.h 
b/clang/include/clang/Sema/SemaCUDA.h
index 43ac11be44bb5..bf990f21e7b63 100644
--- a/clang/include/clang/Sema/SemaCUDA.h
+++ b/clang/include/clang/Sema/SemaCUDA.h
@@ -304,10 +304,6 @@ template <> struct 
DenseMapInfo<clang::SemaCUDA::FunctionDeclAndLoc> {
   using FDBaseInfo =
       DenseMapInfo<clang::CanonicalDeclPtr<const clang::FunctionDecl>>;
 
-  static FunctionDeclAndLoc getEmptyKey() {
-    return {FDBaseInfo::getEmptyKey(), clang::SourceLocation()};
-  }
-
   static unsigned getHashValue(const FunctionDeclAndLoc &FDL) {
     return hash_combine(FDBaseInfo::getHashValue(FDL.FD),
                         FDL.Loc.getHashValue());
diff --git a/clang/include/clang/Sema/Weak.h b/clang/include/clang/Sema/Weak.h
index 8608d574184a4..60341086abf61 100644
--- a/clang/include/clang/Sema/Weak.h
+++ b/clang/include/clang/Sema/Weak.h
@@ -36,9 +36,6 @@ class WeakInfo {
 
   struct DenseMapInfoByAliasOnly
       : private llvm::DenseMapInfo<const IdentifierInfo *> {
-    static inline WeakInfo getEmptyKey() {
-      return WeakInfo(DenseMapInfo::getEmptyKey(), SourceLocation());
-    }
     static unsigned getHashValue(const WeakInfo &W) {
       return DenseMapInfo::getHashValue(W.getAlias());
     }
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h 
b/clang/include/clang/Serialization/ASTBitCodes.h
index 412f87e9da43e..279380de2f7fe 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -134,10 +134,6 @@ static_assert(alignof(TypeIdx) == 4);
 struct UnsafeQualTypeDenseMapInfo {
   static bool isEqual(QualType A, QualType B) { return A == B; }
 
-  static QualType getEmptyKey() {
-    return QualType::getFromOpaquePtr((void *)1);
-  }
-
   static unsigned getHashValue(QualType T) {
     assert(!T.getLocalFastQualifiers() &&
            "hash invalid for types with fast quals");
@@ -2210,10 +2206,6 @@ class DeclarationNameKey {
 namespace llvm {
 
 template <> struct DenseMapInfo<clang::serialization::DeclarationNameKey> {
-  static clang::serialization::DeclarationNameKey getEmptyKey() {
-    return clang::serialization::DeclarationNameKey(-1, 1);
-  }
-
   static unsigned
   getHashValue(const clang::serialization::DeclarationNameKey &Key) {
     return Key.getHash();
diff --git a/clang/include/clang/Tooling/Inclusions/StandardLibrary.h 
b/clang/include/clang/Tooling/Inclusions/StandardLibrary.h
index 66cbe0d49b5f6..7ae07c545f784 100644
--- a/clang/include/clang/Tooling/Inclusions/StandardLibrary.h
+++ b/clang/include/clang/Tooling/Inclusions/StandardLibrary.h
@@ -120,10 +120,6 @@ class Recognizer {
 namespace llvm {
 
 template <> struct DenseMapInfo<clang::tooling::stdlib::Header> {
-  static inline clang::tooling::stdlib::Header getEmptyKey() {
-    return clang::tooling::stdlib::Header(-1,
-                                          clang::tooling::stdlib::Lang::CXX);
-  }
   static unsigned getHashValue(const clang::tooling::stdlib::Header &H) {
     return hash_value(H.ID);
   }
@@ -134,10 +130,6 @@ template <> struct 
DenseMapInfo<clang::tooling::stdlib::Header> {
 };
 
 template <> struct DenseMapInfo<clang::tooling::stdlib::Symbol> {
-  static inline clang::tooling::stdlib::Symbol getEmptyKey() {
-    return clang::tooling::stdlib::Symbol(-1,
-                                          clang::tooling::stdlib::Lang::CXX);
-  }
   static unsigned getHashValue(const clang::tooling::stdlib::Symbol &S) {
     return hash_value(S.ID);
   }
diff --git a/clang/lib/APINotes/APINotesFormat.h 
b/clang/lib/APINotes/APINotesFormat.h
index 7f99fb92e6cbd..5679ae39e9900 100644
--- a/clang/lib/APINotes/APINotesFormat.h
+++ b/clang/lib/APINotes/APINotesFormat.h
@@ -361,11 +361,6 @@ namespace llvm {
 template <> struct DenseMapInfo<clang::api_notes::StoredObjCSelector> {
   typedef DenseMapInfo<unsigned> UnsignedInfo;
 
-  static inline clang::api_notes::StoredObjCSelector getEmptyKey() {
-    return clang::api_notes::StoredObjCSelector{UnsignedInfo::getEmptyKey(),
-                                                {}};
-  }
-
   static unsigned
   getHashValue(const clang::api_notes::StoredObjCSelector &Selector) {
     auto hash = llvm::hash_value(Selector.NumArgs);
@@ -384,10 +379,6 @@ template <> struct 
DenseMapInfo<clang::api_notes::StoredObjCSelector> {
 };
 
 template <> struct DenseMapInfo<clang::api_notes::ContextTableKey> {
-  static inline clang::api_notes::ContextTableKey getEmptyKey() {
-    return clang::api_notes::ContextTableKey();
-  }
-
   static unsigned getHashValue(const clang::api_notes::ContextTableKey &value) 
{
     return value.hashValue();
   }
@@ -399,10 +390,6 @@ template <> struct 
DenseMapInfo<clang::api_notes::ContextTableKey> {
 };
 
 template <> struct DenseMapInfo<clang::api_notes::SingleDeclTableKey> {
-  static inline clang::api_notes::SingleDeclTableKey getEmptyKey() {
-    return clang::api_notes::SingleDeclTableKey();
-  }
-
   static unsigned
   getHashValue(const clang::api_notes::SingleDeclTableKey &value) {
     return value.hashValue();
diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index 91689a4961a1f..fd51584f564bb 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -184,13 +184,6 @@ APValue::LValueBase::operator bool () const {
   return static_cast<bool>(Ptr);
 }
 
-clang::APValue::LValueBase
-llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
-  clang::APValue::LValueBase B;
-  B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey();
-  return B;
-}
-
 namespace clang {
 llvm::hash_code hash_value(const APValue::LValueBase &Base) {
   if (Base.is<TypeInfoLValue>() || Base.is<DynamicAllocLValue>())
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index c774a02440274..33df4cab06e7c 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -733,9 +733,6 @@ namespace {
 namespace llvm {
 template<> struct DenseMapInfo<ObjectUnderConstruction> {
   using Base = DenseMapInfo<APValue::LValueBase>;
-  static ObjectUnderConstruction getEmptyKey() {
-    return {Base::getEmptyKey(), {}};
-  }
   static unsigned getHashValue(const ObjectUnderConstruction &Object) {
     return hash_value(Object);
   }
diff --git a/clang/lib/AST/ItaniumCXXABI.cpp b/clang/lib/AST/ItaniumCXXABI.cpp
index 89fd536d32af2..57378978c4a70 100644
--- a/clang/lib/AST/ItaniumCXXABI.cpp
+++ b/clang/lib/AST/ItaniumCXXABI.cpp
@@ -74,35 +74,13 @@ struct DecompositionDeclName {
 }
 
 namespace llvm {
-template <typename T> static bool isDenseMapKeyEmpty(T V) {
-  return llvm::DenseMapInfo<T>::isEqual(
-      V, llvm::DenseMapInfo<T>::getEmptyKey());
-}
-template <typename T>
-static std::optional<bool> areDenseMapKeysEqualSpecialValues(T LHS, T RHS) {
-  bool LHSEmpty = isDenseMapKeyEmpty(LHS);
-  bool RHSEmpty = isDenseMapKeyEmpty(RHS);
-  if (LHSEmpty || RHSEmpty)
-    return LHSEmpty && RHSEmpty;
-
-  return std::nullopt;
-}
-
 template<>
 struct DenseMapInfo<DecompositionDeclName> {
   using ArrayInfo = llvm::DenseMapInfo<ArrayRef<const BindingDecl*>>;
-  static DecompositionDeclName getEmptyKey() {
-    return {ArrayInfo::getEmptyKey()};
-  }
   static unsigned getHashValue(DecompositionDeclName Key) {
-    assert(!isEqual(Key, getEmptyKey()));
     return llvm::hash_combine_range(Key);
   }
   static bool isEqual(DecompositionDeclName LHS, DecompositionDeclName RHS) {
-    if (std::optional<bool> Result =
-            areDenseMapKeysEqualSpecialValues(LHS.Bindings, RHS.Bindings))
-      return *Result;
-
     return LHS.Bindings.size() == RHS.Bindings.size() &&
            std::equal(LHS.begin(), LHS.end(), RHS.begin());
   }
diff --git a/clang/lib/CodeGen/CGObjCMacConstantLiteralUtil.h 
b/clang/lib/CodeGen/CGObjCMacConstantLiteralUtil.h
index 27b4ef8ca6c16..438d2fe9fa474 100644
--- a/clang/lib/CodeGen/CGObjCMacConstantLiteralUtil.h
+++ b/clang/lib/CodeGen/CGObjCMacConstantLiteralUtil.h
@@ -66,10 +66,6 @@ class NSConstantNumberMapInfo {
         (unsigned)Float.bitcastToAPInt().getZExtValue(), QTypeHash);
   }
 
-  static inline NSConstantNumberMapInfo getEmptyKey() {
-    return NSConstantNumberMapInfo();
-  }
-
   bool operator==(const NSConstantNumberMapInfo &RHS) const {
     if (InfoType != RHS.InfoType || QType != RHS.QType)
       return false;
@@ -159,10 +155,6 @@ namespace llvm {
 using namespace clang::CodeGen::CGObjCMacConstantLiteralUtil;
 
 template <> struct DenseMapInfo<NSConstantNumberMapInfo> {
-  static NSConstantNumberMapInfo getEmptyKey() {
-    return NSConstantNumberMapInfo::getEmptyKey();
-  }
-
   static unsigned getHashValue(const NSConstantNumberMapInfo &S) {
     return S.getHashValue();
   }
diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h
index f3345274c8f55..737bb6943224f 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.h
+++ b/clang/lib/CodeGen/CodeGenTBAA.h
@@ -228,16 +228,6 @@ class CodeGenTBAA {
 namespace llvm {
 
 template<> struct DenseMapInfo<clang::CodeGen::TBAAAccessInfo> {
-  static clang::CodeGen::TBAAAccessInfo getEmptyKey() {
-    unsigned UnsignedKey = DenseMapInfo<unsigned>::getEmptyKey();
-    return clang::CodeGen::TBAAAccessInfo(
-      static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey),
-      DenseMapInfo<MDNode *>::getEmptyKey(),
-      DenseMapInfo<MDNode *>::getEmptyKey(),
-      DenseMapInfo<uint64_t>::getEmptyKey(),
-      DenseMapInfo<uint64_t>::getEmptyKey());
-  }
-
   static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) {
     auto KindValue = static_cast<unsigned>(Val.Kind);
     return DenseMapInfo<unsigned>::getHashValue(KindValue) ^
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 98f88b49aa67d..4449ea11d3ee6 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -4278,11 +4278,7 @@ class CatchHandlerType {
   LLVM_PREFERRED_TYPE(bool)
   unsigned IsPointer : 1;
 
-  // This is a special constructor to be used only with DenseMapInfo's
-  // getEmptyKey() function.
   friend struct llvm::DenseMapInfo<CatchHandlerType>;
-  enum Unique { ForDenseMap };
-  CatchHandlerType(QualType QT, Unique) : QT(QT), IsPointer(false) {}
 
 public:
   /// Used when creating a CatchHandlerType from a handler type; will determine
@@ -4319,11 +4315,6 @@ class CatchHandlerType {
 
 namespace llvm {
 template <> struct DenseMapInfo<CatchHandlerType> {
-  static CatchHandlerType getEmptyKey() {
-    return CatchHandlerType(DenseMapInfo<QualType>::getEmptyKey(),
-                       CatchHandlerType::ForDenseMap);
-  }
-
   static unsigned getHashValue(const CatchHandlerType &Base) {
     return DenseMapInfo<QualType>::getHashValue(Base.underlying());
   }
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp 
b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index c3ea0f41f3b78..2338c06d5f992 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -1238,10 +1238,6 @@ template <> struct DenseMapInfo<PrivateMethodKey> {
   using InterfaceInfo = DenseMapInfo<const ObjCInterfaceDecl *>;
   using SelectorInfo = DenseMapInfo<Selector>;
 
-  static inline PrivateMethodKey getEmptyKey() {
-    return {InterfaceInfo::getEmptyKey(), SelectorInfo::getEmptyKey(), false};
-  }
-
   static unsigned getHashValue(const PrivateMethodKey &Key) {
     return llvm::hash_combine(
         llvm::hash_code(InterfaceInfo::getHashValue(Key.Interface)),
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp 
b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index a57f4a50605b0..6e4fc7060389c 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -142,7 +142,6 @@ using OffloadingImage = OffloadBinary::OffloadingImage;
 namespace llvm {
 // Provide DenseMapInfo so that OffloadKind can be used in a DenseMap.
 template <> struct DenseMapInfo<OffloadKind> {
-  static inline OffloadKind getEmptyKey() { return OFK_LAST; }
   static unsigned getHashValue(const OffloadKind &Val) { return Val; }
 
   static bool isEqual(const OffloadKind &LHS, const OffloadKind &RHS) {
diff --git a/clang/tools/libclang/CXCursor.cpp 
b/clang/tools/libclang/CXCursor.cpp
index d513f9f4cf97b..b2feed578fc0f 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -1622,9 +1622,6 @@ static inline CXCursorSet_Impl 
*unpackCXCursorSet(CXCursorSet set) {
 namespace llvm {
 template <> struct DenseMapInfo<CXCursor> {
 public:
-  static inline CXCursor getEmptyKey() {
-    return MakeCXCursorInvalid(CXCursor_InvalidFile);
-  }
   static inline unsigned getHashValue(const CXCursor &cursor) {
     return llvm::DenseMapInfo<std::pair<const void *, const void *>>::
         getHashValue(std::make_pair(cursor.data[0], cursor.data[1]));
diff --git a/clang/tools/libclang/Indexing.cpp 
b/clang/tools/libclang/Indexing.cpp
index 5783bd0125462..fc8e383faeac8 100644
--- a/clang/tools/libclang/Indexing.cpp
+++ b/clang/tools/libclang/Indexing.cpp
@@ -96,10 +96,6 @@ namespace llvm {
 
   template <>
   struct DenseMapInfo<PPRegion> {
-    static inline PPRegion getEmptyKey() {
-      return PPRegion(llvm::sys::fs::UniqueID(0, 0), unsigned(-1), 0);
-    }
-
     static unsigned getHashValue(const PPRegion &S) {
       llvm::FoldingSetNodeID ID;
       const llvm::sys::fs::UniqueID &UniqueID = S.getUniqueID();

>From f39ea0d244ea9214e4669cb070a9dcd777170e00 Mon Sep 17 00:00:00 2001
From: Fangrui Song <[email protected]>
Date: Sat, 6 Jun 2026 11:49:51 -0700
Subject: [PATCH 2/2] Rebase onto main; remove dead empty-key helpers per
 review

---
 clang-tools-extra/clangd/SystemIncludeExtractor.cpp    |  2 --
 clang-tools-extra/clangd/index/dex/Token.h             |  3 +--
 clang-tools-extra/clangd/index/dex/Trigram.h           |  3 ---
 .../include/clang-include-cleaner/Types.h              | 10 ----------
 clang/include/clang/AST/DeclarationName.h              |  6 ------
 clang/include/clang/Basic/IdentifierTable.h            |  4 ----
 6 files changed, 1 insertion(+), 27 deletions(-)

diff --git a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp 
b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
index b4dbc1df1d636..22237863ff041 100644
--- a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
+++ b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
@@ -207,8 +207,6 @@ struct DriverArgs {
     return Args;
   }
 
-  static DriverArgs getEmpty() { return {}; }
-
 private:
   DriverArgs() = default;
 };
diff --git a/clang-tools-extra/clangd/index/dex/Token.h 
b/clang-tools-extra/clangd/index/dex/Token.h
index 98a504c4c3fa2..8e654940abe36 100644
--- a/clang-tools-extra/clangd/index/dex/Token.h
+++ b/clang-tools-extra/clangd/index/dex/Token.h
@@ -64,8 +64,7 @@ class Token {
     ProximityURI,
     /// Type of symbol (see `Symbol::Type`).
     Type,
-    /// Internal Token type for invalid/special tokens, e.g. empty tokens for
-    /// llvm::DenseMap.
+    /// Internal Token type for invalid/special tokens.
     Sentinel,
   };
 
diff --git a/clang-tools-extra/clangd/index/dex/Trigram.h 
b/clang-tools-extra/clangd/index/dex/Trigram.h
index bad3c4378598f..14cbd329cc280 100644
--- a/clang-tools-extra/clangd/index/dex/Trigram.h
+++ b/clang-tools-extra/clangd/index/dex/Trigram.h
@@ -37,9 +37,6 @@ namespace dex {
 // Trigram generation is the hot path of indexing, so Token is too wasteful.
 class Trigram {
   std::array<char, 4> Data; // Last element is length.
-  // Steal an invalid bit pattern for the DenseMap sentinel.
-  enum class Sentinel { Empty = 4 };
-  Trigram(Sentinel S) : Data{0, 0, 0, static_cast<char>(S)} {}
   uint32_t id() const { return llvm::bit_cast<uint32_t>(Data); }
 
 public:
diff --git 
a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h 
b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
index 341cf1851142b..3158cb91f3b7c 100644
--- a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
+++ b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
@@ -78,11 +78,6 @@ struct Symbol {
   // Order must match Kind enum!
   std::variant<const Decl *, struct Macro> Storage;
 
-  // Disambiguation tag to make sure we can call the right constructor from
-  // DenseMapInfo methods.
-  struct SentinelTag {};
-  Symbol(SentinelTag, decltype(Storage) Sentinel)
-      : Storage(std::move(Sentinel)) {}
   friend llvm::DenseMapInfo<Symbol>;
 };
 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Symbol &);
@@ -144,11 +139,6 @@ struct Header {
   // Order must match Kind enum!
   std::variant<FileEntryRef, tooling::stdlib::Header, StringRef> Storage;
 
-  // Disambiguation tag to make sure we can call the right constructor from
-  // DenseMapInfo methods.
-  struct SentinelTag {};
-  Header(SentinelTag, decltype(Storage) Sentinel)
-      : Storage(std::move(Sentinel)) {}
   friend llvm::DenseMapInfo<Header>;
 };
 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Header &);
diff --git a/clang/include/clang/AST/DeclarationName.h 
b/clang/include/clang/AST/DeclarationName.h
index 3a272c506ca8d..5121b561288c0 100644
--- a/clang/include/clang/AST/DeclarationName.h
+++ b/clang/include/clang/AST/DeclarationName.h
@@ -552,12 +552,6 @@ class DeclarationName {
     return LHS.Ptr != RHS.Ptr;
   }
 
-  static DeclarationName getEmptyMarker() {
-    DeclarationName Name;
-    Name.Ptr = uintptr_t(-1);
-    return Name;
-  }
-
   static int compare(DeclarationName LHS, DeclarationName RHS);
 
   void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
diff --git a/clang/include/clang/Basic/IdentifierTable.h 
b/clang/include/clang/Basic/IdentifierTable.h
index ebb5015bb4ef7..9e80c3fb7079d 100644
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ b/clang/include/clang/Basic/IdentifierTable.h
@@ -1185,10 +1185,6 @@ class Selector {
     return getStringFormatFamilyImpl(*this);
   }
 
-  static Selector getEmptyMarker() {
-    return Selector(uintptr_t(-1));
-  }
-
   static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel);
 };
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to