Ejemplo n.º 1
0
 llvm::Expected<std::unique_ptr<ToolExecutor>>
 create(CommonOptionsParser &OptionsParser) override {
   if (OptionsParser.getSourcePathList().empty())
     return make_string_error(
         "[AllTUsToolExecutorPlugin] Please provide a directory/file path in "
         "the compilation database.");
   return llvm::make_unique<AllTUsToolExecutor>(std::move(OptionsParser),
                                                ExecutorConcurrency);
 }
Ejemplo n.º 2
0
llvm::Expected<URI> URI::create(llvm::StringRef AbsolutePath,
                                llvm::StringRef Scheme) {
  if (!llvm::sys::path::is_absolute(AbsolutePath))
    return make_string_error("Not a valid absolute path: " + AbsolutePath);
  auto S = findSchemeByName(Scheme);
  if (!S)
    return S.takeError();
  return S->get()->uriFromAbsolutePath(AbsolutePath);
}
Ejemplo n.º 3
0
llvm::Expected<URI> URI::create(llvm::StringRef AbsolutePath,
                                const std::vector<std::string> &Schemes) {
  if (!llvm::sys::path::is_absolute(AbsolutePath))
    return make_string_error("Not a valid absolute path: " + AbsolutePath);
  for (const auto &Scheme : Schemes) {
    auto URI = URI::create(AbsolutePath, Scheme);
    // For some paths, conversion to different URI schemes is impossible. These
    // should be just skipped.
    if (!URI) {
      // Ignore the error.
      llvm::consumeError(URI.takeError());
      continue;
    }
    return URI;
  }
  return make_string_error(
      "Couldn't convert " + AbsolutePath +
      " to any given scheme: " + llvm::join(Schemes, ", "));
}
Ejemplo n.º 4
0
llvm::Expected<URI> URI::parse(llvm::StringRef OrigUri) {
  URI U;
  llvm::StringRef Uri = OrigUri;

  auto Pos = Uri.find(':');
  if (Pos == 0 || Pos == llvm::StringRef::npos)
    return make_string_error("Scheme must be provided in URI: " + OrigUri);
  U.Scheme = percentDecode(Uri.substr(0, Pos));
  Uri = Uri.substr(Pos + 1);
  if (Uri.consume_front("//")) {
    Pos = Uri.find('/');
    U.Authority = percentDecode(Uri.substr(0, Pos));
    Uri = Uri.substr(Pos);
  }
  U.Body = percentDecode(Uri);
  return U;
}
Ejemplo n.º 5
0
llvm::Error AllTUsToolExecutor::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.");

  std::string ErrorMsg;
  std::mutex TUMutex;
  auto AppendError = [&](llvm::Twine Err) {
    std::unique_lock<std::mutex> LockGuard(TUMutex);
    ErrorMsg += Err.str();
  };

  auto Log = [&](llvm::Twine Msg) {
    std::unique_lock<std::mutex> LockGuard(TUMutex);
    llvm::errs() << Msg.str() << "\n";
  };

  std::vector<std::string> Files;
  llvm::Regex RegexFilter(Filter);
  for (const auto& File : Compilations.getAllFiles()) {
    if (RegexFilter.match(File))
      Files.push_back(File);
  }
  // Add a counter to track the progress.
  const std::string TotalNumStr = std::to_string(Files.size());
  unsigned Counter = 0;
  auto Count = [&]() {
    std::unique_lock<std::mutex> LockGuard(TUMutex);
    return ++Counter;
  };

  auto &Action = Actions.front();

  {
    llvm::ThreadPool Pool(ThreadCount == 0 ? llvm::hardware_concurrency()
                                           : ThreadCount);
    llvm::SmallString<128> InitialWorkingDir;
    if (auto EC = llvm::sys::fs::current_path(InitialWorkingDir)) {
      InitialWorkingDir = "";
      llvm::errs() << "Error while getting current working directory: "
                   << EC.message() << "\n";
    }
    for (std::string File : Files) {
      Pool.async(
          [&](std::string Path) {
            Log("[" + std::to_string(Count()) + "/" + TotalNumStr +
                "] Processing file " + Path);
            ClangTool Tool(Compilations, {Path});
            Tool.appendArgumentsAdjuster(Action.second);
            Tool.appendArgumentsAdjuster(getDefaultArgumentsAdjusters());
            for (const auto &FileAndContent : OverlayFiles)
              Tool.mapVirtualFile(FileAndContent.first(),
                                  FileAndContent.second);
            // Do not restore working dir from multiple threads to avoid races.
            Tool.setRestoreWorkingDir(false);
            if (Tool.run(Action.first.get()))
              AppendError(llvm::Twine("Failed to run action on ") + Path +
                          "\n");
          },
          File);
    }
    // Make sure all tasks have finished before resetting the working directory.
    Pool.wait();
    if (!InitialWorkingDir.empty()) {
      if (auto EC = llvm::sys::fs::set_current_path(InitialWorkingDir))
        llvm::errs() << "Error while restoring working directory: "
                     << EC.message() << "\n";
    }
  }

  if (!ErrorMsg.empty())
    return make_string_error(ErrorMsg);

  return llvm::Error::success();
}