diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic/FileManager.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/FileManager.cpp | 92 |
1 files changed, 35 insertions, 57 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp index d492744..cb3f75c 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp @@ -22,6 +22,7 @@ #include "clang/Frontend/PCHContainerOperations.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/llvm-config.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" @@ -58,12 +59,7 @@ FileManager::FileManager(const FileSystemOptions &FSO, this->FS = vfs::getRealFileSystem(); } -FileManager::~FileManager() { - for (unsigned i = 0, e = VirtualFileEntries.size(); i != e; ++i) - delete VirtualFileEntries[i]; - for (unsigned i = 0, e = VirtualDirectoryEntries.size(); i != e; ++i) - delete VirtualDirectoryEntries[i]; -} +FileManager::~FileManager() = default; void FileManager::addStatCache(std::unique_ptr<FileSystemStatCache> statCache, bool AtBeginning) { @@ -137,14 +133,14 @@ void FileManager::addAncestorsAsVirtualDirs(StringRef Path) { // at the same time. Therefore, if DirName is already in the cache, // we don't need to recurse as its ancestors must also already be in // the cache. - if (NamedDirEnt.second) + if (NamedDirEnt.second && NamedDirEnt.second != NON_EXISTENT_DIR) return; // Add the virtual directory to the cache. - DirectoryEntry *UDE = new DirectoryEntry; + auto UDE = llvm::make_unique<DirectoryEntry>(); UDE->Name = NamedDirEnt.first().data(); - NamedDirEnt.second = UDE; - VirtualDirectoryEntries.push_back(UDE); + NamedDirEnt.second = UDE.get(); + VirtualDirectoryEntries.push_back(std::move(UDE)); // Recursively add the other ancestors. addAncestorsAsVirtualDirs(DirName); @@ -375,8 +371,8 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, } if (!UFE) { - UFE = new FileEntry(); - VirtualFileEntries.push_back(UFE); + VirtualFileEntries.push_back(llvm::make_unique<FileEntry>()); + UFE = VirtualFileEntries.back().get(); NamedFileEnt.second = UFE; } @@ -389,16 +385,28 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, return UFE; } -void FileManager::FixupRelativePath(SmallVectorImpl<char> &path) const { +bool FileManager::FixupRelativePath(SmallVectorImpl<char> &path) const { StringRef pathRef(path.data(), path.size()); if (FileSystemOpts.WorkingDir.empty() || llvm::sys::path::is_absolute(pathRef)) - return; + return false; SmallString<128> NewPath(FileSystemOpts.WorkingDir); llvm::sys::path::append(NewPath, pathRef); path = NewPath; + return true; +} + +bool FileManager::makeAbsolutePath(SmallVectorImpl<char> &Path) const { + bool Changed = FixupRelativePath(Path); + + if (!llvm::sys::path::is_absolute(StringRef(Path.data(), Path.size()))) { + llvm::sys::fs::make_absolute(Path); + Changed = true; + } + + return Changed; } llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> @@ -501,11 +509,9 @@ void FileManager::GetUniqueIDMapping( UIDToFiles[FE->getValue()->getUID()] = FE->getValue(); // Map virtual file entries - for (SmallVectorImpl<FileEntry *>::const_iterator - VFE = VirtualFileEntries.begin(), VFEEnd = VirtualFileEntries.end(); - VFE != VFEEnd; ++VFE) - if (*VFE && *VFE != NON_EXISTENT_FILE) - UIDToFiles[(*VFE)->getUID()] = *VFE; + for (const auto &VFE : VirtualFileEntries) + if (VFE && VFE.get() != NON_EXISTENT_FILE) + UIDToFiles[VFE->getUID()] = VFE.get(); } void FileManager::modifyFileEntry(FileEntry *File, @@ -514,37 +520,6 @@ void FileManager::modifyFileEntry(FileEntry *File, File->ModTime = ModificationTime; } -/// Remove '.' path components from the given absolute path. -/// \return \c true if any changes were made. -// FIXME: Move this to llvm::sys::path. -bool FileManager::removeDotPaths(SmallVectorImpl<char> &Path) { - using namespace llvm::sys; - - SmallVector<StringRef, 16> ComponentStack; - StringRef P(Path.data(), Path.size()); - - // Skip the root path, then look for traversal in the components. - StringRef Rel = path::relative_path(P); - bool AnyDots = false; - for (StringRef C : llvm::make_range(path::begin(Rel), path::end(Rel))) { - if (C == ".") { - AnyDots = true; - continue; - } - ComponentStack.push_back(C); - } - - if (!AnyDots) - return false; - - SmallString<256> Buffer = path::root_path(P); - for (StringRef C : ComponentStack) - path::append(Buffer, C); - - Path.swap(Buffer); - return true; -} - StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) { // FIXME: use llvm::sys::fs::canonical() when it gets implemented llvm::DenseMap<const DirectoryEntry *, llvm::StringRef>::iterator Known @@ -556,17 +531,20 @@ StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) { #ifdef LLVM_ON_UNIX char CanonicalNameBuf[PATH_MAX]; - if (realpath(Dir->getName(), CanonicalNameBuf)) { - unsigned Len = strlen(CanonicalNameBuf); - char *Mem = static_cast<char *>(CanonicalNameStorage.Allocate(Len, 1)); - memcpy(Mem, CanonicalNameBuf, Len); - CanonicalName = StringRef(Mem, Len); - } + if (realpath(Dir->getName(), CanonicalNameBuf)) + CanonicalName = StringRef(CanonicalNameBuf).copy(CanonicalNameStorage); #else SmallString<256> CanonicalNameBuf(CanonicalName); llvm::sys::fs::make_absolute(CanonicalNameBuf); llvm::sys::path::native(CanonicalNameBuf); - removeDotPaths(CanonicalNameBuf); + // We've run into needing to remove '..' here in the wild though, so + // remove it. + // On Windows, symlinks are significantly less prevalent, so removing + // '..' is pretty safe. + // Ideally we'd have an equivalent of `realpath` and could implement + // sys::fs::canonical across all the platforms. + llvm::sys::path::remove_dots(CanonicalNameBuf, /* remove_dot_dot */ true); + CanonicalName = StringRef(CanonicalNameBuf).copy(CanonicalNameStorage); #endif CanonicalDirNames.insert(std::make_pair(Dir, CanonicalName)); |