@@ -2390,3 +2390,75 @@ SourceManagerForFile::SourceManagerForFile(StringRef FileName,
23902390 assert (ID.isValid ());
23912391 SourceMgr->setMainFileID (ID);
23922392}
2393+
2394+ StringRef
2395+ SourceManager::getNameForDiagnostic (StringRef Filename,
2396+ const DiagnosticOptions &Opts) const {
2397+ OptionalFileEntryRef File = getFileManager ().getOptionalFileRef (Filename);
2398+ if (!File)
2399+ return Filename;
2400+
2401+ bool SimplifyPath = [&] {
2402+ if (Opts.AbsolutePath )
2403+ return true ;
2404+
2405+ // Try to simplify paths that contain '..' in any case since paths to
2406+ // standard library headers especially tend to get quite long otherwise.
2407+ // Only do that for local filesystems though to avoid slowing down
2408+ // compilation too much.
2409+ if (!File->getName ().contains (" .." ))
2410+ return false ;
2411+
2412+ // If we're not on Windows, check if we're on a network file system and
2413+ // avoid simplifying the path in that case since that can be slow. On
2414+ // Windows, the check for a local filesystem is already slow, so skip it.
2415+ #ifndef _WIN32
2416+ if (!llvm::sys::fs::is_local (File->getName ()))
2417+ return false ;
2418+ #endif
2419+
2420+ return true ;
2421+ }();
2422+
2423+ if (!SimplifyPath)
2424+ return Filename;
2425+
2426+ // This may involve computing canonical names, so cache the result.
2427+ StringRef &CacheEntry = DiagNames[Filename];
2428+ if (!CacheEntry.empty ())
2429+ return CacheEntry;
2430+
2431+ // We want to print a simplified absolute path, i. e. without "dots".
2432+ //
2433+ // The hardest part here are the paths like "<part1>/<link>/../<part2>".
2434+ // On Unix-like systems, we cannot just collapse "<link>/..", because
2435+ // paths are resolved sequentially, and, thereby, the path
2436+ // "<part1>/<part2>" may point to a different location. That is why
2437+ // we use FileManager::getCanonicalName(), which expands all indirections
2438+ // with llvm::sys::fs::real_path() and caches the result.
2439+ //
2440+ // On the other hand, it would be better to preserve as much of the
2441+ // original path as possible, because that helps a user to recognize it.
2442+ // real_path() expands all links, which sometimes too much. Luckily,
2443+ // on Windows we can just use llvm::sys::path::remove_dots(), because,
2444+ // on that system, both aforementioned paths point to the same place.
2445+ SmallString<256 > TempBuf;
2446+ #ifdef _WIN32
2447+ TempBuf = File->getName ();
2448+ llvm::sys::fs::make_absolute (TempBuf);
2449+ llvm::sys::path::native (TempBuf);
2450+ llvm::sys::path::remove_dots (TempBuf, /* remove_dot_dot */ true );
2451+ #else
2452+ TempBuf = getFileManager ().getCanonicalName (*File);
2453+ #endif
2454+
2455+ // In some cases, the resolved path may actually end up being longer (e.g.
2456+ // if it was originally a relative path), so just retain whichever one
2457+ // ends up being shorter.
2458+ if (!Opts.AbsolutePath && TempBuf.size () > Filename.size ())
2459+ CacheEntry = Filename;
2460+ else
2461+ CacheEntry = TempBuf.str ().copy (DiagNameAlloc);
2462+
2463+ return CacheEntry;
2464+ }
0 commit comments