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>