diff --git a/clang/test/Frontend/sarif-diagnostics.cpp b/clang/test/Frontend/sarif-diagnostics.cpp --- a/clang/test/Frontend/sarif-diagnostics.cpp +++ b/clang/test/Frontend/sarif-diagnostics.cpp @@ -29,9 +29,26 @@ #include "sarif-diagnostics.hpp" -// RUN: %clang -fsyntax-only -Wall -Wextra -fdiagnostics-format=sarif %s > %t.txt 2>&1 || true +// RUN: %clang -fsyntax-only -Wall -Wextra -fdiagnostics-format=sarif-stderr %s > %t.txt 2>&1 || true // RUN: FileCheck -dump-input=always %s --input-file=%t.txt --check-prefixes=STDERR,SARIF +// RUN: %clang -fsyntax-only -Wall -Wextra -fdiagnostics-format=sarif-file %s > %t.txt 2>&1 || true +// RUN: FileCheck -dump-input=always --check-prefix=STDERR %s --input-file=%t.txt +// RUN: FileCheck -dump-input=always --check-prefix=SARIF %s --input-file=sarif-diagnostics.cpp.sarif + +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: %clang -Wall -Wextra -fdiagnostics-format=sarif-file %s -o %t/sarif-output > %t.txt 2>&1 || true +// RUN: FileCheck -dump-input=always --check-prefix=STDERR %s --input-file=%t.txt +// RUN: FileCheck -dump-input=always --check-prefix=SARIF %s --input-file=%t/sarif-output_sarif/0.sarif + +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: %clang -Wall -Wextra -fdiagnostics-format=sarif-file %s %s -o %t/sarif-output > %t.txt 2>&1 || true +// RUN: FileCheck -dump-input=always --check-prefix=STDERR %s --input-file=%t.txt +// RUN: FileCheck -dump-input=always --check-prefix=SARIF %s --input-file=%t/sarif-output_sarif/0.sarif +// RUN: FileCheck -dump-input=always --check-prefix=SARIF %s --input-file=%t/sarif-output_sarif/1.sarif + // STDERR: warning: diagnostic formatting in SARIF mode is currently unstable [-Wsarif-format-unstable] // SARIF: { // SARIF: "$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json", diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -372,6 +372,35 @@ return 1; } +static std::error_code MoveSarifDiagnostics(ArrayRef InputPaths, std::string OutputPath) +{ + if (InputPaths.size() == 0) + return std::error_code(); + + std::vector SarifDiagnosticPaths; + llvm::copy_if(InputPaths, std::back_inserter(SarifDiagnosticPaths), [](StringRef File) { + return File.ends_with(".o"); + }); + llvm::transform(SarifDiagnosticPaths, SarifDiagnosticPaths.begin(), [](StringRef Temp) { + return (Temp + ".sarif").str(); + }); + + namespace fs = llvm::sys::fs; + OutputPath += "_sarif/"; + if (std::error_code EC = fs::remove_directories(OutputPath)) + return EC; + + if (std::error_code EC = fs::create_directories(OutputPath)) + return EC; + + std::size_t i = 0; + for (StringRef Path : SarifDiagnosticPaths) + if (std::error_code EC = fs::rename(Path, OutputPath + std::to_string(i++) + ".sarif")) + return EC; + + return std::error_code(); +} + int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) { noteBottomOfStack(); llvm::InitLLVM X(Argc, Argv); @@ -634,6 +663,17 @@ Res = 1; #endif + // Finally, we need to move any SARIF diagnostics into the build directory. + const DerivedArgList& ArgList = C->getArgs(); + if (Arg* DF = ArgList.getLastArg(options::OPT_fdiagnostics_format_EQ); DF && DF->containsValue("sarif-file")) { + Arg* o = ArgList.getLastArg(options::OPT_o); + const char* Out = o ? o->getValue(0) : TheDriver.getDefaultImageName(); + if (std::error_code EC = MoveSarifDiagnostics(C->getTempFiles(), Out)) { + llvm::errs() << EC.message() << '\n'; + return EC.value(); + } + } + // If we have multiple failing commands, we return the result of the first // failing command. return Res;