clang  16.0.0git
FileEntry.h
Go to the documentation of this file.
1 //===- clang/Basic/FileEntry.h - File 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::FileEntry and clang::FileEntryRef.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_BASIC_FILEENTRY_H
15 #define LLVM_CLANG_BASIC_FILEENTRY_H
16 
18 #include "clang/Basic/LLVM.h"
19 #include "llvm/ADT/DenseMapInfo.h"
20 #include "llvm/ADT/Hashing.h"
21 #include "llvm/ADT/PointerUnion.h"
22 #include "llvm/ADT/StringMap.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/Support/ErrorOr.h"
25 #include "llvm/Support/FileSystem/UniqueID.h"
26 
27 #include <utility>
28 
29 namespace llvm {
30 
31 class MemoryBuffer;
32 
33 namespace vfs {
34 
35 class File;
36 
37 } // namespace vfs
38 } // namespace llvm
39 
40 namespace clang {
41 
42 class FileEntryRef;
43 
44 } // namespace clang
45 
46 namespace llvm {
47 namespace optional_detail {
48 
49 /// Forward declare a template specialization for OptionalStorage.
50 template <>
51 class OptionalStorage<clang::FileEntryRef, /*is_trivially_copyable*/ true>;
52 
53 } // namespace optional_detail
54 } // namespace llvm
55 
56 namespace clang {
57 
58 class FileEntry;
59 
60 /// A reference to a \c FileEntry that includes the name of the file as it was
61 /// accessed by the FileManager's client.
62 class FileEntryRef {
63 public:
64  /// The name of this FileEntry. If a VFS uses 'use-external-name', this is
65  /// the redirected name. See getRequestedName().
66  StringRef getName() const { return getBaseMapEntry().first(); }
67 
68  /// The name of this FileEntry, as originally requested without applying any
69  /// remappings for VFS 'use-external-name'.
70  ///
71  /// FIXME: this should be the semantics of getName(). See comment in
72  /// FileManager::getFileRef().
73  StringRef getNameAsRequested() const { return ME->first(); }
74 
75  const FileEntry &getFileEntry() const {
76  return *getBaseMapEntry().second->V.get<FileEntry *>();
77  }
78  DirectoryEntryRef getDir() const { return *getBaseMapEntry().second->Dir; }
79 
80  inline off_t getSize() const;
81  inline unsigned getUID() const;
82  inline const llvm::sys::fs::UniqueID &getUniqueID() const;
83  inline time_t getModificationTime() const;
84  inline bool isNamedPipe() const;
85  inline void closeFile() const;
86 
87  /// Check if the underlying FileEntry is the same, intentially ignoring
88  /// whether the file was referenced with the same spelling of the filename.
89  friend bool operator==(const FileEntryRef &LHS, const FileEntryRef &RHS) {
90  return &LHS.getFileEntry() == &RHS.getFileEntry();
91  }
92  friend bool operator==(const FileEntry *LHS, const FileEntryRef &RHS) {
93  return LHS == &RHS.getFileEntry();
94  }
95  friend bool operator==(const FileEntryRef &LHS, const FileEntry *RHS) {
96  return &LHS.getFileEntry() == RHS;
97  }
98  friend bool operator!=(const FileEntryRef &LHS, const FileEntryRef &RHS) {
99  return !(LHS == RHS);
100  }
101  friend bool operator!=(const FileEntry *LHS, const FileEntryRef &RHS) {
102  return !(LHS == RHS);
103  }
104  friend bool operator!=(const FileEntryRef &LHS, const FileEntry *RHS) {
105  return !(LHS == RHS);
106  }
107 
108  /// Hash code is based on the FileEntry, not the specific named reference,
109  /// just like operator==.
110  friend llvm::hash_code hash_value(FileEntryRef Ref) {
111  return llvm::hash_value(&Ref.getFileEntry());
112  }
113 
114  struct MapValue;
115 
116  /// Type used in the StringMap.
117  using MapEntry = llvm::StringMapEntry<llvm::ErrorOr<MapValue>>;
118 
119  /// Type stored in the StringMap.
120  struct MapValue {
121  /// The pointer at another MapEntry is used when the FileManager should
122  /// silently forward from one name to another, which occurs in Redirecting
123  /// VFSs that use external names. In that case, the \c FileEntryRef
124  /// returned by the \c FileManager will have the external name, and not the
125  /// name that was used to lookup the file.
126  ///
127  /// The second type is really a `const MapEntry *`, but that confuses
128  /// gcc5.3. Once that's no longer supported, change this back.
129  llvm::PointerUnion<FileEntry *, const void *> V;
130 
131  /// Directory the file was found in. Set if and only if V is a FileEntry.
133 
134  MapValue() = delete;
135  MapValue(FileEntry &FE, DirectoryEntryRef Dir) : V(&FE), Dir(Dir) {}
136  MapValue(MapEntry &ME) : V(&ME) {}
137  };
138 
139  /// Check if RHS referenced the file in exactly the same way.
140  bool isSameRef(const FileEntryRef &RHS) const { return ME == RHS.ME; }
141 
142  /// Allow FileEntryRef to degrade into 'const FileEntry*' to facilitate
143  /// incremental adoption.
144  ///
145  /// The goal is to avoid code churn due to dances like the following:
146  /// \code
147  /// // Old code.
148  /// lvalue = rvalue;
149  ///
150  /// // Temporary code from an incremental patch.
151  /// lvalue = &rvalue.getFileEntry();
152  ///
153  /// // Final code.
154  /// lvalue = rvalue;
155  /// \endcode
156  ///
157  /// FIXME: Once FileEntryRef is "everywhere" and FileEntry::LastRef and
158  /// FileEntry::getName have been deleted, delete this implicit conversion.
159  operator const FileEntry *() const { return &getFileEntry(); }
160 
161  FileEntryRef() = delete;
162  explicit FileEntryRef(const MapEntry &ME) : ME(&ME) {
163  assert(ME.second && "Expected payload");
164  assert(ME.second->V && "Expected non-null");
165  }
166 
167  /// Expose the underlying MapEntry to simplify packing in a PointerIntPair or
168  /// PointerUnion and allow construction in Optional.
169  const clang::FileEntryRef::MapEntry &getMapEntry() const { return *ME; }
170 
171  /// Retrieve the base MapEntry after redirects.
172  const MapEntry &getBaseMapEntry() const {
173  const MapEntry *ME = this->ME;
174  while (const void *Next = ME->second->V.dyn_cast<const void *>())
175  ME = static_cast<const MapEntry *>(Next);
176  return *ME;
177  }
178 
179 private:
181  struct optional_none_tag {};
182 
183  // Private constructor for use by OptionalStorage.
184  FileEntryRef(optional_none_tag) : ME(nullptr) {}
185  bool hasOptionalValue() const { return ME; }
186 
187  friend struct llvm::DenseMapInfo<FileEntryRef>;
188  struct dense_map_empty_tag {};
189  struct dense_map_tombstone_tag {};
190 
191  // Private constructors for use by DenseMapInfo.
192  FileEntryRef(dense_map_empty_tag)
193  : ME(llvm::DenseMapInfo<const MapEntry *>::getEmptyKey()) {}
194  FileEntryRef(dense_map_tombstone_tag)
195  : ME(llvm::DenseMapInfo<const MapEntry *>::getTombstoneKey()) {}
196  bool isSpecialDenseMapKey() const {
197  return isSameRef(FileEntryRef(dense_map_empty_tag())) ||
198  isSameRef(FileEntryRef(dense_map_tombstone_tag()));
199  }
200 
201  const MapEntry *ME;
202 };
203 
204 static_assert(sizeof(FileEntryRef) == sizeof(const FileEntry *),
205  "FileEntryRef must avoid size overhead");
206 
207 static_assert(std::is_trivially_copyable<FileEntryRef>::value,
208  "FileEntryRef must be trivially copyable");
209 
210 } // end namespace clang
211 
212 namespace llvm {
213 namespace optional_detail {
214 
215 /// Customize OptionalStorage<FileEntryRef> to use FileEntryRef and its
216 /// optional_none_tag to keep it the size of a single pointer.
217 template <>
218 class OptionalStorage<clang::FileEntryRef>
219  : public clang::FileMgr::MapEntryOptionalStorage<clang::FileEntryRef> {
220  using StorageImpl =
222 
223 public:
224  OptionalStorage() = default;
225 
226  template <class... ArgTypes>
227  explicit OptionalStorage(std::in_place_t, ArgTypes &&...Args)
228  : StorageImpl(std::in_place_t{}, std::forward<ArgTypes>(Args)...) {}
229 
230  OptionalStorage &operator=(clang::FileEntryRef Ref) {
231  StorageImpl::operator=(Ref);
232  return *this;
233  }
234 };
235 
236 static_assert(sizeof(Optional<clang::FileEntryRef>) ==
237  sizeof(clang::FileEntryRef),
238  "Optional<FileEntryRef> must avoid size overhead");
239 
240 static_assert(std::is_trivially_copyable<Optional<clang::FileEntryRef>>::value,
241  "Optional<FileEntryRef> should be trivially copyable");
242 
243 } // end namespace optional_detail
244 
245 /// Specialisation of DenseMapInfo for FileEntryRef.
246 template <> struct DenseMapInfo<clang::FileEntryRef> {
248  return clang::FileEntryRef(clang::FileEntryRef::dense_map_empty_tag());
249  }
250 
252  return clang::FileEntryRef(clang::FileEntryRef::dense_map_tombstone_tag());
253  }
254 
255  static unsigned getHashValue(clang::FileEntryRef Val) {
256  return hash_value(Val);
257  }
258 
260  // Catch the easy cases: both empty, both tombstone, or the same ref.
261  if (LHS.isSameRef(RHS))
262  return true;
263 
264  // Confirm LHS and RHS are valid.
265  if (LHS.isSpecialDenseMapKey() || RHS.isSpecialDenseMapKey())
266  return false;
267 
268  // It's safe to use operator==.
269  return LHS == RHS;
270  }
271 };
272 
273 } // end namespace llvm
274 
275 namespace clang {
276 
277 /// Wrapper around Optional<FileEntryRef> that degrades to 'const FileEntry*',
278 /// facilitating incremental patches to propagate FileEntryRef.
279 ///
280 /// This class can be used as return value or field where it's convenient for
281 /// an Optional<FileEntryRef> to degrade to a 'const FileEntry*'. The purpose
282 /// is to avoid code churn due to dances like the following:
283 /// \code
284 /// // Old code.
285 /// lvalue = rvalue;
286 ///
287 /// // Temporary code from an incremental patch.
288 /// Optional<FileEntryRef> MaybeF = rvalue;
289 /// lvalue = MaybeF ? &MaybeF.getFileEntry() : nullptr;
290 ///
291 /// // Final code.
292 /// lvalue = rvalue;
293 /// \endcode
294 ///
295 /// FIXME: Once FileEntryRef is "everywhere" and FileEntry::LastRef and
296 /// FileEntry::getName have been deleted, delete this class and replace
297 /// instances with Optional<FileEntryRef>.
299  : public Optional<FileEntryRef> {
300 public:
307  operator=(OptionalFileEntryRefDegradesToFileEntryPtr &&) = default;
309  operator=(const OptionalFileEntryRefDegradesToFileEntryPtr &) = default;
310 
313  : Optional<FileEntryRef>(Ref) {}
315  : Optional<FileEntryRef>(MaybeRef) {}
316 
318  Optional<FileEntryRef>::operator=(std::nullopt);
319  return *this;
320  }
323  return *this;
324  }
328  return *this;
329  }
330 
331  /// Degrade to 'const FileEntry *' to allow FileEntry::LastRef and
332  /// FileEntry::getName have been deleted, delete this class and replace
333  /// instances with Optional<FileEntryRef>
334  operator const FileEntry *() const {
335  return has_value() ? &value().getFileEntry() : nullptr;
336  }
337 };
338 
339 static_assert(
340  std::is_trivially_copyable<
341  OptionalFileEntryRefDegradesToFileEntryPtr>::value,
342  "OptionalFileEntryRefDegradesToFileEntryPtr should be trivially copyable");
343 
344 inline bool operator==(const FileEntry *LHS,
345  const Optional<FileEntryRef> &RHS) {
346  return LHS == (RHS ? &RHS->getFileEntry() : nullptr);
347 }
348 inline bool operator==(const Optional<FileEntryRef> &LHS,
349  const FileEntry *RHS) {
350  return (LHS ? &LHS->getFileEntry() : nullptr) == RHS;
351 }
352 inline bool operator!=(const FileEntry *LHS,
353  const Optional<FileEntryRef> &RHS) {
354  return !(LHS == RHS);
355 }
356 inline bool operator!=(const Optional<FileEntryRef> &LHS,
357  const FileEntry *RHS) {
358  return !(LHS == RHS);
359 }
360 
361 /// Cached information about one file (either on disk
362 /// or in the virtual file system).
363 ///
364 /// If the 'File' member is valid, then this FileEntry has an open file
365 /// descriptor for the file.
366 class FileEntry {
367  friend class FileManager;
368  friend class FileEntryTestHelper;
369  FileEntry();
370  FileEntry(const FileEntry &) = delete;
371  FileEntry &operator=(const FileEntry &) = delete;
372 
373  std::string RealPathName; // Real path to the file; could be empty.
374  off_t Size = 0; // File size in bytes.
375  time_t ModTime = 0; // Modification time of file.
376  const DirectoryEntry *Dir = nullptr; // Directory file lives in.
377  llvm::sys::fs::UniqueID UniqueID;
378  unsigned UID = 0; // A unique (small) ID for the file.
379  bool IsNamedPipe = false;
380 
381  /// The open file, if it is owned by the \p FileEntry.
382  mutable std::unique_ptr<llvm::vfs::File> File;
383 
384  /// The file content, if it is owned by the \p FileEntry.
385  std::unique_ptr<llvm::MemoryBuffer> Content;
386 
387  // First access name for this FileEntry.
388  //
389  // This is Optional only to allow delayed construction (FileEntryRef has no
390  // default constructor). It should always have a value in practice.
391  //
392  // TODO: remove this once everyone that needs a name uses FileEntryRef.
393  Optional<FileEntryRef> LastRef;
394 
395 public:
396  ~FileEntry();
397  StringRef getName() const { return LastRef->getName(); }
398  FileEntryRef getLastRef() const { return *LastRef; }
399 
400  StringRef tryGetRealPathName() const { return RealPathName; }
401  off_t getSize() const { return Size; }
402  unsigned getUID() const { return UID; }
403  const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
404  time_t getModificationTime() const { return ModTime; }
405 
406  /// Return the directory the file lives in.
407  const DirectoryEntry *getDir() const { return Dir; }
408 
409  /// Check whether the file is a named pipe (and thus can't be opened by
410  /// the native FileManager methods).
411  bool isNamedPipe() const { return IsNamedPipe; }
412 
413  void closeFile() const;
414 };
415 
416 off_t FileEntryRef::getSize() const { return getFileEntry().getSize(); }
417 
418 unsigned FileEntryRef::getUID() const { return getFileEntry().getUID(); }
419 
420 const llvm::sys::fs::UniqueID &FileEntryRef::getUniqueID() const {
421  return getFileEntry().getUniqueID();
422 }
423 
424 time_t FileEntryRef::getModificationTime() const {
425  return getFileEntry().getModificationTime();
426 }
427 
428 bool FileEntryRef::isNamedPipe() const { return getFileEntry().isNamedPipe(); }
429 
430 void FileEntryRef::closeFile() const { getFileEntry().closeFile(); }
431 
432 } // end namespace clang
433 
434 #endif // LLVM_CLANG_BASIC_FILEENTRY_H
llvm
YAML serialization mapping.
Definition: Dominators.h:30
clang::FileEntryRef
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition: FileEntry.h:62
clang::FileEntry::getDir
const DirectoryEntry * getDir() const
Return the directory the file lives in.
Definition: FileEntry.h:407
clang::FileEntryRef::MapValue::V
llvm::PointerUnion< FileEntry *, const void * > V
The pointer at another MapEntry is used when the FileManager should silently forward from one name to...
Definition: FileEntry.h:129
clang::DeclaratorContext::File
@ File
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::FileEntry::getLastRef
FileEntryRef getLastRef() const
Definition: FileEntry.h:398
clang::FileEntryRef::MapValue::Dir
Optional< DirectoryEntryRef > Dir
Directory the file was found in. Set if and only if V is a FileEntry.
Definition: FileEntry.h:132
clang::DirectoryEntryRef
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
Definition: DirectoryEntry.h:52
clang::FileEntryRef::operator!=
friend bool operator!=(const FileEntryRef &LHS, const FileEntry *RHS)
Definition: FileEntry.h:104
llvm::DenseMapInfo< clang::FileEntryRef >::getTombstoneKey
static clang::FileEntryRef getTombstoneKey()
Definition: FileEntry.h:251
clang::FileEntryRef::hash_value
friend llvm::hash_code hash_value(FileEntryRef Ref)
Hash code is based on the FileEntry, not the specific named reference, just like operator==.
Definition: FileEntry.h:110
llvm::DenseMapInfo< clang::FileEntryRef >::getHashValue
static unsigned getHashValue(clang::FileEntryRef Val)
Definition: FileEntry.h:255
clang::OptionalFileEntryRefDegradesToFileEntryPtr::operator=
OptionalFileEntryRefDegradesToFileEntryPtr & operator=(std::nullopt_t)
Definition: FileEntry.h:317
clang::OptionalFileEntryRefDegradesToFileEntryPtr::operator=
OptionalFileEntryRefDegradesToFileEntryPtr & operator=(Optional< FileEntryRef > MaybeRef)
Definition: FileEntry.h:326
clang::FileEntryRef::operator==
friend bool operator==(const FileEntryRef &LHS, const FileEntryRef &RHS)
Check if the underlying FileEntry is the same, intentially ignoring whether the file was referenced w...
Definition: FileEntry.h:89
llvm::Optional< DirectoryEntryRef >
DirectoryEntry.h
clang::FileEntryRef::operator!=
friend bool operator!=(const FileEntry *LHS, const FileEntryRef &RHS)
Definition: FileEntry.h:101
clang::OptionalFileEntryRefDegradesToFileEntryPtr
Wrapper around Optional<FileEntryRef> that degrades to 'const FileEntry*', facilitating incremental p...
Definition: FileEntry.h:298
clang::FileEntry::getUniqueID
const llvm::sys::fs::UniqueID & getUniqueID() const
Definition: FileEntry.h:403
clang::hash_value
llvm::hash_code hash_value(const clang::SanitizerMask &Arg)
Definition: Sanitizers.cpp:68
clang::FileMgr::MapEntryOptionalStorage
Customized storage for refs derived from map entires in FileManager, using the private optional_none_...
Definition: DirectoryEntry.h:30
V
#define V(N, I)
Definition: ASTContext.h:3208
clang::FileEntryRef::getNameAsRequested
StringRef getNameAsRequested() const
The name of this FileEntry, as originally requested without applying any remappings for VFS 'use-exte...
Definition: FileEntry.h:73
clang::operator!=
bool operator!=(const Optional< FileEntryRef > &LHS, const FileEntry *RHS)
Definition: FileEntry.h:356
clang::DirectoryEntry
Cached information about one directory (either on disk or in the virtual file system).
Definition: DirectoryEntry.h:36
clang::FileEntryRef::getMapEntry
const clang::FileEntryRef::MapEntry & getMapEntry() const
Expose the underlying MapEntry to simplify packing in a PointerIntPair or PointerUnion and allow cons...
Definition: FileEntry.h:169
clang::FileEntryRef::FileEntryRef
FileEntryRef(const MapEntry &ME)
Definition: FileEntry.h:162
clang::FileEntryRef::operator==
friend bool operator==(const FileEntryRef &LHS, const FileEntry *RHS)
Definition: FileEntry.h:95
clang::OptionalFileEntryRefDegradesToFileEntryPtr::operator=
OptionalFileEntryRefDegradesToFileEntryPtr & operator=(FileEntryRef Ref)
Definition: FileEntry.h:321
clang::OptionalFileEntryRefDegradesToFileEntryPtr::OptionalFileEntryRefDegradesToFileEntryPtr
OptionalFileEntryRefDegradesToFileEntryPtr(std::nullopt_t)
Definition: FileEntry.h:311
clang::FileEntryRef::getBaseMapEntry
const MapEntry & getBaseMapEntry() const
Retrieve the base MapEntry after redirects.
Definition: FileEntry.h:172
clang::FileEntry::tryGetRealPathName
StringRef tryGetRealPathName() const
Definition: FileEntry.h:400
clang::FileEntry
Cached information about one file (either on disk or in the virtual file system).
Definition: FileEntry.h:366
clang::FileEntry::getUID
unsigned getUID() const
Definition: FileEntry.h:402
llvm::optional_detail::OptionalStorage< clang::FileEntryRef >::operator=
OptionalStorage & operator=(clang::FileEntryRef Ref)
Definition: FileEntry.h:230
clang::FileEntryRef::getName
StringRef getName() const
The name of this FileEntry.
Definition: FileEntry.h:66
clang::OptionalFileEntryRefDegradesToFileEntryPtr::OptionalFileEntryRefDegradesToFileEntryPtr
OptionalFileEntryRefDegradesToFileEntryPtr(Optional< FileEntryRef > MaybeRef)
Definition: FileEntry.h:314
clang::OptionalFileEntryRefDegradesToFileEntryPtr::OptionalFileEntryRefDegradesToFileEntryPtr
OptionalFileEntryRefDegradesToFileEntryPtr(FileEntryRef Ref)
Definition: FileEntry.h:312
LLVM.h
clang::FileEntryRef::MapValue
Type stored in the StringMap.
Definition: FileEntry.h:120
llvm::DenseMapInfo< clang::FileEntryRef >::getEmptyKey
static clang::FileEntryRef getEmptyKey()
Definition: FileEntry.h:247
clang::FileEntryRef::operator==
friend bool operator==(const FileEntry *LHS, const FileEntryRef &RHS)
Definition: FileEntry.h:92
std
Definition: Format.h:4477
clang::FileEntryRef::MapValue::MapValue
MapValue(FileEntry &FE, DirectoryEntryRef Dir)
Definition: FileEntry.h:135
clang::FileEntryRef::operator!=
friend bool operator!=(const FileEntryRef &LHS, const FileEntryRef &RHS)
Definition: FileEntry.h:98
clang
Definition: CalledOnceCheck.h:17
clang::FileManager
Implements support for file system lookup, file system caching, and directory search management.
Definition: FileManager.h:53
clang::FileEntry::getModificationTime
time_t getModificationTime() const
Definition: FileEntry.h:404
llvm::optional_detail::OptionalStorage< clang::FileEntryRef >::OptionalStorage
OptionalStorage(std::in_place_t, ArgTypes &&...Args)
Definition: FileEntry.h:227
clang::FileEntry::getName
StringRef getName() const
Definition: FileEntry.h:397
clang::FileEntryRef::getFileEntry
const FileEntry & getFileEntry() const
Definition: FileEntry.h:75
clang::FileEntryRef::MapValue::MapValue
MapValue(MapEntry &ME)
Definition: FileEntry.h:136
clang::FileEntryRef::isSameRef
bool isSameRef(const FileEntryRef &RHS) const
Check if RHS referenced the file in exactly the same way.
Definition: FileEntry.h:140
clang::FileEntry::isNamedPipe
bool isNamedPipe() const
Check whether the file is a named pipe (and thus can't be opened by the native FileManager methods).
Definition: FileEntry.h:411
true
#define true
Definition: stdbool.h:21
clang::FileEntry::getSize
off_t getSize() const
Definition: FileEntry.h:401
clang::FileEntryRef::getDir
DirectoryEntryRef getDir() const
Definition: FileEntry.h:78
clang::FileEntryRef::MapEntry
llvm::StringMapEntry< llvm::ErrorOr< MapValue > > MapEntry
Type used in the StringMap.
Definition: FileEntry.h:117
clang::operator==
bool operator==(const Optional< FileEntryRef > &LHS, const FileEntry *RHS)
Definition: FileEntry.h:348
llvm::DenseMapInfo< clang::FileEntryRef >::isEqual
static bool isEqual(clang::FileEntryRef LHS, clang::FileEntryRef RHS)
Definition: FileEntry.h:259