@@ -651,34 +651,48 @@ void FileManager::GetUniqueIDMapping(
651
651
}
652
652
653
653
StringRef 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 ());
667
655
}
668
656
669
657
StringRef 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);
672
664
if (Known != CanonicalNames.end ())
673
665
return Known->second ;
674
666
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
+ }
680
694
681
- CanonicalNames.insert ({File , CanonicalName});
695
+ CanonicalNames.insert ({Entry , CanonicalName});
682
696
return CanonicalName;
683
697
}
684
698
0 commit comments