<div dir="ltr"><div class="gmail_quote"><div dir="ltr"><div>Greetings, clangspeople,</div><div><br></div><div>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.</div><div><br></div><div>I have tried passing a raw_string_ostream 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).</div><div><br></div><div>Thanks,</div><div>Geoff</div><div><br></div><div><br></div><div><div><font face="monospace, monospace"> IntrusiveRefCntPtr<DiagnosticOptions> diag_opts(new DiagnosticOptions);</font></div><div><font face="monospace, monospace"> std::string diagnostics;</font></div><div><font face="monospace, monospace"> raw_string_ostream diag_stream(diagnostics);</font></div><div><font face="monospace, monospace"> TextDiagnosticPrinter *diag_client =</font></div><div><font face="monospace, monospace"> new TextDiagnosticPrinter(diag_stream, diag_opts.get());</font></div><div><font face="monospace, monospace"> IntrusiveRefCntPtr<DiagnosticIDs> diag_ids(new DiagnosticIDs);</font></div><div><font face="monospace, monospace"> DiagnosticsEngine diags(diag_ids, diag_opts.get(), diag_client);</font></div><div><span style="font-family:monospace,monospace"> Driver driver(executable, llvm::sys::getDefaultTargetTriple(), diags);</span><br></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> SmallVector<const char*, 16> args;</font></div><div><font face="monospace, monospace"> // various arguments...</font></div><div><font face="monospace, monospace"><br></font></div><div><span style="font-family:monospace,monospace"> std::unique_ptr<Compilation> compilation(driver.BuildCompilation(args));</span><br></div><div><font face="monospace, monospace"> const JobList& jobs = compilation->getJobs();</font></div><div><span style="font-family:monospace,monospace"> const Command& cmd = llvm::cast<Command>(*jobs.begin());</span><br></div><div><span style="font-family:monospace,monospace"> const ArgStringList& ccargs = cmd.getArguments();</span><br></div><div><font face="monospace, monospace"> std::unique_ptr<CompilerInvocation> invocation(new CompilerInvocation);</font></div><div><font face="monospace, monospace"> CompilerInvocation::CreateFromArgs(</font></div><div><font face="monospace, monospace"> *invocation,</font></div><div><font face="monospace, monospace"> const_cast<const char**>(ccargs.data()),</font></div><div><font face="monospace, monospace"> const_cast<const char**>(ccargs.data()) + ccargs.size(),</font></div><div><font face="monospace, monospace"> diags);</font></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace"> CompilerInstance clang;</span><br></div><div><font face="monospace, monospace"> clang.setInvocation(std::move(invocation));</font></div><div><font face="monospace, monospace"> clang.createDiagnostics();</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> std::unique_ptr<CodeGenAction> action(</font></div><div><font face="monospace, monospace"> new EmitLLVMOnlyAction(&my_llvm_context));</font></div><div><font face="monospace, monospace"> if (!clang.ExecuteAction(*action)) {</font></div><div><font face="monospace, monospace"> if (diag_stream.str().empty()) {</font></div><div><font face="monospace, monospace"> setError("Compilation failed: see standard error for details.");</font></div><div><font face="monospace, monospace"> } else {</font></div><div><font face="monospace, monospace"> setError("Compilation failed:\n" + diag_stream.str());</font></div><div><font face="monospace, monospace"> }</font></div></div><div><font face="monospace, monospace"> }</font></div><div><br></div></div>
</div></div>