Index: lld/trunk/Common/ErrorHandler.cpp =================================================================== --- lld/trunk/Common/ErrorHandler.cpp +++ lld/trunk/Common/ErrorHandler.cpp @@ -153,13 +153,34 @@ *errorOS << msg << "\n"; } +void ErrorHandler::printErrorMsg(const Twine &msg) { + newline(errorOS, msg); + printHeader("error: ", raw_ostream::RED, msg); + *errorOS << msg << "\n"; +} + +void ErrorHandler::printError(const Twine &msg) { + if (vsDiagnostics) { + static std::regex reDuplicateSymbol( + R"(^(duplicate symbol: .*))" + R"((\n>>> defined at \S+:\d+\n>>>.*))" + R"((\n>>> defined at \S+:\d+\n>>>.*))"); + std::string msgStr = msg.str(); + std::smatch match; + if (std::regex_match(msgStr, match, reDuplicateSymbol)) { + printErrorMsg(match.str(1) + match.str(2)); + printErrorMsg(match.str(1) + match.str(3)); + return; + } + } + printErrorMsg(msg); +} + void ErrorHandler::error(const Twine &msg) { std::lock_guard lock(mu); if (errorLimit == 0 || errorCount < errorLimit) { - newline(errorOS, msg); - printHeader("error: ", raw_ostream::RED, msg); - *errorOS << msg << "\n"; + printError(msg); } else if (errorCount == errorLimit) { newline(errorOS, msg); printHeader("error: ", raw_ostream::RED, msg); Index: lld/trunk/include/lld/Common/ErrorHandler.h =================================================================== --- lld/trunk/include/lld/Common/ErrorHandler.h +++ lld/trunk/include/lld/Common/ErrorHandler.h @@ -103,6 +103,8 @@ private: void printHeader(StringRef s, raw_ostream::Colors c, const Twine &msg); + void printErrorMsg(const Twine &msg); + void printError(const Twine &msg); }; /// Returns the default error handler. Index: lld/trunk/test/ELF/vs-diagnostics-duplicate.s =================================================================== --- lld/trunk/test/ELF/vs-diagnostics-duplicate.s +++ lld/trunk/test/ELF/vs-diagnostics-duplicate.s @@ -8,8 +8,9 @@ // CHECK: duplicate.s(15): error: duplicate symbol: bar // CHECK-NEXT: >>> defined at duplicate.s:15 // CHECK-NEXT: >>>{{.*}}1.o:(.text+0x{{.+}}) -// CHECK: >>> defined at duplicate2.s:20 -// CHECK: >>>{{.*}}2.o:(.text+0x{{.+}}) +// CHECK: duplicate2.s(20): error: duplicate symbol: bar +// CHECK-NEXT: >>> defined at duplicate2.s:20 +// CHECK-NEXT: >>>{{.*}}2.o:(.text+0x{{.+}}) // Case 2. The source locations are unknown for both symbols. // CHECK: {{.*}}ld.lld{{.*}}: error: duplicate symbol: foo