<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Considering that there is no other viable possibility, for now I have gone with the following:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Menlo" class="">using llvm::Twine;</font></div><div class=""><font face="Menlo" class="">using llvm::SmallString;</font></div><div class=""><font face="Menlo" class="">using llvm::IntrusiveRefCntPtr;</font></div><div class=""><font face="Menlo" class="">using llvm::MemoryBuffer;</font></div><div class=""><font face="Menlo" class="">using clang::FileManager;</font></div><div class=""><font face="Menlo" class="">using clang::PCHContainerOperations;</font></div><div class=""><font face="Menlo" class="">using clang::FileSystemOptions;</font></div><div class=""><font face="Menlo" class="">using clang::tooling::ToolInvocation;</font></div><div class=""><font face="Menlo" class="">using clang::tooling::FileContentMappings;</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">static std::vector<std::string></font></div><div class=""><font face="Menlo" class="">getSyntaxOnlyToolArgs(const Twine &ToolName,</font></div><div class=""><font face="Menlo" class="">                      const std::vector<std::string> &ExtraArgs,</font></div><div class=""><font face="Menlo" class="">                      StringRef FileName) {</font></div><div class=""><font face="Menlo" class="">  std::vector<std::string> Args;</font></div><div class=""><font face="Menlo" class="">  Args.push_back(ToolName.str());</font></div><div class=""><font face="Menlo" class="">  Args.push_back("-fsyntax-only");</font></div><div class=""><font face="Menlo" class="">  Args.insert(Args.end(), ExtraArgs.begin(), ExtraArgs.end());</font></div><div class=""><font face="Menlo" class="">  Args.push_back(FileName.str());</font></div><div class=""><font face="Menlo" class="">  return Args;</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,</font></div><div class=""><font face="Menlo" class="">                   const Twine &FileName, <b class="">clang::DiagnosticConsumer& diagConsumer</b>)</font></div><div class=""><font face="Menlo" class="">{</font></div><div class=""><font face="Menlo" class="">  const std::vector<std::string> args;</font></div><div class=""><font face="Menlo" class="">  const Twine toolName = "clang-tool";</font></div><div class=""><font face="Menlo" class="">  std::shared_ptr<PCHContainerOperations> PCHContainerOps = std::make_shared<PCHContainerOperations>();</font></div><div class=""><font face="Menlo" class="">  const FileContentMappings virtualMappedFiles = FileContentMappings();</font></div><div class=""><font face="Menlo" class="">  </font></div><div class=""><font face="Menlo" class="">  SmallString<16> fileNameStorage;</font></div><div class=""><font face="Menlo" class="">  StringRef fileNameRef = FileName.toNullTerminatedStringRef(fileNameStorage);</font></div><div class=""><font face="Menlo" class="">  IntrusiveRefCntPtr<clang::vfs::OverlayFileSystem> OverlayFileSystem</font></div><div class=""><font face="Menlo" class="">    = new clang::vfs::OverlayFileSystem(clang::vfs::getRealFileSystem());</font></div><div class=""><font face="Menlo" class="">  IntrusiveRefCntPtr<clang::vfs::InMemoryFileSystem> inMemoryFileSystem</font></div><div class=""><font face="Menlo" class="">    = new clang::vfs::InMemoryFileSystem;</font></div><div class=""><font face="Menlo" class="">  OverlayFileSystem->pushOverlay(inMemoryFileSystem);</font></div><div class=""><font face="Menlo" class="">  IntrusiveRefCntPtr<FileManager> files(new FileManager(FileSystemOptions(), OverlayFileSystem));</font></div><div class=""><font face="Menlo" class="">  ToolInvocation invocation(getSyntaxOnlyToolArgs(toolName, args, fileNameRef),</font></div><div class=""><font face="Menlo" class="">                            ToolAction, files.get(), std::move(PCHContainerOps));</font></div><div class=""><font face="Menlo" class="">  <b class="">invocation.setDiagnosticConsumer(&diagConsumer);</b></font></div><div class=""><font face="Menlo" class="">  </font></div><div class=""><font face="Menlo" class="">  SmallString<1024> codeStorage;</font></div><div class=""><font face="Menlo" class="">  inMemoryFileSystem->addFile(fileNameRef, 0,</font></div><div class=""><font face="Menlo" class="">                              MemoryBuffer::getMemBuffer(Code.toNullTerminatedStringRef(codeStorage)));</font></div><div class=""><font face="Menlo" class="">  </font></div><div class=""><font face="Menlo" class="">  for (auto &filenameWithContent : virtualMappedFiles) {</font></div><div class=""><font face="Menlo" class="">    inMemoryFileSystem->addFile(filenameWithContent.first, 0,</font></div><div class=""><font face="Menlo" class="">                                MemoryBuffer::getMemBuffer(filenameWithContent.second));</font></div><div class=""><font face="Menlo" class="">  }</font></div><div class=""><font face="Menlo" class="">  </font></div><div class=""><font face="Menlo" class="">  return invocation.run();</font></div><div class=""><font face="Menlo" class="">}</font></div></div><div class=""><br class=""></div><div class="">It is basically a copy & past of runToolOnCode() but with the added parameter for diagnostic consumer. In the end it was not too much code to duplicate thanks to <font face="Menlo" class="">ToolInvocation::setDiagnosticConsumer()</font> already existing.</div><div class=""><br class=""></div><div class="">Best regards,</div><div class="">L. Soltic</div><br class=""><div class=""><div><blockquote type="cite" class=""><div class="">Le 4 août 2016 à 20:55, Lucas Soltic via cfe-users <<a href="mailto:cfe-users@lists.llvm.org" class="">cfe-users@lists.llvm.org</a>> a écrit :</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hello,<div class=""><br class=""></div><div class="">I am trying to redirect the output emitted when running a tool through clang::tooling::runToolOnCode() to a buffer or string instead of stderr (llvm::errs()). I'm using clangTooling from release 3.9.</div><div class=""><br class=""></div><div class="">When looking at clangTooling code and following the execution flow, I have found the following:</div><div class=""><font face="Menlo" class="">clang::tooling::runToolOnCode()</font></div><div class="">calls <font face="Menlo" class="">clang::tooling::runToolOnCodeWithArgs()</font></div><div class="">which calls <font face="Menlo" class="">clang::tooling::ToolInvocation::run()</font></div><div class="">which contains the following :</div><div class=""><font face="Menlo" class="">TextDiagnosticPrinter DiagnosticPrinter(<b class="">llvm::errs()</b>, &*DiagOpts);</font></div><div class=""><font face="Menlo" class="">DiagnosticsEngine Diagnostics(<br class="">    IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,<br class="">    DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false);</font></div><div class=""><br class=""></div><div class="">So at this point I guess I'm stuck because everything is redirected to stderr…</div><div class=""><b class="">Did I miss something or is there really this limitation?</b></div><div class=""><br class=""></div><div class="">I also thought of redirecting stderr to somewhere else but… I can't see how it will fit my needs as in the end I want to call <span style="font-family: Menlo;" class="">clang::tooling::runToolOnCode()</span> on different files in parallel, all of it in the same process ; so I'll get stderr mixed with output from several executions. The best solution would obviously being able to provide the DiagnosticConsumer but at the moment everything looks hardcoded.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Best regards,</div><div class="">L. Soltic</div><div class=""><br class=""></div></div>_______________________________________________<br class="">cfe-users mailing list<br class=""><a href="mailto:cfe-users@lists.llvm.org" class="">cfe-users@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users<br class=""></div></blockquote></div><br class=""></div></body></html>