11 #include "llvm/Support/Threading.h" 12 #include "llvm/Support/ThreadPool.h" 13 #include "llvm/Support/VirtualFileSystem.h" 22 return llvm::make_error<llvm::StringError>(Message,
23 llvm::inconvertibleErrorCode());
33 class ThreadSafeToolResults :
public ToolResults {
35 void addResult(StringRef Key, StringRef
Value)
override {
36 std::unique_lock<std::mutex> LockGuard(Mutex);
37 Results.addResult(Key, Value);
40 std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
41 AllKVResults()
override {
42 return Results.AllKVResults();
45 void forEachResult(llvm::function_ref<
void(StringRef Key, StringRef Value)>
47 Results.forEachResult(Callback);
51 InMemoryToolResults Results;
57 llvm::cl::opt<std::string>
59 llvm::cl::desc(
"Only process files that match this filter. " 60 "This flag only applies to all-TUs."),
61 llvm::cl::init(
".*"));
65 std::shared_ptr<PCHContainerOperations> PCHContainerOps)
66 : Compilations(Compilations), Results(new ThreadSafeToolResults),
67 Context(Results.get()), ThreadCount(ThreadCount) {}
71 std::shared_ptr<PCHContainerOperations> PCHContainerOps)
72 : OptionsParser(
std::move(Options)),
73 Compilations(OptionsParser->getCompilations()),
74 Results(new ThreadSafeToolResults), Context(Results.get()),
75 ThreadCount(ThreadCount) {}
84 if (Actions.size() != 1)
86 "Only support executing exactly 1 action at this point.");
90 auto AppendError = [&](llvm::Twine Err) {
91 std::unique_lock<std::mutex> LockGuard(TUMutex);
92 ErrorMsg += Err.str();
95 auto Log = [&](llvm::Twine Msg) {
96 std::unique_lock<std::mutex> LockGuard(TUMutex);
97 llvm::errs() << Msg.str() <<
"\n";
100 std::vector<std::string> Files;
101 llvm::Regex RegexFilter(
Filter);
102 for (
const auto& File : Compilations.
getAllFiles()) {
103 if (RegexFilter.match(File))
104 Files.push_back(File);
107 const std::string TotalNumStr = std::to_string(Files.size());
108 unsigned Counter = 0;
110 std::unique_lock<std::mutex> LockGuard(TUMutex);
114 auto &Action = Actions.front();
117 llvm::ThreadPool Pool(ThreadCount == 0 ? llvm::hardware_concurrency()
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().release();
129 std::make_shared<PCHContainerOperations>(), FS);
132 for (
const auto &FileAndContent : OverlayFiles)
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),
171 static ToolExecutorPluginRegistry::Add<AllTUsToolExecutorPlugin>
172 X(
"all-TUs",
"Runs FrontendActions on all TUs in the compilation database. " 173 "Tool results are stored in memory.");
Dataflow Directional Tag Classes.