Index: lld/trunk/Common/ErrorHandler.cpp =================================================================== --- lld/trunk/Common/ErrorHandler.cpp +++ lld/trunk/Common/ErrorHandler.cpp @@ -16,6 +16,7 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" #include +#include #if !defined(_MSC_VER) && !defined(__MINGW32__) #include @@ -84,8 +85,42 @@ [&](ErrorInfoBase &eib) { error(eib.message()); }); } -void ErrorHandler::print(StringRef s, raw_ostream::Colors c) { - *errorOS << logName << ": "; +static std::string getLocation(std::string msg, std::string defaultMsg) { + static std::vector Regexes{ + std::regex(R"(^undefined symbol:.*\n>>> referenced by (\S+):(\d+)\n.*)"), + std::regex(R"(^undefined symbol:.*\n>>> referenced by (.*):)"), + std::regex( + R"(^duplicate symbol: .*\n>>> defined in (\S+)\n>>> defined in.*)"), + std::regex( + R"(^duplicate symbol: .*\n>>> defined at (\S+):(\d+).*)"), + std::regex( + R"(.*\n>>> defined in .*\n>>> referenced by (\S+):(\d+))"), + std::regex( + R"(^undefined (internal|hidden|protected) symbol: .*\n>>> referenced by (\S+):(\d+)\n.*)"), + std::regex(R"((\S+):(\d+): unclosed quote)"), + }; + + std::smatch Match; + for (std::regex &Re : Regexes) { + if (std::regex_search(msg, Match, Re)) { + return Match.size() > 2 ? Match.str(1) + "(" + Match.str(2) + ")" + : Match.str(1); + } + } + return defaultMsg; +} + +void ErrorHandler::printHeader(StringRef s, raw_ostream::Colors c, + const Twine &msg) { + + if (vsDiagnostics) { + // A Visual Studio-style error message starts with an error location. + // If a location cannot be extracted then we default to LogName. + *errorOS << getLocation(msg.str(), logName) << ": "; + } else { + *errorOS << logName << ": "; + } + if (colorDiagnostics) { errorOS->changeColor(c, true); *errorOS << s; @@ -116,7 +151,7 @@ std::lock_guard lock(mu); newline(errorOS, msg); - print("warning: ", raw_ostream::MAGENTA); + printHeader("warning: ", raw_ostream::MAGENTA, msg); *errorOS << msg << "\n"; } @@ -125,10 +160,10 @@ newline(errorOS, msg); if (errorLimit == 0 || errorCount < errorLimit) { - print("error: ", raw_ostream::RED); + printHeader("error: ", raw_ostream::RED, msg); *errorOS << msg << "\n"; } else if (errorCount == errorLimit) { - print("error: ", raw_ostream::RED); + printHeader("error: ", raw_ostream::RED, msg); *errorOS << errorLimitExceededMsg << "\n"; if (exitEarly) exitLld(1); Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -786,6 +786,8 @@ errorHandler().verbose = args.hasArg(OPT_verbose); errorHandler().fatalWarnings = args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); + errorHandler().vsDiagnostics = + args.hasArg(OPT_visual_studio_diagnostics_format, false); threadsEnabled = args.hasFlag(OPT_threads, OPT_no_threads, true); config->allowMultipleDefinition = Index: lld/trunk/ELF/Options.td =================================================================== --- lld/trunk/ELF/Options.td +++ lld/trunk/ELF/Options.td @@ -416,6 +416,9 @@ def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"