[cfe-users] Redirecting clang tooling errors

Lucas Soltic via cfe-users cfe-users at lists.llvm.org
Sat Aug 6 04:11:33 PDT 2016

Considering that there is no other viable possibility, for now I have gone with the following:

using llvm::Twine;
using llvm::SmallString;
using llvm::IntrusiveRefCntPtr;
using llvm::MemoryBuffer;
using clang::FileManager;
using clang::PCHContainerOperations;
using clang::FileSystemOptions;
using clang::tooling::ToolInvocation;
using clang::tooling::FileContentMappings;

static std::vector<std::string>
getSyntaxOnlyToolArgs(const Twine &ToolName,
                      const std::vector<std::string> &ExtraArgs,
                      StringRef FileName) {
  std::vector<std::string> Args;
  Args.insert(Args.end(), ExtraArgs.begin(), ExtraArgs.end());
  return Args;

bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
                   const Twine &FileName, clang::DiagnosticConsumer& diagConsumer)
  const std::vector<std::string> args;
  const Twine toolName = "clang-tool";
  std::shared_ptr<PCHContainerOperations> PCHContainerOps = std::make_shared<PCHContainerOperations>();
  const FileContentMappings virtualMappedFiles = FileContentMappings();
  SmallString<16> fileNameStorage;
  StringRef fileNameRef = FileName.toNullTerminatedStringRef(fileNameStorage);
  IntrusiveRefCntPtr<clang::vfs::OverlayFileSystem> OverlayFileSystem
    = new clang::vfs::OverlayFileSystem(clang::vfs::getRealFileSystem());
  IntrusiveRefCntPtr<clang::vfs::InMemoryFileSystem> inMemoryFileSystem
    = new clang::vfs::InMemoryFileSystem;
  IntrusiveRefCntPtr<FileManager> files(new FileManager(FileSystemOptions(), OverlayFileSystem));
  ToolInvocation invocation(getSyntaxOnlyToolArgs(toolName, args, fileNameRef),
                            ToolAction, files.get(), std::move(PCHContainerOps));
  SmallString<1024> codeStorage;
  inMemoryFileSystem->addFile(fileNameRef, 0,
  for (auto &filenameWithContent : virtualMappedFiles) {
    inMemoryFileSystem->addFile(filenameWithContent.first, 0,
  return invocation.run();

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 ToolInvocation::setDiagnosticConsumer() already existing.

Best regards,
L. Soltic

> Le 4 août 2016 à 20:55, Lucas Soltic via cfe-users <cfe-users at lists.llvm.org> a écrit :
> Hello,
> 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.
> When looking at clangTooling code and following the execution flow, I have found the following:
> clang::tooling::runToolOnCode()
> calls clang::tooling::runToolOnCodeWithArgs()
> which calls clang::tooling::ToolInvocation::run()
> which contains the following :
> TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), &*DiagOpts);
> DiagnosticsEngine Diagnostics(
>     IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
>     DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false);
> So at this point I guess I'm stuck because everything is redirected to stderr…
> Did I miss something or is there really this limitation?
> 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 clang::tooling::runToolOnCode() 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.
> Best regards,
> L. Soltic
> _______________________________________________
> cfe-users mailing list
> cfe-users at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-users/attachments/20160806/36b05658/attachment.html>

More information about the cfe-users mailing list