11 #include "llvm/Support/ThreadPool.h" 12 #include "llvm/Support/VirtualFileSystem.h" 21 return llvm::make_error<llvm::StringError>(Message,
22 llvm::inconvertibleErrorCode());
32 class ThreadSafeToolResults :
public ToolResults {
34 void addResult(StringRef Key, StringRef
Value)
override {
35 std::unique_lock<std::mutex> LockGuard(Mutex);
36 Results.addResult(Key, Value);
39 std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
40 AllKVResults()
override {
41 return Results.AllKVResults();
44 void forEachResult(llvm::function_ref<
void(StringRef Key, StringRef Value)>
46 Results.forEachResult(Callback);
50 InMemoryToolResults Results;
56 llvm::cl::opt<std::string>
58 llvm::cl::desc(
"Only process files that match this filter. " 59 "This flag only applies to all-TUs."),
60 llvm::cl::init(
".*"));
64 std::shared_ptr<PCHContainerOperations> PCHContainerOps)
65 : Compilations(Compilations), Results(new ThreadSafeToolResults),
66 Context(Results.get()), ThreadCount(ThreadCount) {}
70 std::shared_ptr<PCHContainerOperations> PCHContainerOps)
71 : OptionsParser(
std::move(Options)),
72 Compilations(OptionsParser->getCompilations()),
73 Results(new ThreadSafeToolResults), Context(Results.get()),
74 ThreadCount(ThreadCount) {}
83 if (Actions.size() != 1)
85 "Only support executing exactly 1 action at this point.");
89 auto AppendError = [&](llvm::Twine Err) {
90 std::unique_lock<std::mutex> LockGuard(TUMutex);
91 ErrorMsg += Err.str();
94 auto Log = [&](llvm::Twine Msg) {
95 std::unique_lock<std::mutex> LockGuard(TUMutex);
96 llvm::errs() << Msg.str() <<
"\n";
99 std::vector<std::string> Files;
100 llvm::Regex RegexFilter(
Filter);
101 for (
const auto& File : Compilations.
getAllFiles()) {
102 if (RegexFilter.match(File))
103 Files.push_back(File);
106 const std::string TotalNumStr = std::to_string(Files.size());
107 unsigned Counter = 0;
109 std::unique_lock<std::mutex> LockGuard(TUMutex);
113 auto &Action = Actions.front();
116 llvm::ThreadPool Pool(ThreadCount == 0 ? llvm::hardware_concurrency()
118 for (std::string File : Files) {
120 [&](std::string Path) {
121 Log(
"[" + std::to_string(Count()) +
"/" + TotalNumStr +
122 "] Processing file " + Path);
126 llvm::vfs::createPhysicalFileSystem().release();
128 std::make_shared<PCHContainerOperations>(), FS);
131 for (
const auto &FileAndContent : OverlayFiles)
133 FileAndContent.second);
134 if (Tool.
run(Action.first.get()))
135 AppendError(llvm::Twine(
"Failed to run action on ") + Path +
144 if (!ErrorMsg.empty())
147 return llvm::Error::success();
151 "execute-concurrency",
152 llvm::cl::desc(
"The number of threads used to process all files in " 153 "parallel. Set to 0 for hardware concurrency. " 154 "This flag only applies to all-TUs."),
163 "[AllTUsToolExecutorPlugin] Please provide a directory/file path in " 164 "the compilation database.");
165 return llvm::make_unique<AllTUsToolExecutor>(std::move(OptionsParser),
170 static ToolExecutorPluginRegistry::Add<AllTUsToolExecutorPlugin>
171 X(
"all-TUs",
"Runs FrontendActions on all TUs in the compilation database. " 172 "Tool results are stored in memory.");
Dataflow Directional Tag Classes.