Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/include/clang/Frontend/TextDiagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace clang {
class TextDiagnostic : public DiagnosticRenderer {
raw_ostream &OS;
const Preprocessor *PP;
llvm::StringMap<SmallString<128>> SimplifiedFileNameCache;

public:
TextDiagnostic(raw_ostream &OS, const LangOptions &LangOpts,
Expand Down
38 changes: 26 additions & 12 deletions clang/lib/Frontend/TextDiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -738,12 +738,20 @@ 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) {
auto File = SM.getFileManager().getOptionalFileRef(Filename);

// Try to simplify paths that contain '..' in any case since paths to
// standard library headers especially tend to get quite long otherwise.
// Only do that for local filesystems though to avoid slowing down
// compilation too much.
auto AlwaysSimplify = [&] {
return File->getName().contains("..") &&
llvm::sys::fs::is_local(File->getName());
};

if (File && (DiagOpts.AbsolutePath || AlwaysSimplify())) {
SmallString<128> &CacheEntry = SimplifiedFileNameCache[Filename];
if (CacheEntry.empty()) {
// We want to print a simplified absolute path, i. e. without "dots".
//
// The hardest part here are the paths like "<part1>/<link>/../<part2>".
Expand All @@ -759,15 +767,21 @@ void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) {
// 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());
CacheEntry = File->getName();
llvm::sys::fs::make_absolute(CacheEntry);
llvm::sys::path::native(CacheEntry);
llvm::sys::path::remove_dots(CacheEntry, /* remove_dot_dot */ true);
#else
Filename = SM.getFileManager().getCanonicalName(*File);
CacheEntry = SM.getFileManager().getCanonicalName(*File);
#endif

// In some cases, the resolved path may actually end up being longer (e.g.
// if it was originally a relative path), so just retain whichever one
// ends up being shorter.
if (!DiagOpts.AbsolutePath && CacheEntry.size() > Filename.size())
CacheEntry = Filename;
}
Filename = CacheEntry;
}

OS << Filename;
Expand Down
Loading