diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h +++ b/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 +#include +#include 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 Cache; + std::mutex CacheLock; +}; + /// The dependency scanning service contains the shared state that is used by /// the invidual dependency scanning workers. class DependencyScanningService { diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp +++ b/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 LockGuard(CacheLock); + const auto &CachedResourceDir = Cache.find(ClangBinaryPath); + if (CachedResourceDir != Cache.end()) + return CachedResourceDir->second; + + std::vector 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 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) diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/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 -#include 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 LockGuard(CacheLock); - const auto &CachedResourceDir = Cache.find(ClangBinaryPath); - if (CachedResourceDir != Cache.end()) - return CachedResourceDir->second; - - std::vector 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 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 Cache; - std::mutex CacheLock; -}; - llvm::cl::opt Help("h", llvm::cl::desc("Alias for -help"), llvm::cl::Hidden);