11#include "llvm/Support/Regex.h"
12#include "llvm/Support/ThreadPool.h"
13#include "llvm/Support/Threading.h"
14#include "llvm/Support/VirtualFileSystem.h"
23 return llvm::make_error<llvm::StringError>(Message,
24 llvm::inconvertibleErrorCode());
34class ThreadSafeToolResults :
public ToolResults {
36 void addResult(StringRef Key, StringRef
Value)
override {
37 std::unique_lock<std::mutex> LockGuard(Mutex);
38 Results.addResult(Key,
Value);
41 std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
42 AllKVResults()
override {
43 return Results.AllKVResults();
46 void forEachResult(llvm::function_ref<
void(StringRef Key, StringRef
Value)>
48 Results.forEachResult(Callback);
52 InMemoryToolResults Results;
58llvm::cl::opt<std::string>
60 llvm::cl::desc(
"Only process files that match this filter. "
61 "This flag only applies to all-TUs."),
62 llvm::cl::init(
".*"));
66 std::shared_ptr<PCHContainerOperations> PCHContainerOps)
67 : Compilations(Compilations), Results(new ThreadSafeToolResults),
68 Context(Results.get()), ThreadCount(ThreadCount) {}
72 std::shared_ptr<PCHContainerOperations> PCHContainerOps)
73 : OptionsParser(
std::move(Options)),
74 Compilations(OptionsParser->getCompilations()),
75 Results(new ThreadSafeToolResults), Context(Results.get()),
76 ThreadCount(ThreadCount) {}
85 if (Actions.size() != 1)
87 "Only support executing exactly 1 action at this point.");
91 auto AppendError = [&](llvm::Twine Err) {
92 std::unique_lock<std::mutex> LockGuard(TUMutex);
93 ErrorMsg += Err.str();
96 auto Log = [&](llvm::Twine Msg) {
97 std::unique_lock<std::mutex> LockGuard(TUMutex);
98 llvm::errs() << Msg.str() <<
"\n";
101 std::vector<std::string> Files;
102 llvm::Regex RegexFilter(
Filter);
104 if (RegexFilter.match(
File))
105 Files.push_back(
File);
108 const std::string TotalNumStr = std::to_string(Files.size());
109 unsigned Counter = 0;
111 std::unique_lock<std::mutex> LockGuard(TUMutex);
115 auto &Action = Actions.front();
118 llvm::DefaultThreadPool Pool(llvm::hardware_concurrency(ThreadCount));
119 for (std::string
File : Files) {
121 [&](std::string
Path) {
122 Log(
"[" + std::to_string(Count()) +
"/" + TotalNumStr +
123 "] Processing file " +
Path);
127 llvm::vfs::createPhysicalFileSystem();
129 std::make_shared<PCHContainerOperations>(), FS);
132 for (
const auto &FileAndContent : OverlayFiles)
133 Tool.mapVirtualFile(FileAndContent.first(),
134 FileAndContent.second);
135 if (Tool.run(Action.first.get()))
136 AppendError(llvm::Twine(
"Failed to run action on ") +
Path +
145 if (!ErrorMsg.empty())
148 return llvm::Error::success();
152 "execute-concurrency",
153 llvm::cl::desc(
"The number of threads used to process all files in "
154 "parallel. Set to 0 for hardware concurrency. "
155 "This flag only applies to all-TUs."),
164 "[AllTUsToolExecutorPlugin] Please provide a directory/file path in "
165 "the compilation database.");
166 return std::make_unique<AllTUsToolExecutor>(std::move(OptionsParser),
171static ToolExecutorPluginRegistry::Add<AllTUsToolExecutorPlugin>
172 X(
"all-TUs",
"Runs FrontendActions on all TUs in the compilation database. "
173 "Tool results are stored in memory.");
The JSON file list parser is used to communicate input to InstallAPI.