aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Basic/FileManager.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-18 20:30:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-19 21:23:40 +0000
commitbdbe302c3396ceb4dd89d1214485439598f05368 (patch)
treeccf66c6349b23061ed5e9645c21f15fbe718da8b /contrib/llvm-project/clang/lib/Basic/FileManager.cpp
parente7a1904fe1ced461b2a31f03b6592ae6564a243a (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic/FileManager.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Basic/FileManager.cpp87
1 files changed, 50 insertions, 37 deletions
diff --git a/contrib/llvm-project/clang/lib/Basic/FileManager.cpp b/contrib/llvm-project/clang/lib/Basic/FileManager.cpp
index f92c1aeb2112..d16626b10652 100644
--- a/contrib/llvm-project/clang/lib/Basic/FileManager.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/FileManager.cpp
@@ -536,8 +536,9 @@ void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) {
}
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
-FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile,
+FileManager::getBufferForFile(FileEntryRef FE, bool isVolatile,
bool RequiresNullTerminator) {
+ const FileEntry *Entry = &FE.getFileEntry();
// If the content is living on the file entry, return a reference to it.
if (Entry->Content)
return llvm::MemoryBuffer::getMemBuffer(Entry->Content->getMemBufferRef());
@@ -548,7 +549,7 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile,
if (isVolatile || Entry->isNamedPipe())
FileSize = -1;
- StringRef Filename = Entry->getName();
+ StringRef Filename = FE.getName();
// If the file is already open, use the open file descriptor.
if (Entry->File) {
auto Result = Entry->File->getBuffer(Filename, FileSize,
@@ -611,54 +612,66 @@ FileManager::getNoncachedStatValue(StringRef Path,
}
void FileManager::GetUniqueIDMapping(
- SmallVectorImpl<const FileEntry *> &UIDToFiles) const {
+ SmallVectorImpl<OptionalFileEntryRef> &UIDToFiles) const {
UIDToFiles.clear();
UIDToFiles.resize(NextFileUID);
- // Map file entries
- for (llvm::StringMap<llvm::ErrorOr<FileEntryRef::MapValue>,
- llvm::BumpPtrAllocator>::const_iterator
- FE = SeenFileEntries.begin(),
- FEEnd = SeenFileEntries.end();
- FE != FEEnd; ++FE)
- if (llvm::ErrorOr<FileEntryRef::MapValue> Entry = FE->getValue()) {
- if (const auto *FE = Entry->V.dyn_cast<FileEntry *>())
- UIDToFiles[FE->getUID()] = FE;
- }
-
- // Map virtual file entries
- for (const auto &VFE : VirtualFileEntries)
- UIDToFiles[VFE->getUID()] = VFE;
+ for (const auto &Entry : SeenFileEntries) {
+ // Only return files that exist and are not redirected.
+ if (!Entry.getValue() || !Entry.getValue()->V.is<FileEntry *>())
+ continue;
+ FileEntryRef FE(Entry);
+ // Add this file if it's the first one with the UID, or if its name is
+ // better than the existing one.
+ OptionalFileEntryRef &ExistingFE = UIDToFiles[FE.getUID()];
+ if (!ExistingFE || FE.getName() < ExistingFE->getName())
+ ExistingFE = FE;
+ }
}
StringRef FileManager::getCanonicalName(DirectoryEntryRef Dir) {
- auto Known = CanonicalNames.find(Dir);
- if (Known != CanonicalNames.end())
- return Known->second;
-
- StringRef CanonicalName(Dir.getName());
-
- SmallString<4096> CanonicalNameBuf;
- if (!FS->getRealPath(Dir.getName(), CanonicalNameBuf))
- CanonicalName = CanonicalNameBuf.str().copy(CanonicalNameStorage);
+ return getCanonicalName(Dir, Dir.getName());
+}
- CanonicalNames.insert({Dir, CanonicalName});
- return CanonicalName;
+StringRef FileManager::getCanonicalName(FileEntryRef File) {
+ return getCanonicalName(File, File.getName());
}
-StringRef FileManager::getCanonicalName(const FileEntry *File) {
- llvm::DenseMap<const void *, llvm::StringRef>::iterator Known
- = CanonicalNames.find(File);
+StringRef FileManager::getCanonicalName(const void *Entry, StringRef Name) {
+ llvm::DenseMap<const void *, llvm::StringRef>::iterator Known =
+ CanonicalNames.find(Entry);
if (Known != CanonicalNames.end())
return Known->second;
- StringRef CanonicalName(File->getName());
-
- SmallString<4096> CanonicalNameBuf;
- if (!FS->getRealPath(File->getName(), CanonicalNameBuf))
- CanonicalName = CanonicalNameBuf.str().copy(CanonicalNameStorage);
+ // Name comes from FileEntry/DirectoryEntry::getName(), so it is safe to
+ // store it in the DenseMap below.
+ StringRef CanonicalName(Name);
+
+ SmallString<256> AbsPathBuf;
+ SmallString<256> RealPathBuf;
+ if (!FS->getRealPath(Name, RealPathBuf)) {
+ if (is_style_windows(llvm::sys::path::Style::native)) {
+ // For Windows paths, only use the real path if it doesn't resolve
+ // a substitute drive, as those are used to avoid MAX_PATH issues.
+ AbsPathBuf = Name;
+ if (!FS->makeAbsolute(AbsPathBuf)) {
+ if (llvm::sys::path::root_name(RealPathBuf) ==
+ llvm::sys::path::root_name(AbsPathBuf)) {
+ CanonicalName = RealPathBuf.str().copy(CanonicalNameStorage);
+ } else {
+ // Fallback to using the absolute path.
+ // Simplifying /../ is semantically valid on Windows even in the
+ // presence of symbolic links.
+ llvm::sys::path::remove_dots(AbsPathBuf, /*remove_dot_dot=*/true);
+ CanonicalName = AbsPathBuf.str().copy(CanonicalNameStorage);
+ }
+ }
+ } else {
+ CanonicalName = RealPathBuf.str().copy(CanonicalNameStorage);
+ }
+ }
- CanonicalNames.insert({File, CanonicalName});
+ CanonicalNames.insert({Entry, CanonicalName});
return CanonicalName;
}