jansvoboda11 created this revision. jansvoboda11 added reviewers: Bigcheese, dexonsmith, arphaman. jansvoboda11 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The `ResourceDirectoryCache` is useful not only in the `clang-scan-deps` CLI tool, but also in the downstream libclang API. This NFC patch moves it to `DependencyScanningService.h`. to make it reusable. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D108215 Files: clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp clang/tools/clang-scan-deps/ClangScanDeps.cpp
Index: clang/tools/clang-scan-deps/ClangScanDeps.cpp =================================================================== --- clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -14,16 +14,12 @@ #include "clang/Tooling/JSONCompilationDatabase.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Twine.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FileUtilities.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/JSON.h" -#include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" #include "llvm/Support/ThreadPool.h" #include "llvm/Support/Threading.h" #include <mutex> -#include <thread> using namespace clang; using namespace tooling::dependencies; @@ -44,69 +40,6 @@ raw_ostream &OS; }; -class ResourceDirectoryCache { -public: - /// findResourceDir finds the resource directory relative to the clang - /// compiler being used in Args, by running it with "-print-resource-dir" - /// option and cache the results for reuse. \returns resource directory path - /// associated with the given invocation command or empty string if the - /// compiler path is NOT an absolute path. - StringRef findResourceDir(const tooling::CommandLineArguments &Args, - bool ClangCLMode) { - if (Args.size() < 1) - return ""; - - const std::string &ClangBinaryPath = Args[0]; - if (!llvm::sys::path::is_absolute(ClangBinaryPath)) - return ""; - - const std::string &ClangBinaryName = - std::string(llvm::sys::path::filename(ClangBinaryPath)); - - std::unique_lock<std::mutex> LockGuard(CacheLock); - const auto &CachedResourceDir = Cache.find(ClangBinaryPath); - if (CachedResourceDir != Cache.end()) - return CachedResourceDir->second; - - std::vector<StringRef> PrintResourceDirArgs{ClangBinaryName}; - if (ClangCLMode) - PrintResourceDirArgs.push_back("/clang:-print-resource-dir"); - else - PrintResourceDirArgs.push_back("-print-resource-dir"); - - llvm::SmallString<64> OutputFile, ErrorFile; - llvm::sys::fs::createTemporaryFile("print-resource-dir-output", - "" /*no-suffix*/, OutputFile); - llvm::sys::fs::createTemporaryFile("print-resource-dir-error", - "" /*no-suffix*/, ErrorFile); - llvm::FileRemover OutputRemover(OutputFile.c_str()); - llvm::FileRemover ErrorRemover(ErrorFile.c_str()); - llvm::Optional<StringRef> Redirects[] = { - {""}, // Stdin - OutputFile.str(), - ErrorFile.str(), - }; - if (const int RC = llvm::sys::ExecuteAndWait( - ClangBinaryPath, PrintResourceDirArgs, {}, Redirects)) { - auto ErrorBuf = llvm::MemoryBuffer::getFile(ErrorFile.c_str()); - llvm::errs() << ErrorBuf.get()->getBuffer(); - return ""; - } - - auto OutputBuf = llvm::MemoryBuffer::getFile(OutputFile.c_str()); - if (!OutputBuf) - return ""; - StringRef Output = OutputBuf.get()->getBuffer().rtrim('\n'); - - Cache[ClangBinaryPath] = Output.str(); - return Cache[ClangBinaryPath]; - } - -private: - std::map<std::string, std::string> Cache; - std::mutex CacheLock; -}; - llvm::cl::opt<bool> Help("h", llvm::cl::desc("Alias for -help"), llvm::cl::Hidden); Index: clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp +++ clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp @@ -8,11 +8,65 @@ #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Support/FileUtilities.h" +#include "llvm/Support/Program.h" using namespace clang; using namespace tooling; using namespace dependencies; +StringRef +ResourceDirectoryCache::findResourceDir(const CommandLineArguments &Args, + bool ClangCLMode) { + if (Args.size() < 1) + return ""; + + const std::string &ClangBinaryPath = Args[0]; + if (!llvm::sys::path::is_absolute(ClangBinaryPath)) + return ""; + + const std::string &ClangBinaryName = + std::string(llvm::sys::path::filename(ClangBinaryPath)); + + std::unique_lock<std::mutex> LockGuard(CacheLock); + const auto &CachedResourceDir = Cache.find(ClangBinaryPath); + if (CachedResourceDir != Cache.end()) + return CachedResourceDir->second; + + std::vector<StringRef> PrintResourceDirArgs{ClangBinaryName}; + if (ClangCLMode) + PrintResourceDirArgs.push_back("/clang:-print-resource-dir"); + else + PrintResourceDirArgs.push_back("-print-resource-dir"); + + llvm::SmallString<64> OutputFile, ErrorFile; + llvm::sys::fs::createTemporaryFile("print-resource-dir-output", + "" /*no-suffix*/, OutputFile); + llvm::sys::fs::createTemporaryFile("print-resource-dir-error", + "" /*no-suffix*/, ErrorFile); + llvm::FileRemover OutputRemover(OutputFile.c_str()); + llvm::FileRemover ErrorRemover(ErrorFile.c_str()); + llvm::Optional<StringRef> Redirects[] = { + {""}, // Stdin + OutputFile.str(), + ErrorFile.str(), + }; + if (const int RC = llvm::sys::ExecuteAndWait( + ClangBinaryPath, PrintResourceDirArgs, {}, Redirects)) { + auto ErrorBuf = llvm::MemoryBuffer::getFile(ErrorFile.c_str()); + llvm::errs() << ErrorBuf.get()->getBuffer(); + return ""; + } + + auto OutputBuf = llvm::MemoryBuffer::getFile(OutputFile.c_str()); + if (!OutputBuf) + return ""; + StringRef Output = OutputBuf.get()->getBuffer().rtrim('\n'); + + Cache[ClangBinaryPath] = Output.str(); + return Cache[ClangBinaryPath]; +} + DependencyScanningService::DependencyScanningService( ScanningMode Mode, ScanningOutputFormat Format, bool ReuseFileManager, bool SkipExcludedPPRanges) Index: clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h =================================================================== --- clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h +++ clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h @@ -10,6 +10,11 @@ #define LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_SERVICE_H #include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h" +#include "clang/Tooling/ArgumentsAdjusters.h" + +#include <map> +#include <mutex> +#include <string> namespace clang { namespace tooling { @@ -42,6 +47,20 @@ Full, }; +class ResourceDirectoryCache { +public: + /// findResourceDir finds the resource directory relative to the clang + /// compiler being used in Args, by running it with "-print-resource-dir" + /// option and cache the results for reuse. \returns resource directory path + /// associated with the given invocation command or empty string if the + /// compiler path is NOT an absolute path. + StringRef findResourceDir(const CommandLineArguments &Args, bool ClangCLMode); + +private: + std::map<std::string, std::string> Cache; + std::mutex CacheLock; +}; + /// The dependency scanning service contains the shared state that is used by /// the invidual dependency scanning workers. class DependencyScanningService {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits