142 lines
3.9 KiB
C++
142 lines
3.9 KiB
C++
//===- llvm/CAS/CASID.h -----------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CAS_CASID_H
|
|
#define LLVM_CAS_CASID_H
|
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/DenseMapInfo.h"
|
|
#include "llvm/ADT/SmallString.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/Error.h"
|
|
|
|
namespace llvm {
|
|
|
|
class raw_ostream;
|
|
|
|
namespace cas {
|
|
|
|
class CASID;
|
|
|
|
/// Context for CAS identifiers.
|
|
class LLVM_ABI CASContext {
|
|
virtual void anchor();
|
|
|
|
public:
|
|
virtual ~CASContext() = default;
|
|
|
|
/// Get an identifer for the schema used by this CAS context. Two CAS
|
|
/// instances should return \c true for this identifier if and only if their
|
|
/// CASIDs are safe to compare by hash. This is used by \a
|
|
/// CASID::equalsImpl().
|
|
virtual StringRef getHashSchemaIdentifier() const = 0;
|
|
|
|
protected:
|
|
/// Print \p ID to \p OS.
|
|
virtual void printIDImpl(raw_ostream &OS, const CASID &ID) const = 0;
|
|
|
|
friend class CASID;
|
|
};
|
|
|
|
/// Unique identifier for a CAS object.
|
|
///
|
|
/// Locally, stores an internal CAS identifier that's specific to a single CAS
|
|
/// instance. It's guaranteed not to change across the view of that CAS, but
|
|
/// might change between runs.
|
|
///
|
|
/// It also has \a CASIDContext pointer to allow comparison of these
|
|
/// identifiers. If two CASIDs are from the same CASIDContext, they can be
|
|
/// compared directly. If they are, then \a
|
|
/// CASIDContext::getHashSchemaIdentifier() is compared to see if they can be
|
|
/// compared by hash, in which case the result of \a getHash() is compared.
|
|
class CASID {
|
|
public:
|
|
LLVM_ABI void dump() const;
|
|
|
|
friend raw_ostream &operator<<(raw_ostream &OS, const CASID &ID) {
|
|
ID.print(OS);
|
|
return OS;
|
|
}
|
|
|
|
/// Print CASID.
|
|
void print(raw_ostream &OS) const {
|
|
return getContext().printIDImpl(OS, *this);
|
|
}
|
|
|
|
/// Return a printable string for CASID.
|
|
LLVM_ABI std::string toString() const;
|
|
|
|
ArrayRef<uint8_t> getHash() const {
|
|
return arrayRefFromStringRef<uint8_t>(Hash);
|
|
}
|
|
|
|
friend bool operator==(const CASID &LHS, const CASID &RHS) {
|
|
if (LHS.Context == RHS.Context)
|
|
return LHS.Hash == RHS.Hash;
|
|
|
|
// TombstoneKey.
|
|
if (!LHS.Context || !RHS.Context)
|
|
return false;
|
|
|
|
// CASIDs are equal when they have the same hash schema and same hash value.
|
|
return LHS.Context->getHashSchemaIdentifier() ==
|
|
RHS.Context->getHashSchemaIdentifier() &&
|
|
LHS.Hash == RHS.Hash;
|
|
}
|
|
|
|
friend bool operator!=(const CASID &LHS, const CASID &RHS) {
|
|
return !(LHS == RHS);
|
|
}
|
|
|
|
friend hash_code hash_value(const CASID &ID) {
|
|
return hash_combine_range(ID.getHash());
|
|
}
|
|
|
|
const CASContext &getContext() const {
|
|
assert(Context && "Tombstone key for DenseMap?");
|
|
return *Context;
|
|
}
|
|
|
|
static CASID getDenseMapTombstoneKey() {
|
|
// A reserved StringRef value distinct from the empty key, used only as a
|
|
// DenseMap sentinel for CASID.
|
|
return CASID(nullptr, StringRef(reinterpret_cast<const char *>(
|
|
~static_cast<uintptr_t>(1)),
|
|
0));
|
|
}
|
|
|
|
CASID() = delete;
|
|
|
|
/// Create CASID from CASContext and raw hash bytes.
|
|
static CASID create(const CASContext *Context, StringRef Hash) {
|
|
return CASID(Context, Hash);
|
|
}
|
|
|
|
private:
|
|
CASID(const CASContext *Context, StringRef Hash)
|
|
: Context(Context), Hash(Hash) {}
|
|
|
|
const CASContext *Context;
|
|
SmallString<32> Hash;
|
|
};
|
|
|
|
} // namespace cas
|
|
|
|
template <> struct DenseMapInfo<cas::CASID> {
|
|
static unsigned getHashValue(cas::CASID ID) {
|
|
return (unsigned)hash_value(ID);
|
|
}
|
|
|
|
static bool isEqual(cas::CASID LHS, cas::CASID RHS) { return LHS == RHS; }
|
|
};
|
|
|
|
} // namespace llvm
|
|
|
|
#endif // LLVM_CAS_CASID_H
|