[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 (MatchedTemplateLocations.count(
ReplacementRange.getBegin().getRawEncoding()) == 0) {
if (MatchedTemplateLocations.count(ReplacementRange.getBegin()) == 0) {
// For each location matched in a template instantiation, we check if
// the location can also be found in `MatchedTemplateLocations`. If it
// 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) {
// We gather source locations from template matches not in template
// instantiations for future matches.
MatchedTemplateLocations.insert(
ReplacementRange.getBegin().getRawEncoding());
MatchedTemplateLocations.insert(ReplacementRange.getBegin());
}
if (!AddFix) {

View File

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

View File

@ -175,6 +175,7 @@ public:
End.isFileID();
}
unsigned getHashValue() const;
void print(raw_ostream &OS, const SourceManager &SM) const;
std::string printToString(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.
template<>
struct PointerLikeTypeTraits<clang::SourceLocation> {

View File

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