Index: include/clang/Basic/FileManager.h =================================================================== --- include/clang/Basic/FileManager.h +++ include/clang/Basic/FileManager.h @@ -173,6 +173,10 @@ /// or a directory) as virtual directories. void addAncestorsAsVirtualDirs(StringRef Path); + /// Fills the RealPathName entry in UFE by converting the given filename to an + /// absolute path, returns true if FileName was modified. + bool fillRealPathName(FileEntry *UFE, llvm::StringRef FileName); + public: FileManager(const FileSystemOptions &FileSystemOpts, IntrusiveRefCntPtr FS = nullptr); Index: lib/Basic/FileManager.cpp =================================================================== --- lib/Basic/FileManager.cpp +++ lib/Basic/FileManager.cpp @@ -293,16 +293,8 @@ // If we opened the file for the first time, record the resulting info. // Do this even if the cache entry was valid, maybe we didn't previously open. if (F && !UFE.File) { - if (auto PathName = F->getName()) { - llvm::SmallString<128> AbsPath(*PathName); - // This is not the same as `VFS::getRealPath()`, which resolves symlinks - // but can be very expensive on real file systems. - // FIXME: the semantic of RealPathName is unclear, and the name might be - // misleading. We need to clean up the interface here. - makeAbsolutePath(AbsPath); - llvm::sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true); - UFE.RealPathName = AbsPath.str(); - } + if (auto PathName = F->getName()) + fillRealPathName(&UFE, *PathName); UFE.File = std::move(F); assert(!UFE.DeferredOpen && "we just opened it!"); } @@ -395,6 +387,7 @@ UFE->UniqueID = Data.UniqueID; UFE->IsNamedPipe = Data.IsNamedPipe; UFE->InPCH = Data.InPCH; + fillRealPathName(UFE, Data.Name); } if (!UFE) { @@ -438,6 +431,18 @@ return Changed; } +bool FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) { + llvm::SmallString<128> AbsPath(FileName); + // This is not the same as `VFS::getRealPath()`, which resolves symlinks + // but can be very expensive on real file systems. + // FIXME: the semantic of RealPathName is unclear, and the name might be + // misleading. We need to clean up the interface here. + bool Changed = makeAbsolutePath(AbsPath); + llvm::sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true); + UFE->RealPathName = AbsPath.str(); + return Changed; +} + llvm::ErrorOr> FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile, bool ShouldCloseOpenFile) {