diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Tooling/ArgumentsAdjusters.cpp | 4 | ||||
-rw-r--r-- | lib/Tooling/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib/Tooling/CommonOptionsParser.cpp | 8 | ||||
-rw-r--r-- | lib/Tooling/Execution.cpp | 89 | ||||
-rw-r--r-- | lib/Tooling/StandaloneExecution.cpp | 91 | ||||
-rw-r--r-- | lib/Tooling/Tooling.cpp | 7 |
6 files changed, 193 insertions, 8 deletions
diff --git a/lib/Tooling/ArgumentsAdjusters.cpp b/lib/Tooling/ArgumentsAdjusters.cpp index ac9fd3c5ca..962ea45258 100644 --- a/lib/Tooling/ArgumentsAdjusters.cpp +++ b/lib/Tooling/ArgumentsAdjusters.cpp @@ -96,6 +96,10 @@ ArgumentsAdjuster getInsertArgumentAdjuster(const char *Extra, ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First, ArgumentsAdjuster Second) { + if (!First) + return Second; + if (!Second) + return First; return [First, Second](const CommandLineArguments &Args, StringRef File) { return Second(First(Args, File), File); }; diff --git a/lib/Tooling/CMakeLists.txt b/lib/Tooling/CMakeLists.txt index 32a1935b3f..ee681bbb45 100644 --- a/lib/Tooling/CMakeLists.txt +++ b/lib/Tooling/CMakeLists.txt @@ -11,11 +11,13 @@ add_clang_library(clangTooling ArgumentsAdjusters.cpp CommonOptionsParser.cpp CompilationDatabase.cpp + Execution.cpp FileMatchTrie.cpp FixIt.cpp JSONCompilationDatabase.cpp Refactoring.cpp RefactoringCallbacks.cpp + StandaloneExecution.cpp Tooling.cpp DEPENDS diff --git a/lib/Tooling/CommonOptionsParser.cpp b/lib/Tooling/CommonOptionsParser.cpp index 9ad15cc8b2..74ad4e83ee 100644 --- a/lib/Tooling/CommonOptionsParser.cpp +++ b/lib/Tooling/CommonOptionsParser.cpp @@ -147,10 +147,12 @@ llvm::Error CommonOptionsParser::init( auto AdjustingCompilations = llvm::make_unique<ArgumentsAdjustingCompilations>( std::move(Compilations)); - AdjustingCompilations->appendArgumentsAdjuster( - getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN)); - AdjustingCompilations->appendArgumentsAdjuster( + Adjuster = + getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN); + Adjuster = combineAdjusters( + std::move(Adjuster), getInsertArgumentAdjuster(ArgsAfter, ArgumentInsertPosition::END)); + AdjustingCompilations->appendArgumentsAdjuster(Adjuster); Compilations = std::move(AdjustingCompilations); return llvm::Error::success(); } diff --git a/lib/Tooling/Execution.cpp b/lib/Tooling/Execution.cpp new file mode 100644 index 0000000000..1a078ef7e1 --- /dev/null +++ b/lib/Tooling/Execution.cpp @@ -0,0 +1,89 @@ +//===- lib/Tooling/Execution.cpp - Implements tool execution framework. ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Tooling/Execution.h" +#include "clang/Tooling/ToolExecutorPluginRegistry.h" +#include "clang/Tooling/Tooling.h" + +LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry) + +namespace clang { +namespace tooling { + +static llvm::cl::opt<std::string> + ExecutorName("executor", llvm::cl::desc("The name of the executor to use."), + llvm::cl::init("standalone")); + +void InMemoryToolResults::addResult(StringRef Key, StringRef Value) { + KVResults.push_back({Key.str(), Value.str()}); +} + +std::vector<std::pair<std::string, std::string>> +InMemoryToolResults::AllKVResults() { + return KVResults; +} + +void InMemoryToolResults::forEachResult( + llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) { + for (const auto &KV : KVResults) { + Callback(KV.first, KV.second); + } +} + +void ExecutionContext::reportResult(StringRef Key, StringRef Value) { + Results->addResult(Key, Value); +} + +llvm::Error +ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action) { + return execute(std::move(Action), ArgumentsAdjuster()); +} + +llvm::Error ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action, + ArgumentsAdjuster Adjuster) { + std::vector< + std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>> + Actions; + Actions.emplace_back(std::move(Action), std::move(Adjuster)); + return execute(Actions); +} + +llvm::Expected<std::unique_ptr<ToolExecutor>> +createExecutorFromCommandLineArgs(int &argc, const char **argv, + llvm::cl::OptionCategory &Category, + const char *Overview) { + auto OptionsParser = + CommonOptionsParser::create(argc, argv, Category, llvm::cl::ZeroOrMore, + /*Overview=*/nullptr); + if (!OptionsParser) + return OptionsParser.takeError(); + for (auto I = ToolExecutorPluginRegistry::begin(), + E = ToolExecutorPluginRegistry::end(); + I != E; ++I) { + if (I->getName() != ExecutorName) { + continue; + } + std::unique_ptr<ToolExecutorPlugin> Plugin(I->instantiate()); + llvm::Expected<std::unique_ptr<ToolExecutor>> Executor = + Plugin->create(*OptionsParser); + if (!Executor) { + return llvm::make_error<llvm::StringError>( + llvm::Twine("Failed to create '") + I->getName() + + "': " + llvm::toString(Executor.takeError()) + "\n", + llvm::inconvertibleErrorCode()); + } + return std::move(*Executor); + } + return llvm::make_error<llvm::StringError>( + llvm::Twine("Executor \"") + ExecutorName + "\" is not registered.", + llvm::inconvertibleErrorCode()); +} + +} // end namespace tooling +} // end namespace clang diff --git a/lib/Tooling/StandaloneExecution.cpp b/lib/Tooling/StandaloneExecution.cpp new file mode 100644 index 0000000000..aade40b62a --- /dev/null +++ b/lib/Tooling/StandaloneExecution.cpp @@ -0,0 +1,91 @@ +//===- lib/Tooling/Execution.cpp - Standalone clang action execution. -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Tooling/StandaloneExecution.h" +#include "clang/Tooling/ToolExecutorPluginRegistry.h" + +namespace clang { +namespace tooling { + +static llvm::Error make_string_error(const llvm::Twine &Message) { + return llvm::make_error<llvm::StringError>(Message, + llvm::inconvertibleErrorCode()); +} + +const char *StandaloneToolExecutor::ExecutorName = "StandaloneToolExecutor"; + +static ArgumentsAdjuster getDefaultArgumentsAdjusters() { + return combineAdjusters( + getClangStripOutputAdjuster(), + combineAdjusters(getClangSyntaxOnlyAdjuster(), + getClangStripDependencyFileAdjuster())); +} + +StandaloneToolExecutor::StandaloneToolExecutor( + const CompilationDatabase &Compilations, + llvm::ArrayRef<std::string> SourcePaths, + std::shared_ptr<PCHContainerOperations> PCHContainerOps) + : Tool(Compilations, SourcePaths), Context(&Results), + ArgsAdjuster(getDefaultArgumentsAdjusters()) { + // Use self-defined default argument adjusters instead of the default + // adjusters that come with the old `ClangTool`. + Tool.clearArgumentsAdjusters(); +} + +StandaloneToolExecutor::StandaloneToolExecutor( + CommonOptionsParser Options, + std::shared_ptr<PCHContainerOperations> PCHContainerOps) + : OptionsParser(std::move(Options)), + Tool(OptionsParser->getCompilations(), OptionsParser->getSourcePathList(), + PCHContainerOps), + Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) { + Tool.clearArgumentsAdjusters(); +} + +llvm::Error StandaloneToolExecutor::execute( + llvm::ArrayRef< + std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>> + Actions) { + if (Actions.empty()) + return make_string_error("No action to execute."); + + if (Actions.size() != 1) + return make_string_error( + "Only support executing exactly 1 action at this point."); + + auto &Action = Actions.front(); + Tool.appendArgumentsAdjuster(Action.second); + Tool.appendArgumentsAdjuster(ArgsAdjuster); + if (int Ret = Tool.run(Action.first.get())) + return make_string_error("Failed to run action."); + + return llvm::Error::success(); +} + +class StandaloneToolExecutorPlugin : public ToolExecutorPlugin { +public: + llvm::Expected<std::unique_ptr<ToolExecutor>> + create(CommonOptionsParser &OptionsParser) override { + if (OptionsParser.getSourcePathList().empty()) + return make_string_error( + "[StandaloneToolExecutorPlugin] No positional argument found."); + return llvm::make_unique<StandaloneToolExecutor>(std::move(OptionsParser)); + } +}; + +// This anchor is used to force the linker to link in the generated object file +// and thus register the plugin. +volatile int ToolExecutorPluginAnchorSource = 0; + +static ToolExecutorPluginRegistry::Add<StandaloneToolExecutorPlugin> + X("standalone", "Runs FrontendActions on a set of files provided " + "via positional arguments."); + +} // end namespace tooling +} // end namespace clang diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp index df9d7df694..4fbfa4f004 100644 --- a/lib/Tooling/Tooling.cpp +++ b/lib/Tooling/Tooling.cpp @@ -29,6 +29,7 @@ #include "llvm/Config/llvm-config.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" @@ -347,11 +348,7 @@ void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) { } void ClangTool::appendArgumentsAdjuster(ArgumentsAdjuster Adjuster) { - if (ArgsAdjuster) - ArgsAdjuster = - combineAdjusters(std::move(ArgsAdjuster), std::move(Adjuster)); - else - ArgsAdjuster = std::move(Adjuster); + ArgsAdjuster = combineAdjusters(std::move(ArgsAdjuster), std::move(Adjuster)); } void ClangTool::clearArgumentsAdjusters() { |