diff options
author | Sirraide <aeternalmail@gmail.com> | 2025-07-08 01:02:19 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-08 01:02:19 +0200 |
commit | e3e7393c4681f31cd3820fdda2831a3e004a48f5 (patch) | |
tree | 2ffdcd5a104c9d3c39ed763a33eab7f18c8ea775 /clang/lib/Frontend | |
parent | c8850051c2414b899416e16222f5d96e854be563 (diff) | |
download | llvm-e3e7393c4681f31cd3820fdda2831a3e004a48f5.zip llvm-e3e7393c4681f31cd3820fdda2831a3e004a48f5.tar.gz llvm-e3e7393c4681f31cd3820fdda2831a3e004a48f5.tar.bz2 |
[Clang] [Diagnostics] Simplify filenames that contain '..' (#143520)
This can significantly shorten file paths to standard library headers,
e.g. on my system, `<ranges>` is currently printed as
```console
/usr/lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/ranges
```
but with this change, we instead print
```console
/usr/include/c++/15/ranges
```
This is of course just a heuristic; there are paths that would get longer
as a result of this, so we use whichever path ends up being shorter.
@AaronBallman pointed out that this might be problematic for network
file systems since path resolution might take a while, so this is enabled
only for paths that are part of a local filesystem—though not on Windows
since there we noticed that the check itself is slow.
The file names are cached in `SourceManager`.
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r-- | clang/lib/Frontend/SARIFDiagnostic.cpp | 31 | ||||
-rw-r--r-- | clang/lib/Frontend/TextDiagnostic.cpp | 34 |
2 files changed, 2 insertions, 63 deletions
diff --git a/clang/lib/Frontend/SARIFDiagnostic.cpp b/clang/lib/Frontend/SARIFDiagnostic.cpp index ac27d74..f971401 100644 --- a/clang/lib/Frontend/SARIFDiagnostic.cpp +++ b/clang/lib/Frontend/SARIFDiagnostic.cpp @@ -163,36 +163,7 @@ SARIFDiagnostic::addDiagnosticLevelToRule(SarifRule Rule, llvm::StringRef SARIFDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) { - if (DiagOpts.AbsolutePath) { - auto File = SM.getFileManager().getOptionalFileRef(Filename); - if (File) { - // We want to print a simplified absolute path, i. e. without "dots". - // - // The hardest part here are the paths like "<part1>/<link>/../<part2>". - // On Unix-like systems, we cannot just collapse "<link>/..", because - // paths are resolved sequentially, and, thereby, the path - // "<part1>/<part2>" may point to a different location. That is why - // we use FileManager::getCanonicalName(), which expands all indirections - // with llvm::sys::fs::real_path() and caches the result. - // - // On the other hand, it would be better to preserve as much of the - // original path as possible, because that helps a user to recognize it. - // real_path() expands all links, which is sometimes too much. Luckily, - // on Windows we can just use llvm::sys::path::remove_dots(), because, - // on that system, both aforementioned paths point to the same place. -#ifdef _WIN32 - SmallString<256> TmpFilename = File->getName(); - llvm::sys::fs::make_absolute(TmpFilename); - llvm::sys::path::native(TmpFilename); - llvm::sys::path::remove_dots(TmpFilename, /* remove_dot_dot */ true); - Filename = StringRef(TmpFilename.data(), TmpFilename.size()); -#else - Filename = SM.getFileManager().getCanonicalName(*File); -#endif - } - } - - return Filename; + return SM.getNameForDiagnostic(Filename, DiagOpts); } /// Print out the file/line/column information and include trace. diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index ccdd59d..e5bf867 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -738,39 +738,7 @@ void TextDiagnostic::printDiagnosticMessage(raw_ostream &OS, } void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) { -#ifdef _WIN32 - SmallString<4096> TmpFilename; -#endif - if (DiagOpts.AbsolutePath) { - auto File = SM.getFileManager().getOptionalFileRef(Filename); - if (File) { - // We want to print a simplified absolute path, i. e. without "dots". - // - // The hardest part here are the paths like "<part1>/<link>/../<part2>". - // On Unix-like systems, we cannot just collapse "<link>/..", because - // paths are resolved sequentially, and, thereby, the path - // "<part1>/<part2>" may point to a different location. That is why - // we use FileManager::getCanonicalName(), which expands all indirections - // with llvm::sys::fs::real_path() and caches the result. - // - // On the other hand, it would be better to preserve as much of the - // original path as possible, because that helps a user to recognize it. - // real_path() expands all links, which sometimes too much. Luckily, - // on Windows we can just use llvm::sys::path::remove_dots(), because, - // on that system, both aforementioned paths point to the same place. -#ifdef _WIN32 - TmpFilename = File->getName(); - llvm::sys::fs::make_absolute(TmpFilename); - llvm::sys::path::native(TmpFilename); - llvm::sys::path::remove_dots(TmpFilename, /* remove_dot_dot */ true); - Filename = StringRef(TmpFilename.data(), TmpFilename.size()); -#else - Filename = SM.getFileManager().getCanonicalName(*File); -#endif - } - } - - OS << Filename; + OS << SM.getNameForDiagnostic(Filename, DiagOpts); } /// Print out the file/line/column information and include trace. |