clang 23.0.0git
DirectoryEntry.h
Go to the documentation of this file.
1//===- clang/Basic/DirectoryEntry.h - Directory references ------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// Defines interfaces for clang::DirectoryEntry and clang::DirectoryEntryRef.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_BASIC_DIRECTORYENTRY_H
15#define LLVM_CLANG_BASIC_DIRECTORYENTRY_H
16
18#include "clang/Basic/LLVM.h"
19#include "llvm/ADT/DenseMapInfo.h"
20#include "llvm/ADT/Hashing.h"
21#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/StringMap.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/ErrorOr.h"
25
26#include <optional>
27#include <utility>
28
29namespace clang {
30namespace FileMgr {
31
32template <class RefTy> class MapEntryOptionalStorage;
33
34} // end namespace FileMgr
35
36/// Cached information about one directory (either on disk or in
37/// the virtual file system).
38class DirectoryEntry {
39 DirectoryEntry() = default;
40 DirectoryEntry(const DirectoryEntry &) = delete;
41 DirectoryEntry &operator=(const DirectoryEntry &) = delete;
42 friend class FileManager;
43 friend class FileEntryTestHelper;
44};
45
46/// A reference to a \c DirectoryEntry that includes the name of the directory
47/// as it was accessed by the FileManager's client.
49public:
50 const DirectoryEntry &getDirEntry() const { return *ME->getValue(); }
51
52 StringRef getName() const { return ME->getKey(); }
53
54 /// Hash code is based on the DirectoryEntry, not the specific named
55 /// reference.
56 friend llvm::hash_code hash_value(DirectoryEntryRef Ref) {
57 return llvm::hash_value(&Ref.getDirEntry());
58 }
59
60 using MapEntry = llvm::StringMapEntry<llvm::ErrorOr<DirectoryEntry &>>;
61
62 const MapEntry &getMapEntry() const { return *ME; }
63
64 /// Check if RHS referenced the file in exactly the same way.
65 bool isSameRef(DirectoryEntryRef RHS) const { return ME == RHS.ME; }
66
68 explicit DirectoryEntryRef(const MapEntry &ME) : ME(&ME) {}
69
70 /// Allow DirectoryEntryRef to degrade into 'const DirectoryEntry*' to
71 /// facilitate incremental adoption.
72 ///
73 /// The goal is to avoid code churn due to dances like the following:
74 /// \code
75 /// // Old code.
76 /// lvalue = rvalue;
77 ///
78 /// // Temporary code from an incremental patch.
79 /// lvalue = &rvalue.getDirectoryEntry();
80 ///
81 /// // Final code.
82 /// lvalue = rvalue;
83 /// \endcode
84 ///
85 /// FIXME: Once DirectoryEntryRef is "everywhere" and DirectoryEntry::getName
86 /// has been deleted, delete this implicit conversion.
87 operator const DirectoryEntry *() const { return &getDirEntry(); }
88
89private:
91 struct optional_none_tag {};
92
93 // Private constructor for use by OptionalStorage.
94 DirectoryEntryRef(optional_none_tag) : ME(nullptr) {}
95 bool hasOptionalValue() const { return ME; }
96
97 friend struct llvm::DenseMapInfo<DirectoryEntryRef>;
98
99 const MapEntry *ME;
100};
101
103
104namespace FileMgr {
105
106/// Customized storage for refs derived from map entires in FileManager, using
107/// the private optional_none_tag to keep it to the size of a single pointer.
108template <class RefTy> class MapEntryOptionalStorage {
109 using optional_none_tag = typename RefTy::optional_none_tag;
110 RefTy MaybeRef = optional_none_tag();
111
112public:
114
115 template <class... ArgTypes>
116 explicit MapEntryOptionalStorage(std::in_place_t, ArgTypes &&...Args)
117 : MaybeRef(std::forward<ArgTypes>(Args)...) {}
118
119 void reset() { MaybeRef = optional_none_tag(); }
120
121 bool has_value() const { return MaybeRef.hasOptionalValue(); }
122
123 RefTy &value() & {
124 assert(has_value());
125 return MaybeRef;
126 }
127 RefTy const &value() const & {
128 assert(has_value());
129 return MaybeRef;
130 }
131 RefTy &&value() && {
132 assert(has_value());
133 return std::move(MaybeRef);
134 }
135
136 template <class... Args> void emplace(Args &&...args) {
137 MaybeRef = RefTy(std::forward<Args>(args)...);
138 }
139
141 MaybeRef = Ref;
142 return *this;
143 }
144};
145
146} // end namespace FileMgr
147
148namespace optional_detail {
149
150/// Customize OptionalStorage<DirectoryEntryRef> to use DirectoryEntryRef and
151/// its optional_none_tag to keep it the size of a single pointer.
152template <>
154 : public clang::FileMgr::MapEntryOptionalStorage<clang::DirectoryEntryRef> {
155 using StorageImpl =
157
158public:
159 using StorageImpl::StorageImpl;
160
165};
166
167static_assert(sizeof(OptionalDirectoryEntryRef) == sizeof(DirectoryEntryRef),
168 "OptionalDirectoryEntryRef must avoid size overhead");
169
170static_assert(std::is_trivially_copyable<OptionalDirectoryEntryRef>::value,
171 "OptionalDirectoryEntryRef should be trivially copyable");
172
173} // end namespace optional_detail
174} // namespace clang
175
176namespace llvm {
177
178template <> struct PointerLikeTypeTraits<clang::DirectoryEntryRef> {
180 return const_cast<clang::DirectoryEntryRef::MapEntry *>(&Dir.getMapEntry());
181 }
182
185 *reinterpret_cast<const clang::DirectoryEntryRef::MapEntry *>(Ptr));
186 }
187
190};
191
192/// Specialisation of DenseMapInfo for DirectoryEntryRef.
193template <> struct DenseMapInfo<clang::DirectoryEntryRef> {
195 return hash_value(Val);
196 }
197
200 if (LHS.isSameRef(RHS))
201 return true;
202 return LHS == RHS;
203 }
204};
205
206} // end namespace llvm
207
208#endif // LLVM_CLANG_BASIC_DIRECTORYENTRY_H
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
DirectoryEntryRef(const MapEntry &ME)
friend llvm::hash_code hash_value(DirectoryEntryRef Ref)
Hash code is based on the DirectoryEntry, not the specific named reference.
bool isSameRef(DirectoryEntryRef RHS) const
Check if RHS referenced the file in exactly the same way.
const MapEntry & getMapEntry() const
llvm::StringMapEntry< llvm::ErrorOr< DirectoryEntry & > > MapEntry
const DirectoryEntry & getDirEntry() const
Cached information about one directory (either on disk or in the virtual file system).
friend class FileEntryTestHelper
Customized storage for refs derived from map entires in FileManager, using the private optional_none_...
MapEntryOptionalStorage(std::in_place_t, ArgTypes &&...Args)
MapEntryOptionalStorage & operator=(RefTy Ref)
OptionalStorage & operator=(clang::DirectoryEntryRef Ref)
Code completion in a.
The JSON file list parser is used to communicate input to InstallAPI.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
hash_code hash_value(const clang::dependencies::ModuleID &ID)
static unsigned getHashValue(clang::DirectoryEntryRef Val)
static bool isEqual(clang::DirectoryEntryRef LHS, clang::DirectoryEntryRef RHS)
static clang::DirectoryEntryRef getFromVoidPointer(void *Ptr)
static void * getAsVoidPointer(clang::DirectoryEntryRef Dir)