diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-12-11 20:50:24 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-12-11 20:50:24 +0000 |
commit | 54cc3c2f231846e110dcfbc04ff52f266aa6dfb9 (patch) | |
tree | 40917c9ba0ce4b23b2f98595f012d5ab5d50a332 /clang/lib/Basic/FileManager.cpp | |
parent | 72b05aa59c0268f3404af9c3e61c706d1661fd03 (diff) | |
download | bcm5719-llvm-54cc3c2f231846e110dcfbc04ff52f266aa6dfb9.tar.gz bcm5719-llvm-54cc3c2f231846e110dcfbc04ff52f266aa6dfb9.zip |
[modules] When constructing paths relative to a module, strip out /./ directory
components. These sometimes get synthetically added, and we don't want -Ifoo
and -I./foo to be treated fundamentally differently here.
llvm-svn: 224055
Diffstat (limited to 'clang/lib/Basic/FileManager.cpp')
-rw-r--r-- | clang/lib/Basic/FileManager.cpp | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index af6022fdc92..214e0f35a52 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -513,15 +513,47 @@ 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 -#ifdef LLVM_ON_UNIX llvm::DenseMap<const DirectoryEntry *, llvm::StringRef>::iterator Known = CanonicalDirNames.find(Dir); if (Known != CanonicalDirNames.end()) return Known->second; StringRef CanonicalName(Dir->getName()); + +#ifdef LLVM_ON_UNIX char CanonicalNameBuf[PATH_MAX]; if (realpath(Dir->getName(), CanonicalNameBuf)) { unsigned Len = strlen(CanonicalNameBuf); @@ -529,12 +561,15 @@ StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) { memcpy(Mem, CanonicalNameBuf, Len); CanonicalName = StringRef(Mem, Len); } +#else + SmallString<256> CanonicalNameBuf(CanonicalName); + llvm::sys::fs::make_absolute(CanonicalNameBuf); + llvm::sys::path::native(CanonicalNameBuf); + removeDotPaths(CanonicalNameBuf); +#endif CanonicalDirNames.insert(std::make_pair(Dir, CanonicalName)); return CanonicalName; -#else - return StringRef(Dir->getName()); -#endif } void FileManager::PrintStats() const { |