@@ -651,34 +651,48 @@ void FileManager::GetUniqueIDMapping(
651651}
652652
653653StringRef FileManager::getCanonicalName (const DirectoryEntry *Dir) {
654- llvm::DenseMap<const void *, llvm::StringRef>::iterator Known
655- = CanonicalNames.find (Dir);
656- if (Known != CanonicalNames.end ())
657- return Known->second ;
658-
659- StringRef CanonicalName (Dir->getName ());
660-
661- SmallString<4096 > CanonicalNameBuf;
662- if (!FS->getRealPath (Dir->getName (), CanonicalNameBuf))
663- CanonicalName = CanonicalNameBuf.str ().copy (CanonicalNameStorage);
664-
665- CanonicalNames.insert ({Dir, CanonicalName});
666- return CanonicalName;
654+ return getCanonicalName (Dir, Dir->getName ());
667655}
668656
669657StringRef FileManager::getCanonicalName (const FileEntry *File) {
670- llvm::DenseMap<const void *, llvm::StringRef>::iterator Known
671- = CanonicalNames.find (File);
658+ return getCanonicalName (File, File->getName ());
659+ }
660+
661+ StringRef FileManager::getCanonicalName (const void *Entry, StringRef Name) {
662+ llvm::DenseMap<const void *, llvm::StringRef>::iterator Known =
663+ CanonicalNames.find (Entry);
672664 if (Known != CanonicalNames.end ())
673665 return Known->second ;
674666
675- StringRef CanonicalName (File->getName ());
676-
677- SmallString<4096 > CanonicalNameBuf;
678- if (!FS->getRealPath (File->getName (), CanonicalNameBuf))
679- CanonicalName = CanonicalNameBuf.str ().copy (CanonicalNameStorage);
667+ // Name comes from FileEntry/DirectoryEntry::getName(), so it is safe to
668+ // store it in the DenseMap below.
669+ StringRef CanonicalName (Name);
670+
671+ SmallString<256 > AbsPathBuf;
672+ SmallString<256 > RealPathBuf;
673+ if (!FS->getRealPath (Name, RealPathBuf)) {
674+ if (is_style_windows (llvm::sys::path::Style::native)) {
675+ // For Windows paths, only use the real path if it doesn't resolve
676+ // a substitute drive, as those are used to avoid MAX_PATH issues.
677+ AbsPathBuf = Name;
678+ if (!FS->makeAbsolute (AbsPathBuf)) {
679+ if (llvm::sys::path::root_name (RealPathBuf) ==
680+ llvm::sys::path::root_name (AbsPathBuf)) {
681+ CanonicalName = RealPathBuf.str ().copy (CanonicalNameStorage);
682+ } else {
683+ // Fallback to using the absolute path.
684+ // Simplifying /../ is semantically valid on Windows even in the
685+ // presence of symbolic links.
686+ llvm::sys::path::remove_dots (AbsPathBuf, /* remove_dot_dot=*/ true );
687+ CanonicalName = AbsPathBuf.str ().copy (CanonicalNameStorage);
688+ }
689+ }
690+ } else {
691+ CanonicalName = RealPathBuf.str ().copy (CanonicalNameStorage);
692+ }
693+ }
680694
681- CanonicalNames.insert ({File , CanonicalName});
695+ CanonicalNames.insert ({Entry , CanonicalName});
682696 return CanonicalName;
683697}
684698
0 commit comments