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
getSyntaxOnlyToolArgs(const Twine &ToolName,
const std::vector &ExtraArgs,
StringRef FileName) {
std::vector 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 args;
const Twine toolName = "clang-tool";
std::shared_ptr PCHContainerOps =
std::make_shared();
const FileContentMappings virtualMappedFiles = FileContentMappings();
SmallString<16> fileNameStorage;
StringRef fileNameRef = FileName.toNullTerminatedStringRef(fileNameStorage);
IntrusiveRefCntPtr OverlayFileSystem
= new clang::vfs::OverlayFileSystem(clang::vfs::getRealFileSystem());
IntrusiveRefCntPtr inMemoryFileSystem
= new clang::vfs::InMemoryFileSystem;
OverlayFileSystem->pushOverlay(inMemoryFileSystem);
IntrusiveRefCntPtr 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
> 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(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