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.push_back(ToolName.str()); Args.push_back("-fsyntax-only"); Args.insert(Args.end(), ExtraArgs.begin(), ExtraArgs.end()); Args.push_back(FileName.str()); 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; OverlayFileSystem->pushOverlay(inMemoryFileSystem); IntrusiveRefCntPtr<FileManager> files(new FileManager(FileSystemOptions(), OverlayFileSystem)); ToolInvocation invocation(getSyntaxOnlyToolArgs(toolName, args, fileNameRef), ToolAction, files.get(), std::move(PCHContainerOps)); invocation.setDiagnosticConsumer(&diagConsumer); SmallString<1024> codeStorage; inMemoryFileSystem->addFile(fileNameRef, 0, MemoryBuffer::getMemBuffer(Code.toNullTerminatedStringRef(codeStorage))); for (auto &filenameWithContent : virtualMappedFiles) { inMemoryFileSystem->addFile(filenameWithContent.first, 0, MemoryBuffer::getMemBuffer(filenameWithContent.second)); } 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@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@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
_______________________________________________ cfe-users mailing list cfe-users@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users