xref: /freebsd-src/contrib/llvm-project/clang/lib/Tooling/StandaloneExecution.cpp (revision 5b27928474e6a4103d65b347544705c40c9618fd)
10b57cec5SDimitry Andric //===- lib/Tooling/Execution.cpp - Standalone clang action execution. -----===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "clang/Tooling/StandaloneExecution.h"
100b57cec5SDimitry Andric #include "clang/Tooling/ToolExecutorPluginRegistry.h"
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric namespace clang {
130b57cec5SDimitry Andric namespace tooling {
140b57cec5SDimitry Andric 
make_string_error(const llvm::Twine & Message)150b57cec5SDimitry Andric static llvm::Error make_string_error(const llvm::Twine &Message) {
160b57cec5SDimitry Andric   return llvm::make_error<llvm::StringError>(Message,
170b57cec5SDimitry Andric                                              llvm::inconvertibleErrorCode());
180b57cec5SDimitry Andric }
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric const char *StandaloneToolExecutor::ExecutorName = "StandaloneToolExecutor";
210b57cec5SDimitry Andric 
getDefaultArgumentsAdjusters()220b57cec5SDimitry Andric static ArgumentsAdjuster getDefaultArgumentsAdjusters() {
230b57cec5SDimitry Andric   return combineAdjusters(
240b57cec5SDimitry Andric       getClangStripOutputAdjuster(),
250b57cec5SDimitry Andric       combineAdjusters(getClangSyntaxOnlyAdjuster(),
260b57cec5SDimitry Andric                        getClangStripDependencyFileAdjuster()));
270b57cec5SDimitry Andric }
280b57cec5SDimitry Andric 
StandaloneToolExecutor(const CompilationDatabase & Compilations,llvm::ArrayRef<std::string> SourcePaths,IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,std::shared_ptr<PCHContainerOperations> PCHContainerOps)290b57cec5SDimitry Andric StandaloneToolExecutor::StandaloneToolExecutor(
300b57cec5SDimitry Andric     const CompilationDatabase &Compilations,
310b57cec5SDimitry Andric     llvm::ArrayRef<std::string> SourcePaths,
320b57cec5SDimitry Andric     IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
330b57cec5SDimitry Andric     std::shared_ptr<PCHContainerOperations> PCHContainerOps)
340b57cec5SDimitry Andric     : Tool(Compilations, SourcePaths, std::move(PCHContainerOps),
350b57cec5SDimitry Andric            std::move(BaseFS)),
360b57cec5SDimitry Andric       Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) {
370b57cec5SDimitry Andric   // Use self-defined default argument adjusters instead of the default
380b57cec5SDimitry Andric   // adjusters that come with the old `ClangTool`.
390b57cec5SDimitry Andric   Tool.clearArgumentsAdjusters();
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric 
StandaloneToolExecutor(CommonOptionsParser Options,std::shared_ptr<PCHContainerOperations> PCHContainerOps)420b57cec5SDimitry Andric StandaloneToolExecutor::StandaloneToolExecutor(
430b57cec5SDimitry Andric     CommonOptionsParser Options,
440b57cec5SDimitry Andric     std::shared_ptr<PCHContainerOperations> PCHContainerOps)
450b57cec5SDimitry Andric     : OptionsParser(std::move(Options)),
460b57cec5SDimitry Andric       Tool(OptionsParser->getCompilations(), OptionsParser->getSourcePathList(),
470b57cec5SDimitry Andric            std::move(PCHContainerOps)),
480b57cec5SDimitry Andric       Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) {
490b57cec5SDimitry Andric   Tool.clearArgumentsAdjusters();
500b57cec5SDimitry Andric }
510b57cec5SDimitry Andric 
execute(llvm::ArrayRef<std::pair<std::unique_ptr<FrontendActionFactory>,ArgumentsAdjuster>> Actions)520b57cec5SDimitry Andric llvm::Error StandaloneToolExecutor::execute(
530b57cec5SDimitry Andric     llvm::ArrayRef<
540b57cec5SDimitry Andric         std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
550b57cec5SDimitry Andric         Actions) {
560b57cec5SDimitry Andric   if (Actions.empty())
570b57cec5SDimitry Andric     return make_string_error("No action to execute.");
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric   if (Actions.size() != 1)
600b57cec5SDimitry Andric     return make_string_error(
610b57cec5SDimitry Andric         "Only support executing exactly 1 action at this point.");
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   auto &Action = Actions.front();
640b57cec5SDimitry Andric   Tool.appendArgumentsAdjuster(Action.second);
650b57cec5SDimitry Andric   Tool.appendArgumentsAdjuster(ArgsAdjuster);
660b57cec5SDimitry Andric   if (Tool.run(Action.first.get()))
670b57cec5SDimitry Andric     return make_string_error("Failed to run action.");
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   return llvm::Error::success();
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric class StandaloneToolExecutorPlugin : public ToolExecutorPlugin {
730b57cec5SDimitry Andric public:
740b57cec5SDimitry Andric   llvm::Expected<std::unique_ptr<ToolExecutor>>
create(CommonOptionsParser & OptionsParser)750b57cec5SDimitry Andric   create(CommonOptionsParser &OptionsParser) override {
760b57cec5SDimitry Andric     if (OptionsParser.getSourcePathList().empty())
770b57cec5SDimitry Andric       return make_string_error(
780b57cec5SDimitry Andric           "[StandaloneToolExecutorPlugin] No positional argument found.");
79*a7dea167SDimitry Andric     return std::make_unique<StandaloneToolExecutor>(std::move(OptionsParser));
800b57cec5SDimitry Andric   }
810b57cec5SDimitry Andric };
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric static ToolExecutorPluginRegistry::Add<StandaloneToolExecutorPlugin>
840b57cec5SDimitry Andric     X("standalone", "Runs FrontendActions on a set of files provided "
850b57cec5SDimitry Andric                     "via positional arguments.");
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric // This anchor is used to force the linker to link in the generated object file
880b57cec5SDimitry Andric // and thus register the plugin.
890b57cec5SDimitry Andric volatile int StandaloneToolExecutorAnchorSource = 0;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric } // end namespace tooling
920b57cec5SDimitry Andric } // end namespace clang
93