Geoff Levner via llvm-dev
2018-Aug-26 11:22 UTC
[llvm-dev] warnings and error messages always go to standard error
Greeting, LLVM wizards,
We are using Clang and LLVM in an application to compile and execute C++
code on the fly. If the code fails to compile, I would like to be able to
pop up a dialog box telling the user why. But warnings and error messages
go straight to standard error.
I have tried passing a raw_string_stream to TextDiagnosticPrinter instead
of errs(), but that seems to have no effect. What is that stream actually
used for? Am I doing something wrong? I have attached the code we use to
compile (simplified a bit).
Thanks,
Geoff
IntrusiveRefCntPtr<DiagnosticOptions> diag_opts(new
DiagnosticOptions);
std::string diagnostics;
raw_string_ostream diag_stream(diagnostics);
TextDiagnosticPrinter *diag_client new
TextDiagnosticPrinter(diag_stream, diag_opts.get());
IntrusiveRefCntPtr<DiagnosticIDs> diag_ids(new DiagnosticIDs);
DiagnosticsEngine diags(diag_ids, diag_opts.get(), diag_client);
Driver driver(executable, llvm::sys::getDefaultTargetTriple(), diags);
SmallVector<const char*, 16> args;
// various arguments...
std::unique_ptr<Compilation>
compilation(driver.BuildCompilation(args));
const JobList& jobs = compilation->getJobs();
const Command& cmd = llvm::cast<Command>(*jobs.begin());
const ArgStringList& ccargs = cmd.getArguments();
std::unique_ptr<CompilerInvocation> invocation(new
CompilerInvocation);
CompilerInvocation::CreateFromArgs(
*invocation,
const_cast<const char**>(ccargs.data()),
const_cast<const char**>(ccargs.data()) + ccargs.size(),
diags);
CompilerInstance clang;
clang.setInvocation(std::move(invocation));
clang.createDiagnostics();
std::unique_ptr<CodeGenAction> action(
new EmitLLVMOnlyAction(&my_llvm_context));
if (!clang.ExecuteAction(*action)) {
if (diag_stream.str().empty()) {
setError("Compilation failed: see standard error for
details.");
} else {
setError("Compilation failed:\n" + diag_stream.str());
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20180826/c1c41223/attachment.html>
Geoff Levner via llvm-dev
2018-Aug-28 21:06 UTC
[llvm-dev] warnings and error messages always go to standard error
Well, if anybody on this list is interested, the solution was pointed out to me by Eli Friedman on the cfe-dev list (it is in fact a Clang problem). The DiagnosticsEngine passed to the Driver is used only by the Driver itself, not by the resulting compilation. To retrieve the diagnostics from the compilation, I have to pass my TextDiagnosticPrinter to CompilerInstance::createDiagnostics(). Thanks to Eli. On Sun, 26 Aug 2018 at 13:22, Geoff Levner <glevner at gmail.com> wrote:> Greeting, LLVM wizards, > > We are using Clang and LLVM in an application to compile and execute C++ > code on the fly. If the code fails to compile, I would like to be able to > pop up a dialog box telling the user why. But warnings and error messages > go straight to standard error. > > I have tried passing a raw_string_stream to TextDiagnosticPrinter instead > of errs(), but that seems to have no effect. What is that stream actually > used for? Am I doing something wrong? I have attached the code we use to > compile (simplified a bit). > > Thanks, > Geoff > > > IntrusiveRefCntPtr<DiagnosticOptions> diag_opts(new DiagnosticOptions); > std::string diagnostics; > raw_string_ostream diag_stream(diagnostics); > TextDiagnosticPrinter *diag_client > new TextDiagnosticPrinter(diag_stream, diag_opts.get()); > IntrusiveRefCntPtr<DiagnosticIDs> diag_ids(new DiagnosticIDs); > DiagnosticsEngine diags(diag_ids, diag_opts.get(), diag_client); > Driver driver(executable, llvm::sys::getDefaultTargetTriple(), diags); > > SmallVector<const char*, 16> args; > // various arguments... > > std::unique_ptr<Compilation> > compilation(driver.BuildCompilation(args)); > const JobList& jobs = compilation->getJobs(); > const Command& cmd = llvm::cast<Command>(*jobs.begin()); > const ArgStringList& ccargs = cmd.getArguments(); > std::unique_ptr<CompilerInvocation> invocation(new CompilerInvocation); > CompilerInvocation::CreateFromArgs( > *invocation, > const_cast<const char**>(ccargs.data()), > const_cast<const char**>(ccargs.data()) + ccargs.size(), > diags); > > CompilerInstance clang; > clang.setInvocation(std::move(invocation)); > clang.createDiagnostics(); > > std::unique_ptr<CodeGenAction> action( > new EmitLLVMOnlyAction(&my_llvm_context)); > if (!clang.ExecuteAction(*action)) { > if (diag_stream.str().empty()) { > setError("Compilation failed: see standard error for > details."); > } else { > setError("Compilation failed:\n" + diag_stream.str()); > } > } > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180828/65088e61/attachment.html>