Skip to content

Commit 15c0a79

Browse files
committed
[Clang] [Diagnostics] Simplify filenames that contain '..'
1 parent 97a32f2 commit 15c0a79

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

clang/include/clang/Frontend/TextDiagnostic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ namespace clang {
3535
class TextDiagnostic : public DiagnosticRenderer {
3636
raw_ostream &OS;
3737
const Preprocessor *PP;
38+
llvm::StringMap<SmallString<128>> SimplifiedFileNameCache;
3839

3940
public:
4041
TextDiagnostic(raw_ostream &OS, const LangOptions &LangOpts,

clang/lib/Frontend/TextDiagnostic.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -738,12 +738,20 @@ void TextDiagnostic::printDiagnosticMessage(raw_ostream &OS,
738738
}
739739

740740
void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) {
741-
#ifdef _WIN32
742-
SmallString<4096> TmpFilename;
743-
#endif
744-
if (DiagOpts.AbsolutePath) {
745-
auto File = SM.getFileManager().getOptionalFileRef(Filename);
746-
if (File) {
741+
auto File = SM.getFileManager().getOptionalFileRef(Filename);
742+
743+
// Try to simplify paths that contain '..' in any case since paths to
744+
// standard library headers especially tend to get quite long otherwise.
745+
// Only do that for local filesystems though to avoid slowing down
746+
// compilation too much.
747+
auto AlwaysSimplify = [&] {
748+
return File->getName().contains("..") &&
749+
llvm::sys::fs::is_local(File->getName());
750+
};
751+
752+
if (File && (DiagOpts.AbsolutePath || AlwaysSimplify())) {
753+
SmallString<128> &CacheEntry = SimplifiedFileNameCache[Filename];
754+
if (CacheEntry.empty()) {
747755
// We want to print a simplified absolute path, i. e. without "dots".
748756
//
749757
// The hardest part here are the paths like "<part1>/<link>/../<part2>".
@@ -759,15 +767,15 @@ void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) {
759767
// on Windows we can just use llvm::sys::path::remove_dots(), because,
760768
// on that system, both aforementioned paths point to the same place.
761769
#ifdef _WIN32
762-
TmpFilename = File->getName();
763-
llvm::sys::fs::make_absolute(TmpFilename);
764-
llvm::sys::path::native(TmpFilename);
765-
llvm::sys::path::remove_dots(TmpFilename, /* remove_dot_dot */ true);
766-
Filename = StringRef(TmpFilename.data(), TmpFilename.size());
770+
CacheEntry = File->getName();
771+
llvm::sys::fs::make_absolute(CacheEntry);
772+
llvm::sys::path::native(CacheEntry);
773+
llvm::sys::path::remove_dots(CacheEntry, /* remove_dot_dot */ true);
767774
#else
768-
Filename = SM.getFileManager().getCanonicalName(*File);
775+
CacheEntry = SM.getFileManager().getCanonicalName(*File);
769776
#endif
770777
}
778+
Filename = CacheEntry;
771779
}
772780

773781
OS << Filename;

0 commit comments

Comments
 (0)