[clang][Basic] Make SourceLocation usable as key in hash maps, NFCI

This change creates a `DenseMapInfo` trait specialization for the
SourceLocation class. The empty key, the tombstone key, and the hash
function are identical to `DenseMapInfo<unsigned>`, because we already
have hash maps that use raw the representation of `SourceLocation` as
a key.

The update of existing `DenseMap`s containing raw representation of
`SourceLocation`s will be done in a follow-up patch. As an example
the patch makes use of the new trait in one instance:
clang-tidy/google/UpgradeGoogletestCaseCheck.{h,cpp}

Reviewed By: dexonsmith

Differential Revision: https://reviews.llvm.org/D89719
This commit is contained in:
Mikhail Maltsev 2020-10-20 15:52:59 +01:00
parent eaa928b71a
commit 234c47ae2a
4 changed files with 30 additions and 5 deletions

View File

@ -298,8 +298,7 @@ void UpgradeGoogletestCaseCheck::check(const MatchFinder::MatchResult &Result) {
} }
if (IsInInstantiation) { if (IsInInstantiation) {
if (MatchedTemplateLocations.count( if (MatchedTemplateLocations.count(ReplacementRange.getBegin()) == 0) {
ReplacementRange.getBegin().getRawEncoding()) == 0) {
// For each location matched in a template instantiation, we check if // For each location matched in a template instantiation, we check if
// the location can also be found in `MatchedTemplateLocations`. If it // the location can also be found in `MatchedTemplateLocations`. If it
// is not found, that means the expression did not create a match // is not found, that means the expression did not create a match
@ -313,8 +312,7 @@ void UpgradeGoogletestCaseCheck::check(const MatchFinder::MatchResult &Result) {
if (IsInTemplate) { if (IsInTemplate) {
// We gather source locations from template matches not in template // We gather source locations from template matches not in template
// instantiations for future matches. // instantiations for future matches.
MatchedTemplateLocations.insert( MatchedTemplateLocations.insert(ReplacementRange.getBegin());
ReplacementRange.getBegin().getRawEncoding());
} }
if (!AddFix) { if (!AddFix) {

View File

@ -33,7 +33,7 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private: private:
llvm::DenseSet<unsigned> MatchedTemplateLocations; llvm::DenseSet<SourceLocation> MatchedTemplateLocations;
}; };
} // namespace google } // namespace google

View File

@ -175,6 +175,7 @@ public:
End.isFileID(); End.isFileID();
} }
unsigned getHashValue() const;
void print(raw_ostream &OS, const SourceManager &SM) const; void print(raw_ostream &OS, const SourceManager &SM) const;
std::string printToString(const SourceManager &SM) const; std::string printToString(const SourceManager &SM) const;
void dump(const SourceManager &SM) const; void dump(const SourceManager &SM) const;
@ -479,6 +480,27 @@ namespace llvm {
} }
}; };
/// 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() {
return clang::SourceLocation::getFromRawEncoding(~0U);
}
static clang::SourceLocation getTombstoneKey() {
return clang::SourceLocation::getFromRawEncoding(~0U - 1);
}
static unsigned getHashValue(clang::SourceLocation Loc) {
return Loc.getHashValue();
}
static bool isEqual(clang::SourceLocation LHS, clang::SourceLocation RHS) {
return LHS == RHS;
}
};
// Teach SmallPtrSet how to handle SourceLocation. // Teach SmallPtrSet how to handle SourceLocation.
template<> template<>
struct PointerLikeTypeTraits<clang::SourceLocation> { struct PointerLikeTypeTraits<clang::SourceLocation> {

View File

@ -14,6 +14,7 @@
#include "clang/Basic/LLVM.h" #include "clang/Basic/LLVM.h"
#include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/PrettyStackTrace.h"
#include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManager.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
@ -40,6 +41,10 @@ void PrettyStackTraceLoc::print(raw_ostream &OS) const {
// SourceLocation // SourceLocation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
unsigned SourceLocation::getHashValue() const {
return llvm::DenseMapInfo<unsigned>::getHashValue(ID);
}
void SourceLocation::print(raw_ostream &OS, const SourceManager &SM)const{ void SourceLocation::print(raw_ostream &OS, const SourceManager &SM)const{
if (!isValid()) { if (!isValid()) {
OS << "<invalid loc>"; OS << "<invalid loc>";