Index: include/llvm/Support/SourceMgr.h =================================================================== --- include/llvm/Support/SourceMgr.h +++ include/llvm/Support/SourceMgr.h @@ -47,6 +47,25 @@ DK_Note, }; + enum TextDiagnosticFormat { Clang, MSVC, Vi }; + TextDiagnosticFormat DiagnosticFormat = TextDiagnosticFormat::Clang; + enum MSVCVersion { + MSVC40 = 1000, + MSVC97 = 1100, + MSVC60 = 1200, + MSVC2002 = 1300, + MSVC2003 = 1310, + MSVC2005 = 1400, + MSVC2008 = 1500, + MSVC2010 = 1600, + MSVC2012 = 1700, + MSVC2013 = 1800, + MSVC2015 = 1900, + MSVC2017 = 1910 + }; + MSVCVersion MsvcVersion = MSVCVersion::MSVC2017; + bool ShowColumn = true; + /// Clients that want to handle their own diagnostics in a custom way can /// register a function pointer+context as a diagnostic handler. /// It gets called each time PrintMessage is invoked. @@ -241,6 +260,11 @@ std::vector> Ranges; SmallVector FixIts; + SourceMgr::TextDiagnosticFormat DiagnosticFormat = + SourceMgr::TextDiagnosticFormat::Clang; + SourceMgr::MSVCVersion MsvcVersion = SourceMgr::MSVCVersion::MSVC2017; + bool ShowColumn = true; + public: // Null diagnostic. SMDiagnostic() = default; Index: lib/Support/SourceMgr.cpp =================================================================== --- lib/Support/SourceMgr.cpp +++ lib/Support/SourceMgr.cpp @@ -239,14 +239,15 @@ // SMDiagnostic Implementation //===----------------------------------------------------------------------===// -SMDiagnostic::SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, - int Line, int Col, SourceMgr::DiagKind Kind, - StringRef Msg, StringRef LineStr, - ArrayRef> Ranges, +SMDiagnostic::SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line, + int Col, SourceMgr::DiagKind Kind, StringRef Msg, + StringRef LineStr, + ArrayRef> Ranges, ArrayRef Hints) - : SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Kind(Kind), - Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()), - FixIts(Hints.begin(), Hints.end()) { + : SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Kind(Kind), + Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()), + FixIts(Hints.begin(), Hints.end()), DiagnosticFormat(sm.DiagnosticFormat), + MsvcVersion(sm.MsvcVersion), ShowColumn(sm.ShowColumn) { std::sort(FixIts.begin(), FixIts.end()); } @@ -359,12 +360,55 @@ else S << Filename; - if (LineNo != -1) { - S << ':' << LineNo; - if (ColumnNo != -1) - S << ':' << (ColumnNo+1); + if (!SM) { + if (LineNo != -1) { + S << ':' << LineNo; + if (ColumnNo != -1) + S << ':' << (ColumnNo + 1); + } + } else if (LineNo != -1) { + switch (DiagnosticFormat) { + default: + case SourceMgr::TextDiagnosticFormat::Clang: + S << ':' << LineNo; + break; + case SourceMgr::TextDiagnosticFormat::MSVC: + S << '(' << LineNo; + break; + case SourceMgr::TextDiagnosticFormat::Vi: + S << " +" << LineNo; + break; + } + if (ShowColumn && (ColumnNo != -1)) { + int ColumnNoOffs = 0; + if (DiagnosticFormat == SourceMgr::TextDiagnosticFormat::MSVC) { + S << ','; + // Visual Studio 2010 or earlier expects column number to be off by + // one + if (MsvcVersion <= SourceMgr::MSVCVersion::MSVC2010) + ColumnNoOffs = 1; + } else + S << ':'; + S << ((ColumnNo + 1) - ColumnNoOffs); + } + switch (DiagnosticFormat) { + default: + case SourceMgr::TextDiagnosticFormat::Clang: + case SourceMgr::TextDiagnosticFormat::Vi: + S << ": "; + break; + case SourceMgr::TextDiagnosticFormat::MSVC: + // MSVC2013 and before print 'file(4) : error'. MSVC2015 gets rid of the + // space and prints 'file(4): error'. + if (MsvcVersion < SourceMgr::MSVCVersion::MSVC2015) + S << ") : "; + else + S << "): "; + break; + } + } else { + S << ": "; } - S << ": "; } if (ShowKindLabel) {