File indexing completed on 2026-05-10 08:36:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_BASIC_DIRECTORYENTRY_H
0015 #define LLVM_CLANG_BASIC_DIRECTORYENTRY_H
0016
0017 #include "clang/Basic/CustomizableOptional.h"
0018 #include "clang/Basic/LLVM.h"
0019 #include "llvm/ADT/DenseMapInfo.h"
0020 #include "llvm/ADT/Hashing.h"
0021 #include "llvm/ADT/STLExtras.h"
0022 #include "llvm/ADT/StringMap.h"
0023 #include "llvm/ADT/StringRef.h"
0024 #include "llvm/Support/ErrorOr.h"
0025
0026 #include <optional>
0027 #include <utility>
0028
0029 namespace clang {
0030 namespace FileMgr {
0031
0032 template <class RefTy> class MapEntryOptionalStorage;
0033
0034 }
0035
0036
0037
0038 class DirectoryEntry {
0039 DirectoryEntry() = default;
0040 DirectoryEntry(const DirectoryEntry &) = delete;
0041 DirectoryEntry &operator=(const DirectoryEntry &) = delete;
0042 friend class FileManager;
0043 friend class FileEntryTestHelper;
0044 };
0045
0046
0047
0048 class DirectoryEntryRef {
0049 public:
0050 const DirectoryEntry &getDirEntry() const { return *ME->getValue(); }
0051
0052 StringRef getName() const { return ME->getKey(); }
0053
0054
0055
0056 friend llvm::hash_code hash_value(DirectoryEntryRef Ref) {
0057 return llvm::hash_value(&Ref.getDirEntry());
0058 }
0059
0060 using MapEntry = llvm::StringMapEntry<llvm::ErrorOr<DirectoryEntry &>>;
0061
0062 const MapEntry &getMapEntry() const { return *ME; }
0063
0064
0065 bool isSameRef(DirectoryEntryRef RHS) const { return ME == RHS.ME; }
0066
0067 DirectoryEntryRef() = delete;
0068 explicit DirectoryEntryRef(const MapEntry &ME) : ME(&ME) {}
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 operator const DirectoryEntry *() const { return &getDirEntry(); }
0088
0089 private:
0090 friend class FileMgr::MapEntryOptionalStorage<DirectoryEntryRef>;
0091 struct optional_none_tag {};
0092
0093
0094 DirectoryEntryRef(optional_none_tag) : ME(nullptr) {}
0095 bool hasOptionalValue() const { return ME; }
0096
0097 friend struct llvm::DenseMapInfo<DirectoryEntryRef>;
0098 struct dense_map_empty_tag {};
0099 struct dense_map_tombstone_tag {};
0100
0101
0102 DirectoryEntryRef(dense_map_empty_tag)
0103 : ME(llvm::DenseMapInfo<const MapEntry *>::getEmptyKey()) {}
0104 DirectoryEntryRef(dense_map_tombstone_tag)
0105 : ME(llvm::DenseMapInfo<const MapEntry *>::getTombstoneKey()) {}
0106 bool isSpecialDenseMapKey() const {
0107 return isSameRef(DirectoryEntryRef(dense_map_empty_tag())) ||
0108 isSameRef(DirectoryEntryRef(dense_map_tombstone_tag()));
0109 }
0110
0111 const MapEntry *ME;
0112 };
0113
0114 using OptionalDirectoryEntryRef = CustomizableOptional<DirectoryEntryRef>;
0115
0116 namespace FileMgr {
0117
0118
0119
0120 template <class RefTy> class MapEntryOptionalStorage {
0121 using optional_none_tag = typename RefTy::optional_none_tag;
0122 RefTy MaybeRef;
0123
0124 public:
0125 MapEntryOptionalStorage() : MaybeRef(optional_none_tag()) {}
0126
0127 template <class... ArgTypes>
0128 explicit MapEntryOptionalStorage(std::in_place_t, ArgTypes &&...Args)
0129 : MaybeRef(std::forward<ArgTypes>(Args)...) {}
0130
0131 void reset() { MaybeRef = optional_none_tag(); }
0132
0133 bool has_value() const { return MaybeRef.hasOptionalValue(); }
0134
0135 RefTy &value() & {
0136 assert(has_value());
0137 return MaybeRef;
0138 }
0139 RefTy const &value() const & {
0140 assert(has_value());
0141 return MaybeRef;
0142 }
0143 RefTy &&value() && {
0144 assert(has_value());
0145 return std::move(MaybeRef);
0146 }
0147
0148 template <class... Args> void emplace(Args &&...args) {
0149 MaybeRef = RefTy(std::forward<Args>(args)...);
0150 }
0151
0152 MapEntryOptionalStorage &operator=(RefTy Ref) {
0153 MaybeRef = Ref;
0154 return *this;
0155 }
0156 };
0157
0158 }
0159
0160 namespace optional_detail {
0161
0162
0163
0164 template <>
0165 class OptionalStorage<clang::DirectoryEntryRef>
0166 : public clang::FileMgr::MapEntryOptionalStorage<clang::DirectoryEntryRef> {
0167 using StorageImpl =
0168 clang::FileMgr::MapEntryOptionalStorage<clang::DirectoryEntryRef>;
0169
0170 public:
0171 OptionalStorage() = default;
0172
0173 template <class... ArgTypes>
0174 explicit OptionalStorage(std::in_place_t, ArgTypes &&...Args)
0175 : StorageImpl(std::in_place_t{}, std::forward<ArgTypes>(Args)...) {}
0176
0177 OptionalStorage &operator=(clang::DirectoryEntryRef Ref) {
0178 StorageImpl::operator=(Ref);
0179 return *this;
0180 }
0181 };
0182
0183 static_assert(sizeof(OptionalDirectoryEntryRef) == sizeof(DirectoryEntryRef),
0184 "OptionalDirectoryEntryRef must avoid size overhead");
0185
0186 static_assert(std::is_trivially_copyable<OptionalDirectoryEntryRef>::value,
0187 "OptionalDirectoryEntryRef should be trivially copyable");
0188
0189 }
0190 }
0191
0192 namespace llvm {
0193
0194 template <> struct PointerLikeTypeTraits<clang::DirectoryEntryRef> {
0195 static inline void *getAsVoidPointer(clang::DirectoryEntryRef Dir) {
0196 return const_cast<clang::DirectoryEntryRef::MapEntry *>(&Dir.getMapEntry());
0197 }
0198
0199 static inline clang::DirectoryEntryRef getFromVoidPointer(void *Ptr) {
0200 return clang::DirectoryEntryRef(
0201 *reinterpret_cast<const clang::DirectoryEntryRef::MapEntry *>(Ptr));
0202 }
0203
0204 static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<
0205 const clang::DirectoryEntryRef::MapEntry *>::NumLowBitsAvailable;
0206 };
0207
0208
0209 template <> struct DenseMapInfo<clang::DirectoryEntryRef> {
0210 static inline clang::DirectoryEntryRef getEmptyKey() {
0211 return clang::DirectoryEntryRef(
0212 clang::DirectoryEntryRef::dense_map_empty_tag());
0213 }
0214
0215 static inline clang::DirectoryEntryRef getTombstoneKey() {
0216 return clang::DirectoryEntryRef(
0217 clang::DirectoryEntryRef::dense_map_tombstone_tag());
0218 }
0219
0220 static unsigned getHashValue(clang::DirectoryEntryRef Val) {
0221 return hash_value(Val);
0222 }
0223
0224 static bool isEqual(clang::DirectoryEntryRef LHS,
0225 clang::DirectoryEntryRef RHS) {
0226
0227 if (LHS.isSameRef(RHS))
0228 return true;
0229
0230
0231 if (LHS.isSpecialDenseMapKey() || RHS.isSpecialDenseMapKey())
0232 return false;
0233
0234
0235 return LHS == RHS;
0236 }
0237 };
0238
0239 }
0240
0241 #endif