diff --git a/clang-tools-extra/clangd/ScanningProjectModules.cpp b/clang-tools-extra/clangd/ScanningProjectModules.cpp index 7eb15de91464d..c491acdfe150f 100644 --- a/clang-tools-extra/clangd/ScanningProjectModules.cpp +++ b/clang-tools-extra/clangd/ScanningProjectModules.cpp @@ -8,8 +8,8 @@ #include "ProjectModules.h" #include "support/Logger.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" +#include "clang/DependencyScanning/DependencyScanningService.h" +#include "clang/Tooling/DependencyScanningTool.h" namespace clang::clangd { namespace { @@ -36,9 +36,9 @@ class ModuleDependencyScanner { std::shared_ptr CDB, const ThreadsafeFS &TFS) : CDB(CDB), TFS(TFS), - Service(tooling::dependencies::ScanningMode::CanonicalPreprocessing, - tooling::dependencies::ScanningOutputFormat::P1689, - CASOptions(), nullptr, nullptr) {} + Service(dependencies::ScanningMode::CanonicalPreprocessing, + dependencies::ScanningOutputFormat::P1689, CASOptions(), + nullptr, nullptr) {} /// The scanned modules dependency information for a specific source file. struct ModuleDependencyInfo { @@ -82,7 +82,7 @@ class ModuleDependencyScanner { // Whether the scanner has scanned the project globally. bool GlobalScanned = false; - clang::tooling::dependencies::DependencyScanningService Service; + clang::dependencies::DependencyScanningService Service; // TODO: Add a scanning cache. diff --git a/clang/lib/Tooling/DependencyScanning/CachingActions.h b/clang/include/clang/DependencyScanning/CachingActions.h similarity index 61% rename from clang/lib/Tooling/DependencyScanning/CachingActions.h rename to clang/include/clang/DependencyScanning/CachingActions.h index f6d15fdb25fcb..2556c10223bb0 100644 --- a/clang/lib/Tooling/DependencyScanning/CachingActions.h +++ b/clang/include/clang/DependencyScanning/CachingActions.h @@ -1,4 +1,4 @@ -//===- CachingActions.h -----------------------------------------*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,13 +6,14 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_CACHINGACTIONS_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_CACHINGACTIONS_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_CACHINGACTIONS_H +#define LLVM_CLANG_DEPENDENCYSCANNING_CACHINGACTIONS_H -#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" -#include "clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h" +#include "clang/DependencyScanning/DependencyScanningUtils.h" +#include "clang/DependencyScanning/DependencyScanningWorker.h" +#include "clang/DependencyScanning/ScanAndUpdateArgs.h" -namespace clang::tooling::dependencies { +namespace clang::dependencies { std::unique_ptr createIncludeTreeActionController(LookupModuleOutputCallback LookupModuleOutput, @@ -24,5 +25,5 @@ createIncludeTreeActionController(LookupModuleOutputCallback LookupModuleOutput, void addReversePrefixMappingFileSystem(const llvm::PrefixMapper &PrefixMapper, CompilerInstance &ScanInstance); -} // namespace clang::tooling::dependencies -#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_CACHINGACTIONS_H +} // namespace clang::dependencies +#endif // LLVM_CLANG_DEPENDENCYSCANNING_CACHINGACTIONS_H diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.h b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h similarity index 96% rename from clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.h rename to clang/include/clang/DependencyScanning/DependencyScannerImpl.h index fd1f8ec6e815f..e92fe43b53928 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.h +++ b/clang/include/clang/DependencyScanning/DependencyScannerImpl.h @@ -1,4 +1,4 @@ -//===- DependencyScannerImpl.h - Implements dependency scanning *- C++ -*--===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,18 +9,18 @@ #ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNER_H #define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNER_H +#include "clang/DependencyScanning/DependencyScanningFilesystem.h" +#include "clang/DependencyScanning/ModuleDepCollector.h" #include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Serialization/ObjectFilePCHContainerReader.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h" -#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" namespace clang { class DiagnosticConsumer; -namespace tooling { namespace dependencies { class DependencyScanningService; class DependencyScanningWorker; @@ -206,7 +206,6 @@ class CompilerInstanceWithContext { llvm::Error handleReturnStatus(bool Success); }; } // namespace dependencies -} // namespace tooling } // namespace clang #endif diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h b/clang/include/clang/DependencyScanning/DependencyScanningFilesystem.h similarity index 98% rename from clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h rename to clang/include/clang/DependencyScanning/DependencyScanningFilesystem.h index dc161401f0add..95a30d2dd1e6b 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h +++ b/clang/include/clang/DependencyScanning/DependencyScanningFilesystem.h @@ -1,4 +1,4 @@ -//===- DependencyScanningFilesystem.h - clang-scan-deps fs ===---*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H +#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H #include "clang/Basic/LLVM.h" #include "clang/Lex/DependencyDirectivesScanner.h" @@ -22,7 +22,6 @@ #include namespace clang { -namespace tooling { namespace dependencies { class DependencyScanningService; @@ -534,7 +533,6 @@ class DependencyScanningWorkerFilesystem }; } // end namespace dependencies -} // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H +#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/clang/include/clang/DependencyScanning/DependencyScanningService.h similarity index 91% rename from clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h rename to clang/include/clang/DependencyScanning/DependencyScanningService.h index 7ae422ee9897b..15b3dd04f14bd 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h +++ b/clang/include/clang/DependencyScanning/DependencyScanningService.h @@ -1,4 +1,4 @@ -//===- DependencyScanningService.h - clang-scan-deps service ===-*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,18 +6,17 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H +#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H #include "clang/CAS/CASOptions.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h" -#include "clang/Tooling/DependencyScanning/InProcessModuleCache.h" +#include "clang/DependencyScanning/DependencyScanningFilesystem.h" +#include "clang/DependencyScanning/InProcessModuleCache.h" #include "llvm/ADT/BitmaskEnum.h" #include "llvm/CAS/ActionCache.h" #include "llvm/Support/Chrono.h" namespace clang { -namespace tooling { namespace dependencies { /// The mode in which the dependency scanner will operate to find the @@ -155,7 +154,6 @@ class DependencyScanningService { }; } // end namespace dependencies -} // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H +#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H diff --git a/clang/include/clang/DependencyScanning/DependencyScanningUtils.h b/clang/include/clang/DependencyScanning/DependencyScanningUtils.h new file mode 100644 index 0000000000000..ba83f0e89603e --- /dev/null +++ b/clang/include/clang/DependencyScanning/DependencyScanningUtils.h @@ -0,0 +1,174 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGUTILS_H +#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGUTILS_H + +#include "clang/DependencyScanning/DependencyScannerImpl.h" +#include "clang/DependencyScanning/DependencyScanningWorker.h" +#include "clang/DependencyScanning/ModuleDepCollector.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/MapVector.h" +#include +#include + +namespace clang { +namespace dependencies { + +/// Graph of modular dependencies. +using ModuleDepsGraph = std::vector; + +/// The full dependencies and module graph for a specific input. +struct TranslationUnitDeps { + /// The graph of direct and transitive modular dependencies. + ModuleDepsGraph ModuleGraph; + + /// The identifier of the C++20 module this translation unit exports. + /// + /// If the translation unit is not a module then \c ID.ModuleName is empty. + ModuleID ID; + + /// A collection of absolute paths to files that this translation unit + /// directly depends on, not including transitive dependencies. + std::vector FileDeps; + + /// A collection of prebuilt modules this translation unit directly depends + /// on, not including transitive dependencies. + std::vector PrebuiltModuleDeps; + + /// A list of modules this translation unit directly depends on, not including + /// transitive dependencies. + /// + /// This may include modules with a different context hash when it can be + /// determined that the differences are benign for this compilation. + std::vector ClangModuleDeps; + + /// A list of module names that are visible to this translation unit. This + /// includes both direct and transitive module dependencies. + std::vector VisibleModules; + + /// The include-tree for input file dependency tree. + std::optional IncludeTreeID; + + /// A list of the C++20 named modules this translation unit depends on. + std::vector NamedModuleDeps; + + /// The sequence of commands required to build the translation unit. Commands + /// should be executed in order. + /// + /// FIXME: If we add support for multi-arch builds in clang-scan-deps, we + /// should make the dependencies between commands explicit to enable parallel + /// builds of each architecture. + std::vector Commands; + + /// Deprecated driver command-line. This will be removed in a future version. + std::vector DriverCommandLine; +}; + +class FullDependencyConsumer : public DependencyConsumer { +public: + FullDependencyConsumer(const llvm::DenseSet &AlreadySeen) + : AlreadySeen(AlreadySeen) {} + + void handleBuildCommand(Command Cmd) override { + Commands.push_back(std::move(Cmd)); + } + + void handleDependencyOutputOpts(const DependencyOutputOptions &) override {} + + void handleFileDependency(StringRef File) override { + Dependencies.push_back(std::string(File)); + } + + void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) override { + PrebuiltModuleDeps.emplace_back(std::move(PMD)); + } + + void handleModuleDependency(ModuleDeps MD) override { + ClangModuleDeps[MD.ID] = std::move(MD); + } + + void handleDirectModuleDependency(ModuleID ID) override { + DirectModuleDeps.push_back(ID); + } + + void handleVisibleModule(std::string ModuleName) override { + VisibleModules.push_back(ModuleName); + } + + void handleContextHash(std::string Hash) override { + ContextHash = std::move(Hash); + } + + void handleIncludeTreeID(std::string ID) override { + IncludeTreeID = std::move(ID); + } + + void handleProvidedAndRequiredStdCXXModules( + std::optional Provided, + std::vector Requires) override { + ModuleName = Provided ? Provided->ModuleName : ""; + llvm::transform(Requires, std::back_inserter(NamedModuleDeps), + [](const auto &Module) { return Module.ModuleName; }); + } + + TranslationUnitDeps takeTranslationUnitDeps(); + +private: + std::vector Dependencies; + std::vector PrebuiltModuleDeps; + llvm::MapVector ClangModuleDeps; + std::string ModuleName; + std::vector NamedModuleDeps; + std::vector DirectModuleDeps; + std::vector VisibleModules; + std::vector Commands; + std::string ContextHash; + std::optional IncludeTreeID; + const llvm::DenseSet &AlreadySeen; +}; + +/// A callback to lookup module outputs for "-fmodule-file=", "-o" etc. +using LookupModuleOutputCallback = + llvm::function_ref; + +/// A simple dependency action controller that uses a callback. If no callback +/// is provided, it is assumed that looking up module outputs is unreachable. +class CallbackActionController + : public clang::dependencies::DependencyActionController { +public: + virtual ~CallbackActionController(); + + static std::string + lookupUnreachableModuleOutput(const clang::dependencies::ModuleDeps &MD, + clang::dependencies::ModuleOutputKind Kind) { + llvm::report_fatal_error("unexpected call to lookupModuleOutput"); + }; + + CallbackActionController(LookupModuleOutputCallback LMO) + : LookupModuleOutput(std::move(LMO)) { + if (!LookupModuleOutput) { + LookupModuleOutput = lookupUnreachableModuleOutput; + } + } + + std::string + lookupModuleOutput(const clang::dependencies::ModuleDeps &MD, + clang::dependencies::ModuleOutputKind Kind) override { + return LookupModuleOutput(MD, Kind); + } + +private: + LookupModuleOutputCallback LookupModuleOutput; +}; + +} // end namespace dependencies +} // end namespace clang + +#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGUTILS_H diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h similarity index 94% rename from clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h rename to clang/include/clang/DependencyScanning/DependencyScanningWorker.h index 812999180d81f..ad9422685d649 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h +++ b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h @@ -1,4 +1,4 @@ -//===- DependencyScanningWorker.h - clang-scan-deps worker ===---*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,15 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H +#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LLVM.h" +#include "clang/DependencyScanning/DependencyScanningService.h" +#include "clang/DependencyScanning/ModuleDepCollector.h" #include "clang/Frontend/PCHContainerOperations.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" -#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBufferRef.h" @@ -25,7 +25,6 @@ namespace clang { class DependencyOutputOptions; -namespace tooling { namespace dependencies { class DependencyScanningWorkerFilesystem; class CompilerInstanceWithContext; @@ -233,7 +232,6 @@ class DependencyScanningWorker { }; } // end namespace dependencies -} // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H +#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H diff --git a/clang/include/clang/Tooling/DependencyScanning/InProcessModuleCache.h b/clang/include/clang/DependencyScanning/InProcessModuleCache.h similarity index 82% rename from clang/include/clang/Tooling/DependencyScanning/InProcessModuleCache.h rename to clang/include/clang/DependencyScanning/InProcessModuleCache.h index 213e60b39c199..0585348fa7d1d 100644 --- a/clang/include/clang/Tooling/DependencyScanning/InProcessModuleCache.h +++ b/clang/include/clang/DependencyScanning/InProcessModuleCache.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H +#define LLVM_CLANG_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H #include "clang/Serialization/ModuleCache.h" #include "llvm/ADT/StringMap.h" @@ -16,8 +16,8 @@ #include namespace clang { -namespace tooling { namespace dependencies { + struct ModuleCacheEntry { std::shared_mutex CompilationMutex; std::atomic Timestamp = 0; @@ -30,8 +30,8 @@ struct ModuleCacheEntries { IntrusiveRefCntPtr makeInProcessModuleCache(ModuleCacheEntries &Entries); + } // namespace dependencies -} // namespace tooling } // namespace clang -#endif +#endif // LLVM_CLANG_DEPENDENCYSCANNING_INPROCESSMODULECACHE_H diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/DependencyScanning/ModuleDepCollector.h similarity index 95% rename from clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h rename to clang/include/clang/DependencyScanning/ModuleDepCollector.h index 75685f3b8abb0..c6970cd7b3abb 100644 --- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ b/clang/include/clang/DependencyScanning/ModuleDepCollector.h @@ -1,4 +1,4 @@ -//===- ModuleDepCollector.h - Callbacks to collect deps ---------*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,18 +6,18 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H +#define LLVM_CLANG_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H #include "clang/Basic/LLVM.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" +#include "clang/DependencyScanning/DependencyScanningService.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/Utils.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Serialization/ASTReader.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringSet.h" @@ -29,7 +29,6 @@ #include namespace clang { -namespace tooling { namespace dependencies { class DependencyActionController; @@ -112,7 +111,7 @@ struct ModuleID { std::tie(Other.ModuleName, Other.ContextHash); } - bool operator<(const ModuleID& Other) const { + bool operator<(const ModuleID &Other) const { return std::tie(ModuleName, ContextHash) < std::tie(Other.ModuleName, Other.ContextHash); } @@ -281,10 +280,11 @@ class ModuleDepCollectorPP final : public PPCallbacks { /// Traverses the affecting modules and updates \c MD with references to the /// parent \c ModuleDepCollector info. - void addAllAffectingClangModules(const Module *M, ModuleDeps &MD, + void + addAllAffectingClangModules(const Module *M, ModuleDeps &MD, llvm::DenseSet &AddedModules); void addAffectingClangModule(const Module *M, ModuleDeps &MD, - llvm::DenseSet &AddedModules); + llvm::DenseSet &AddedModules); /// Add discovered module dependency for the given module. void addOneModuleDep(const Module *M, const ModuleID ID, ModuleDeps &MD); @@ -423,16 +423,15 @@ bool areOptionsInStableDir(const ArrayRef Directories, const HeaderSearchOptions &HSOpts); } // end namespace dependencies -} // end namespace tooling } // end namespace clang namespace llvm { -inline hash_code hash_value(const clang::tooling::dependencies::ModuleID &ID) { +inline hash_code hash_value(const clang::dependencies::ModuleID &ID) { return hash_combine(ID.ModuleName, ID.ContextHash); } -template <> struct DenseMapInfo { - using ModuleID = clang::tooling::dependencies::ModuleID; +template <> struct DenseMapInfo { + using ModuleID = clang::dependencies::ModuleID; static inline ModuleID getEmptyKey() { return ModuleID{"", ""}; } static inline ModuleID getTombstoneKey() { return ModuleID{"~", "~"}; // ~ is not a valid module name or context hash @@ -444,4 +443,4 @@ template <> struct DenseMapInfo { }; } // namespace llvm -#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H +#endif // LLVM_CLANG_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H diff --git a/clang/include/clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h b/clang/include/clang/DependencyScanning/ScanAndUpdateArgs.h similarity index 72% rename from clang/include/clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h rename to clang/include/clang/DependencyScanning/ScanAndUpdateArgs.h index 56d520aafb42d..d5baad4735f07 100644 --- a/clang/include/clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h +++ b/clang/include/clang/DependencyScanning/ScanAndUpdateArgs.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_DRIVER_SCANANDUPDATEARGS_H -#define LLVM_CLANG_DRIVER_SCANANDUPDATEARGS_H +#ifndef LLVM_CLANG_DEPENDENCYSCANNING_SCANANDUPDATEARGS_H +#define LLVM_CLANG_DEPENDENCYSCANNING_SCANANDUPDATEARGS_H #include "clang/Basic/LLVM.h" #include "clang/Frontend/CompileJobCacheKey.h" @@ -31,9 +31,7 @@ class CASOptions; class CompilerInvocation; class DiagnosticConsumer; -namespace tooling { namespace dependencies { -class DependencyScanningTool; /// Apply CAS inputs for compilation caching to the given invocation, if /// enabled. @@ -48,22 +46,16 @@ struct DepscanPrefixMapping { llvm::PrefixMapper &Mapper); /// Add path mappings to the \p Mapper. - static void configurePrefixMapper(ArrayRef> PathPrefixMappings, - llvm::PrefixMapper &Mapper); + static void configurePrefixMapper( + ArrayRef> PathPrefixMappings, + llvm::PrefixMapper &Mapper); /// Apply the mappings from \p Mapper to \p Invocation. static void remapInvocationPaths(CompilerInvocation &Invocation, llvm::PrefixMapper &Mapper); }; -} // namespace dependencies -} // namespace tooling - -Expected scanAndUpdateCC1InlineWithTool( - tooling::dependencies::DependencyScanningTool &Tool, - DiagnosticConsumer &DiagsConsumer, raw_ostream *VerboseOS, - CompilerInvocation &Invocation, StringRef WorkingDirectory, - llvm::cas::ObjectStore &DB); +} // namespace dependencies } // end namespace clang -#endif +#endif // LLVM_CLANG_DEPENDENCYSCANNING_SCANANDUPDATEARGS_H diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanningTool.h similarity index 50% rename from clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h rename to clang/include/clang/Tooling/DependencyScanningTool.h index b553013db442c..99696370c5413 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ b/clang/include/clang/Tooling/DependencyScanningTool.h @@ -1,4 +1,4 @@ -//===- DependencyScanningTool.h - clang-scan-deps service -----------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,19 +6,20 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H -#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H +#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H +#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" -#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" -#include "clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h" +#include "clang/DependencyScanning/DependencyScanningService.h" +#include "clang/DependencyScanning/DependencyScanningUtils.h" +#include "clang/DependencyScanning/DependencyScanningWorker.h" +#include "clang/DependencyScanning/ModuleDepCollector.h" +#include "clang/DependencyScanning/ScanAndUpdateArgs.h" #include "clang/Tooling/JSONCompilationDatabase.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/CAS/CASID.h" #include "llvm/Support/PrefixMapper.h" -#include "llvm/ADT/STLExtras.h" #include #include #include @@ -37,64 +38,10 @@ class IncludeTreeRoot; namespace tooling { namespace dependencies { -/// A callback to lookup module outputs for "-fmodule-file=", "-o" etc. -using LookupModuleOutputCallback = - llvm::function_ref; - -/// Graph of modular dependencies. -using ModuleDepsGraph = std::vector; - -/// The full dependencies and module graph for a specific input. -struct TranslationUnitDeps { - /// The graph of direct and transitive modular dependencies. - ModuleDepsGraph ModuleGraph; - - /// The identifier of the C++20 module this translation unit exports. - /// - /// If the translation unit is not a module then \c ID.ModuleName is empty. - ModuleID ID; - - /// A collection of absolute paths to files that this translation unit - /// directly depends on, not including transitive dependencies. - std::vector FileDeps; - - /// A collection of prebuilt modules this translation unit directly depends - /// on, not including transitive dependencies. - std::vector PrebuiltModuleDeps; - - /// A list of modules this translation unit directly depends on, not including - /// transitive dependencies. - /// - /// This may include modules with a different context hash when it can be - /// determined that the differences are benign for this compilation. - std::vector ClangModuleDeps; - - /// A list of module names that are visible to this translation unit. This - /// includes both direct and transitive module dependencies. - std::vector VisibleModules; - - /// The include-tree for input file dependency tree. - std::optional IncludeTreeID; - - /// A list of the C++20 named modules this translation unit depends on. - std::vector NamedModuleDeps; - - /// The sequence of commands required to build the translation unit. Commands - /// should be executed in order. - /// - /// FIXME: If we add support for multi-arch builds in clang-scan-deps, we - /// should make the dependencies between commands explicit to enable parallel - /// builds of each architecture. - std::vector Commands; - - /// Deprecated driver command-line. This will be removed in a future version. - std::vector DriverCommandLine; -}; - struct P1689Rule { std::string PrimaryOutput; - std::optional Provides; - std::vector Requires; + std::optional Provides; + std::vector Requires; }; /// The high-level implementation of the dependency discovery tool that runs on @@ -105,9 +52,10 @@ class DependencyScanningTool { /// /// @param Service The parent service. Must outlive the tool. /// @param FS The filesystem for the tool to use. Defaults to the physical FS. - DependencyScanningTool(DependencyScanningService &Service, - llvm::IntrusiveRefCntPtr FS = - llvm::vfs::createPhysicalFileSystem()); + DependencyScanningTool( + clang::dependencies::DependencyScanningService &Service, + llvm::IntrusiveRefCntPtr FS = + llvm::vfs::createPhysicalFileSystem()); /// Print out the dependency information into a string using the dependency /// file format that is specified in the options (-MD is the default) and @@ -143,10 +91,10 @@ class DependencyScanningTool { MakeformatOutputPath); } - Expected - getIncludeTree(cas::ObjectStore &DB, - const std::vector &CommandLine, StringRef CWD, - LookupModuleOutputCallback LookupModuleOutput); + Expected getIncludeTree( + cas::ObjectStore &DB, const std::vector &CommandLine, + StringRef CWD, + clang::dependencies::LookupModuleOutputCallback LookupModuleOutput); /// If \p DiagGenerationAsCompilation is true it will generate error /// diagnostics same way as the normal compilation, with "N errors generated" @@ -154,7 +102,8 @@ class DependencyScanningTool { /// \p DiagOpts.DiagnosticSerializationFile setting is set for the invocation. Expected getIncludeTreeFromCompilerInvocation( cas::ObjectStore &DB, std::shared_ptr Invocation, - StringRef CWD, LookupModuleOutputCallback LookupModuleOutput, + StringRef CWD, + clang::dependencies::LookupModuleOutputCallback LookupModuleOutput, DiagnosticConsumer &DiagsConsumer, raw_ostream *VerboseOS, bool DiagGenerationAsCompilation); @@ -175,10 +124,11 @@ class DependencyScanningTool { /// /// \returns a \c StringError with the diagnostic output if clang errors /// occurred, \c TranslationUnitDeps otherwise. - llvm::Expected getTranslationUnitDependencies( + llvm::Expected + getTranslationUnitDependencies( const std::vector &CommandLine, StringRef CWD, - const llvm::DenseSet &AlreadySeen, - LookupModuleOutputCallback LookupModuleOutput, + const llvm::DenseSet &AlreadySeen, + clang::dependencies::LookupModuleOutputCallback LookupModuleOutput, std::optional TUBuffer = std::nullopt); /// Given a compilation context specified via the Clang driver command-line, @@ -187,10 +137,12 @@ class DependencyScanningTool { /// TODO: this method should be removed as soon as Swift and our C-APIs adopt /// CompilerInstanceWithContext. We are keeping it here so that it is easier /// to coordinate with Swift and C-API changes. - llvm::Expected getModuleDependencies( + llvm::Expected + getModuleDependencies( StringRef ModuleName, const std::vector &CommandLine, - StringRef CWD, const llvm::DenseSet &AlreadySeen, - LookupModuleOutputCallback LookupModuleOutput); + StringRef CWD, + const llvm::DenseSet &AlreadySeen, + clang::dependencies::LookupModuleOutputCallback LookupModuleOutput); /// The following three methods provide a new interface to perform /// by name dependency scan. The new interface's intention is to improve @@ -220,9 +172,11 @@ class DependencyScanningTool { /// arguments for dependencies. /// @return An instance of \c TranslationUnitDeps if the scan is successful. /// Otherwise it returns an error. - llvm::Expected computeDependenciesByNameWithContext( - StringRef ModuleName, const llvm::DenseSet &AlreadySeen, - LookupModuleOutputCallback LookupModuleOutput); + llvm::Expected + computeDependenciesByNameWithContext( + StringRef ModuleName, + const llvm::DenseSet &AlreadySeen, + clang::dependencies::LookupModuleOutputCallback LookupModuleOutput); /// @brief This method finializes the compiler instance. It finalizes the /// diagnostics and deletes the compiler instance. Call this method @@ -232,116 +186,37 @@ class DependencyScanningTool { llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); } - ScanningOutputFormat getScanningFormat() const { + clang::dependencies::ScanningOutputFormat getScanningFormat() const { return Worker.getScanningFormat(); } const CASOptions &getCASOpts() const { return Worker.getCASOpts(); } - static std::unique_ptr - createActionController(DependencyScanningWorker &Worker, - LookupModuleOutputCallback LookupModuleOutput); - -private: - std::unique_ptr - createActionController(LookupModuleOutputCallback LookupModuleOutput); - -private: - DependencyScanningWorker Worker; -}; - -class FullDependencyConsumer : public DependencyConsumer { -public: - FullDependencyConsumer(const llvm::DenseSet &AlreadySeen) - : AlreadySeen(AlreadySeen) {} - - void handleBuildCommand(Command Cmd) override { - Commands.push_back(std::move(Cmd)); - } - - void handleDependencyOutputOpts(const DependencyOutputOptions &) override {} - - void handleFileDependency(StringRef File) override { - Dependencies.push_back(std::string(File)); - } - - void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) override { - PrebuiltModuleDeps.emplace_back(std::move(PMD)); - } - - void handleModuleDependency(ModuleDeps MD) override { - ClangModuleDeps[MD.ID] = std::move(MD); - } - - void handleDirectModuleDependency(ModuleID ID) override { - DirectModuleDeps.push_back(ID); - } - - void handleVisibleModule(std::string ModuleName) override { - VisibleModules.push_back(ModuleName); - } - - void handleContextHash(std::string Hash) override { - ContextHash = std::move(Hash); - } - - void handleIncludeTreeID(std::string ID) override { - IncludeTreeID = std::move(ID); - } - - void handleProvidedAndRequiredStdCXXModules( - std::optional Provided, - std::vector Requires) override { - ModuleName = Provided ? Provided->ModuleName : ""; - llvm::transform(Requires, std::back_inserter(NamedModuleDeps), - [](const auto &Module) { return Module.ModuleName; }); - } - - TranslationUnitDeps takeTranslationUnitDeps(); + static std::unique_ptr + createActionController( + clang::dependencies::DependencyScanningWorker &Worker, + clang::dependencies::LookupModuleOutputCallback LookupModuleOutput); private: - std::vector Dependencies; - std::vector PrebuiltModuleDeps; - llvm::MapVector ClangModuleDeps; - std::string ModuleName; - std::vector NamedModuleDeps; - std::vector DirectModuleDeps; - std::vector VisibleModules; - std::vector Commands; - std::string ContextHash; - std::optional IncludeTreeID; - const llvm::DenseSet &AlreadySeen; -}; - -/// A simple dependency action controller that uses a callback. If no callback -/// is provided, it is assumed that looking up module outputs is unreachable. -class CallbackActionController : public DependencyActionController { -public: - virtual ~CallbackActionController(); - - static std::string lookupUnreachableModuleOutput(const ModuleDeps &MD, - ModuleOutputKind Kind) { - llvm::report_fatal_error("unexpected call to lookupModuleOutput"); - }; - - CallbackActionController(LookupModuleOutputCallback LMO) - : LookupModuleOutput(std::move(LMO)) { - if (!LookupModuleOutput) { - LookupModuleOutput = lookupUnreachableModuleOutput; - } - } - - std::string lookupModuleOutput(const ModuleDeps &MD, - ModuleOutputKind Kind) override { - return LookupModuleOutput(MD, Kind); - } + std::unique_ptr + createActionController( + clang::dependencies::LookupModuleOutputCallback LookupModuleOutput); private: - LookupModuleOutputCallback LookupModuleOutput; + clang::dependencies::DependencyScanningWorker Worker; + std::unique_ptr + DiagPrinterWithOS; }; } // end namespace dependencies } // end namespace tooling + +Expected scanAndUpdateCC1InlineWithTool( + tooling::dependencies::DependencyScanningTool &Tool, + DiagnosticConsumer &DiagsConsumer, raw_ostream *VerboseOS, + CompilerInvocation &Invocation, StringRef WorkingDirectory, + llvm::cas::ObjectStore &DB); + } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H +#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H diff --git a/clang/lib/CMakeLists.txt b/clang/lib/CMakeLists.txt index 66fad4fc328ba..ca21ef9f01990 100644 --- a/clang/lib/CMakeLists.txt +++ b/clang/lib/CMakeLists.txt @@ -19,6 +19,7 @@ add_subdirectory(Serialization) add_subdirectory(Frontend) add_subdirectory(FrontendTool) add_subdirectory(Tooling) +add_subdirectory(DependencyScanning) add_subdirectory(DirectoryWatcher) add_subdirectory(Index) add_subdirectory(IndexDataStore) diff --git a/clang/lib/Tooling/DependencyScanning/CMakeLists.txt b/clang/lib/DependencyScanning/CMakeLists.txt similarity index 94% rename from clang/lib/Tooling/DependencyScanning/CMakeLists.txt rename to clang/lib/DependencyScanning/CMakeLists.txt index 0afef66ea41b1..906489017883e 100644 --- a/clang/lib/Tooling/DependencyScanning/CMakeLists.txt +++ b/clang/lib/DependencyScanning/CMakeLists.txt @@ -10,8 +10,8 @@ add_clang_library(clangDependencyScanning DependencyScanningFilesystem.cpp DependencyScanningService.cpp DependencyScanningWorker.cpp - DependencyScanningTool.cpp IncludeTreeActionController.cpp + DependencyScanningUtils.cpp DependencyScannerImpl.cpp InProcessModuleCache.cpp ModuleDepCollector.cpp diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp similarity index 99% rename from clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp rename to clang/lib/DependencyScanning/DependencyScannerImpl.cpp index 117cbda01213c..3ff8c5e130ed2 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp +++ b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp @@ -6,21 +6,20 @@ // //===----------------------------------------------------------------------===// -#include "DependencyScannerImpl.h" +#include "clang/DependencyScanning/DependencyScannerImpl.h" #include "clang/Basic/DiagnosticCAS.h" #include "clang/Basic/DiagnosticFrontend.h" #include "clang/Basic/DiagnosticSerialization.h" +#include "clang/DependencyScanning/DependencyScanningWorker.h" +#include "clang/DependencyScanning/ScanAndUpdateArgs.h" #include "clang/Driver/Driver.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Frontend/MultiplexConsumer.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" -#include "clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/CAS/CASProvidingFileSystem.h" #include "llvm/TargetParser/Host.h" using namespace clang; -using namespace tooling; using namespace dependencies; using llvm::Error; diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp b/clang/lib/DependencyScanning/DependencyScanningFilesystem.cpp similarity index 97% rename from clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp rename to clang/lib/DependencyScanning/DependencyScanningFilesystem.cpp index b314408d79db3..455ee81cbdaee 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ b/clang/lib/DependencyScanning/DependencyScanningFilesystem.cpp @@ -1,4 +1,4 @@ -//===- DependencyScanningFilesystem.cpp - clang-scan-deps fs --------------===// +//===- DependencyScanningFilesystem.cpp - Optimized Scanning FS -----------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,15 +6,14 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" +#include "clang/DependencyScanning/DependencyScanningFilesystem.h" +#include "clang/DependencyScanning/DependencyScanningService.h" #include "llvm/CAS/CASFileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" #include using namespace clang; -using namespace tooling; using namespace dependencies; llvm::ErrorOr @@ -451,10 +450,10 @@ DepScanFile::create(EntryRef Entry) { std::unique_ptr Result; if (Entry.getObjectRefForContent()) Result = std::make_unique( - llvm::MemoryBuffer::getMemBuffer(Entry.getContents(), - Entry.getStatus().getName(), - /*RequiresNullTerminator=*/false), - *Entry.getObjectRefForContent(), Entry.getStatus()); + llvm::MemoryBuffer::getMemBuffer(Entry.getContents(), + Entry.getStatus().getName(), + /*RequiresNullTerminator=*/false), + *Entry.getObjectRefForContent(), Entry.getStatus()); else Result = std::make_unique( llvm::MemoryBuffer::getMemBuffer(Entry.getContents(), @@ -462,7 +461,6 @@ DepScanFile::create(EntryRef Entry) { /*RequiresNullTerminator=*/false), Entry.getStatus()); - return Result; } diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp b/clang/lib/DependencyScanning/DependencyScanningService.cpp similarity index 90% rename from clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp rename to clang/lib/DependencyScanning/DependencyScanningService.cpp index 2276e9e4a4013..6803f427a3d17 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp +++ b/clang/lib/DependencyScanning/DependencyScanningService.cpp @@ -1,4 +1,4 @@ -//===- DependencyScanningService.cpp - clang-scan-deps service ------------===// +//===- DependencyScanningService.cpp - Scanning Service -------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,17 +6,16 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" +#include "clang/DependencyScanning/DependencyScanningService.h" #include "clang/Basic/BitmaskEnum.h" #include "llvm/CAS/ActionCache.h" #include "llvm/CAS/ObjectStore.h" #include "llvm/Support/Process.h" using namespace clang; -using namespace tooling; using namespace dependencies; -bool clang::tooling::dependencies::shouldCacheNegativeStatsDefault() { +bool clang::dependencies::shouldCacheNegativeStatsDefault() { if (std::optional MaybeNegStats = llvm::sys::Process::GetEnv("CLANG_SCAN_CACHE_NEGATIVE_STATS")) { if (MaybeNegStats->empty()) diff --git a/clang/lib/DependencyScanning/DependencyScanningUtils.cpp b/clang/lib/DependencyScanning/DependencyScanningUtils.cpp new file mode 100644 index 0000000000000..2199944b14105 --- /dev/null +++ b/clang/lib/DependencyScanning/DependencyScanningUtils.cpp @@ -0,0 +1,39 @@ +//===- DependencyScanningUtils.cpp - Common Scanning Utilities ------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/DependencyScanning/DependencyScanningUtils.h" + +using namespace clang; +using namespace dependencies; + +TranslationUnitDeps FullDependencyConsumer::takeTranslationUnitDeps() { + TranslationUnitDeps TU; + + TU.ID.ContextHash = std::move(ContextHash); + TU.ID.ModuleName = std::move(ModuleName); + TU.NamedModuleDeps = std::move(NamedModuleDeps); + TU.FileDeps = std::move(Dependencies); + TU.PrebuiltModuleDeps = std::move(PrebuiltModuleDeps); + TU.VisibleModules = std::move(VisibleModules); + TU.Commands = std::move(Commands); + TU.IncludeTreeID = std::move(IncludeTreeID); + + for (auto &&M : ClangModuleDeps) { + auto &MD = M.second; + // TODO: Avoid handleModuleDependency even being called for modules + // we've already seen. + if (AlreadySeen.count(M.first)) + continue; + TU.ModuleGraph.push_back(std::move(MD)); + } + TU.ClangModuleDeps = std::move(DirectModuleDeps); + + return TU; +} + +CallbackActionController::~CallbackActionController() {} diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/DependencyScanning/DependencyScanningWorker.cpp similarity index 97% rename from clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp rename to clang/lib/DependencyScanning/DependencyScanningWorker.cpp index 6a5c93d4098a3..ab7e2ef4226e3 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/DependencyScanning/DependencyScanningWorker.cpp @@ -1,4 +1,4 @@ -//===- DependencyScanningWorker.cpp - clang-scan-deps worker --------------===// +//===- DependencyScanningWorker.cpp - Thread-Safe Scanning Worker ---------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,14 +6,13 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" -#include "DependencyScannerImpl.h" +#include "clang/DependencyScanning/DependencyScanningWorker.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "clang/DependencyScanning/DependencyScannerImpl.h" #include "clang/Driver/Driver.h" #include "clang/Driver/Tool.h" using namespace clang; -using namespace tooling; using namespace dependencies; using llvm::Error; diff --git a/clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp b/clang/lib/DependencyScanning/InProcessModuleCache.cpp similarity index 95% rename from clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp rename to clang/lib/DependencyScanning/InProcessModuleCache.cpp index d1e543b438225..1dd2d34032a96 100644 --- a/clang/lib/Tooling/DependencyScanning/InProcessModuleCache.cpp +++ b/clang/lib/DependencyScanning/InProcessModuleCache.cpp @@ -1,4 +1,4 @@ -//===----------------------------------------------------------------------===// +//===- InProcessModuleCache.cpp - Implicit Module Cache ---------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/DependencyScanning/InProcessModuleCache.h" +#include "clang/DependencyScanning/InProcessModuleCache.h" #include "clang/Serialization/InMemoryModuleCache.h" #include "llvm/Support/AdvisoryLock.h" @@ -15,7 +15,6 @@ #include using namespace clang; -using namespace tooling; using namespace dependencies; namespace { diff --git a/clang/lib/Tooling/DependencyScanning/IncludeTreeActionController.cpp b/clang/lib/DependencyScanning/IncludeTreeActionController.cpp similarity index 99% rename from clang/lib/Tooling/DependencyScanning/IncludeTreeActionController.cpp rename to clang/lib/DependencyScanning/IncludeTreeActionController.cpp index 1378ee22f2598..7d645ab3cdd51 100644 --- a/clang/lib/Tooling/DependencyScanning/IncludeTreeActionController.cpp +++ b/clang/lib/DependencyScanning/IncludeTreeActionController.cpp @@ -6,10 +6,10 @@ // //===----------------------------------------------------------------------===// -#include "CachingActions.h" #include "clang/APINotes/APINotesManager.h" #include "clang/APINotes/APINotesReader.h" #include "clang/CAS/IncludeTree.h" +#include "clang/DependencyScanning/CachingActions.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Preprocessor.h" #include "llvm/CAS/ObjectStore.h" @@ -17,7 +17,6 @@ #include "llvm/Support/PrefixMappingFileSystem.h" using namespace clang; -using namespace tooling; using namespace dependencies; using llvm::Error; @@ -766,8 +765,8 @@ IncludeTreeBuilder::finishIncludeTree(CompilerInstance &ScanInstance, if (Module *M = MMap.findModule(ScanInstance.getLangOpts().CurrentModule)) if (Error E = AddModule(M)) return std::move(E); - if (Module *PM = - MMap.findModule(ScanInstance.getLangOpts().ModuleName + "_Private")) + if (Module *PM = MMap.findModule(ScanInstance.getLangOpts().ModuleName + + "_Private")) if (Error E = AddModule(PM)) return std::move(E); } diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/DependencyScanning/ModuleDepCollector.cpp similarity index 99% rename from clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp rename to clang/lib/DependencyScanning/ModuleDepCollector.cpp index 64c79acf00c65..0f83804e9d068 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/DependencyScanning/ModuleDepCollector.cpp @@ -6,14 +6,13 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" - +#include "clang/DependencyScanning/ModuleDepCollector.h" #include "clang/Basic/DiagnosticCAS.h" #include "clang/Basic/MakeSupport.h" +#include "clang/DependencyScanning/DependencyScanningWorker.h" #include "clang/Frontend/CompileJobCacheKey.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CAS/CASID.h" #include "llvm/CAS/ObjectStore.h" @@ -22,7 +21,6 @@ #include using namespace clang; -using namespace tooling; using namespace dependencies; void ModuleDeps::forEachFileDep(llvm::function_ref Cb) const { diff --git a/clang/lib/Tooling/DependencyScanning/ScanAndUpdateArgs.cpp b/clang/lib/DependencyScanning/ScanAndUpdateArgs.cpp similarity index 76% rename from clang/lib/Tooling/DependencyScanning/ScanAndUpdateArgs.cpp rename to clang/lib/DependencyScanning/ScanAndUpdateArgs.cpp index fb67b71fe0840..61d252c3c10a9 100644 --- a/clang/lib/Tooling/DependencyScanning/ScanAndUpdateArgs.cpp +++ b/clang/lib/DependencyScanning/ScanAndUpdateArgs.cpp @@ -6,17 +6,17 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h" +#include "clang/DependencyScanning/ScanAndUpdateArgs.h" #include "clang/CAS/IncludeTree.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Lex/HeaderSearchOptions.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" +#include "clang/Tooling/DependencyScanningTool.h" #include "llvm/CAS/ObjectStore.h" #include "llvm/Support/Path.h" #include "llvm/Support/PrefixMapper.h" using namespace clang; -using namespace clang::tooling::dependencies; +using namespace clang::dependencies; using llvm::Error; static void updateRelativePath(std::string &Path, @@ -29,9 +29,11 @@ static void updateRelativePath(std::string &Path, Path = PathStorage.str(); } -void tooling::dependencies::configureInvocationForCaching( - CompilerInvocation &CI, CASOptions CASOpts, std::string InputID, - CachingInputKind InputKind, std::string WorkingDir) { +void dependencies::configureInvocationForCaching(CompilerInvocation &CI, + CASOptions CASOpts, + std::string InputID, + CachingInputKind InputKind, + std::string WorkingDir) { CI.getCASOpts() = std::move(CASOpts); auto &FrontendOpts = CI.getFrontendOpts(); FrontendOpts.CacheCompileJob = true; @@ -160,7 +162,8 @@ void DepscanPrefixMapping::configurePrefixMapper(const CompilerInvocation &CI, } void DepscanPrefixMapping::configurePrefixMapper( - ArrayRef> PathPrefixMappings, llvm::PrefixMapper &Mapper) { + ArrayRef> PathPrefixMappings, + llvm::PrefixMapper &Mapper) { if (PathPrefixMappings.empty()) return; @@ -171,40 +174,3 @@ void DepscanPrefixMapping::configurePrefixMapper( Mapper.sort(); } - -Expected clang::scanAndUpdateCC1InlineWithTool( - DependencyScanningTool &Tool, DiagnosticConsumer &DiagsConsumer, - raw_ostream *VerboseOS, CompilerInvocation &Invocation, - StringRef WorkingDirectory, llvm::cas::ObjectStore &DB) { - // Override the CASOptions. They may match (the caller having sniffed them - // out of InputArgs) but if they have been overridden we want the new ones. - Invocation.getCASOpts() = Tool.getCASOpts(); - - llvm::PrefixMapper Mapper; - DepscanPrefixMapping::configurePrefixMapper(Invocation, Mapper); - - auto ScanInvocation = std::make_shared(Invocation); - // An error during dep-scanning is treated as if the main compilation has - // failed, but warnings are ignored and deferred for the main compilation. - ScanInvocation->getDiagnosticOpts().IgnoreWarnings = true; - - LookupModuleOutputCallback Lookup; - - std::optional Root; - if (Error E = - Tool.getIncludeTreeFromCompilerInvocation( - DB, std::move(ScanInvocation), WorkingDirectory, - /*LookupModuleOutput=*/nullptr, DiagsConsumer, VerboseOS, - /*DiagGenerationAsCompilation*/ true) - .moveInto(Root)) - return std::move(E); - - // Turn off dependency outputs. Should have already been emitted. - Invocation.getDependencyOutputOpts().OutputFile.clear(); - - configureInvocationForCaching(Invocation, Tool.getCASOpts(), Root->toString(), - CachingInputKind::IncludeTree, - WorkingDirectory.str()); - DepscanPrefixMapping::remapInvocationPaths(Invocation, Mapper); - return *Root; -} diff --git a/clang/lib/Tooling/CMakeLists.txt b/clang/lib/Tooling/CMakeLists.txt index 67a76d43aebd1..5ba1ac9135e72 100644 --- a/clang/lib/Tooling/CMakeLists.txt +++ b/clang/lib/Tooling/CMakeLists.txt @@ -11,7 +11,6 @@ add_subdirectory(Refactor) add_subdirectory(Refactoring) add_subdirectory(ASTDiff) add_subdirectory(Syntax) -add_subdirectory(DependencyScanning) add_subdirectory(Transformer) add_clang_library(clangTooling @@ -19,6 +18,7 @@ add_clang_library(clangTooling ArgumentsAdjusters.cpp CommonOptionsParser.cpp CompilationDatabase.cpp + DependencyScanningTool.cpp Execution.cpp ExpandResponseFilesCompilationDatabase.cpp FileMatchTrie.cpp @@ -40,6 +40,7 @@ add_clang_library(clangTooling clangAST clangASTMatchers clangBasic + clangDependencyScanning clangDriver clangOptions clangFormat diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanningTool.cpp similarity index 84% rename from clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp rename to clang/lib/Tooling/DependencyScanningTool.cpp index 787f3323a2892..bdf0569f337e6 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp +++ b/clang/lib/Tooling/DependencyScanningTool.cpp @@ -6,17 +6,18 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" -#include "CachingActions.h" +#include "clang/Tooling/DependencyScanningTool.h" #include "clang/CAS/IncludeTree.h" +#include "clang/DependencyScanning/CachingActions.h" +#include "clang/DependencyScanning/ScanAndUpdateArgs.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/Utils.h" -#include "clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h" #include "llvm/CAS/ObjectStore.h" using namespace clang; using namespace tooling; -using namespace dependencies; +using namespace clang::dependencies; +using namespace clang::tooling::dependencies; using llvm::Error; DependencyScanningTool::DependencyScanningTool( @@ -134,7 +135,7 @@ class GetIncludeTree : public EmptyDependencyConsumer { cas::ObjectStore &DB; std::optional IncludeTreeID; }; -} +} // namespace Expected DependencyScanningTool::getIncludeTree( cas::ObjectStore &DB, const std::vector &CommandLine, @@ -278,33 +279,6 @@ llvm::Error DependencyScanningTool::finalizeCompilerInstanceWithContext() { return Worker.finalizeCompilerInstanceWithContextOrError(); } -TranslationUnitDeps FullDependencyConsumer::takeTranslationUnitDeps() { - TranslationUnitDeps TU; - - TU.ID.ContextHash = std::move(ContextHash); - TU.ID.ModuleName = std::move(ModuleName); - TU.NamedModuleDeps = std::move(NamedModuleDeps); - TU.FileDeps = std::move(Dependencies); - TU.PrebuiltModuleDeps = std::move(PrebuiltModuleDeps); - TU.VisibleModules = std::move(VisibleModules); - TU.Commands = std::move(Commands); - TU.IncludeTreeID = std::move(IncludeTreeID); - - for (auto &&M : ClangModuleDeps) { - auto &MD = M.second; - // TODO: Avoid handleModuleDependency even being called for modules - // we've already seen. - if (AlreadySeen.count(M.first)) - continue; - TU.ModuleGraph.push_back(std::move(MD)); - } - TU.ClangModuleDeps = std::move(DirectModuleDeps); - - return TU; -} - -CallbackActionController::~CallbackActionController() {} - std::unique_ptr DependencyScanningTool::createActionController( DependencyScanningWorker &Worker, @@ -320,3 +294,40 @@ DependencyScanningTool::createActionController( LookupModuleOutputCallback LookupModuleOutput) { return createActionController(Worker, std::move(LookupModuleOutput)); } + +Expected clang::scanAndUpdateCC1InlineWithTool( + DependencyScanningTool &Tool, DiagnosticConsumer &DiagsConsumer, + raw_ostream *VerboseOS, CompilerInvocation &Invocation, + StringRef WorkingDirectory, llvm::cas::ObjectStore &DB) { + // Override the CASOptions. They may match (the caller having sniffed them + // out of InputArgs) but if they have been overridden we want the new ones. + Invocation.getCASOpts() = Tool.getCASOpts(); + + llvm::PrefixMapper Mapper; + DepscanPrefixMapping::configurePrefixMapper(Invocation, Mapper); + + auto ScanInvocation = std::make_shared(Invocation); + // An error during dep-scanning is treated as if the main compilation has + // failed, but warnings are ignored and deferred for the main compilation. + ScanInvocation->getDiagnosticOpts().IgnoreWarnings = true; + + LookupModuleOutputCallback Lookup; + + std::optional Root; + if (Error E = + Tool.getIncludeTreeFromCompilerInvocation( + DB, std::move(ScanInvocation), WorkingDirectory, + /*LookupModuleOutput=*/nullptr, DiagsConsumer, VerboseOS, + /*DiagGenerationAsCompilation*/ true) + .moveInto(Root)) + return std::move(E); + + // Turn off dependency outputs. Should have already been emitted. + Invocation.getDependencyOutputOpts().OutputFile.clear(); + + configureInvocationForCaching(Invocation, Tool.getCASOpts(), Root->toString(), + CachingInputKind::IncludeTree, + WorkingDirectory.str()); + DepscanPrefixMapping::remapInvocationPaths(Invocation, Mapper); + return *Root; +} diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index 1eb3fd8907cd9..5e0a9c3b185f8 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -7,15 +7,15 @@ //===----------------------------------------------------------------------===// #include "clang/CAS/IncludeTree.h" +#include "clang/DependencyScanning/DependencyScanningService.h" +#include "clang/DependencyScanning/DependencyScanningWorker.h" +#include "clang/DependencyScanning/ScanAndUpdateArgs.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Tooling/CommonOptionsParser.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" -#include "clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h" +#include "clang/Tooling/DependencyScanningTool.h" #include "clang/Tooling/JSONCompilationDatabase.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/STLExtras.h" @@ -46,7 +46,8 @@ using namespace clang; using namespace tooling; -using namespace tooling::dependencies; +using namespace clang::dependencies; +using namespace clang::tooling::dependencies; namespace { diff --git a/clang/tools/driver/CMakeLists.txt b/clang/tools/driver/CMakeLists.txt index 491a6d692d2a3..8057f3a331ddf 100644 --- a/clang/tools/driver/CMakeLists.txt +++ b/clang/tools/driver/CMakeLists.txt @@ -72,6 +72,7 @@ clang_target_link_libraries(clang clangFrontendTool clangOptions clangSerialization + clangTooling ) if(WIN32 AND NOT CYGWIN) diff --git a/clang/tools/driver/cc1depscanProtocol.cpp b/clang/tools/driver/cc1depscanProtocol.cpp index d33c33ed39b92..bb32ec169b53e 100644 --- a/clang/tools/driver/cc1depscanProtocol.cpp +++ b/clang/tools/driver/cc1depscanProtocol.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include "cc1depscanProtocol.h" -#include "clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h" +#include "clang/DependencyScanning/ScanAndUpdateArgs.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/Allocator.h" diff --git a/clang/tools/driver/cc1depscan_main.cpp b/clang/tools/driver/cc1depscan_main.cpp index 78e023b9bf1c7..a2674f0643d31 100644 --- a/clang/tools/driver/cc1depscan_main.cpp +++ b/clang/tools/driver/cc1depscan_main.cpp @@ -13,6 +13,8 @@ #include "clang/Basic/Stack.h" #include "clang/Basic/TargetOptions.h" #include "clang/Config/config.h" +#include "clang/DependencyScanning/DependencyScanningService.h" +#include "clang/DependencyScanning/ScanAndUpdateArgs.h" #include "clang/Frontend/CompileJobCacheKey.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" @@ -21,9 +23,7 @@ #include "clang/Frontend/Utils.h" #include "clang/FrontendTool/Utils.h" #include "clang/Options/Options.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" -#include "clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h" +#include "clang/Tooling/DependencyScanningTool.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallVector.h" @@ -897,10 +897,9 @@ int ScanServer::listen() { if (!Cache) reportError("cannot create ActionCache"); - tooling::dependencies::DependencyScanningService Service( - tooling::dependencies::ScanningMode::DependencyDirectivesScan, - tooling::dependencies::ScanningOutputFormat::IncludeTree, CASOpts, CAS, - Cache); + dependencies::DependencyScanningService Service( + dependencies::ScanningMode::DependencyDirectivesScan, + dependencies::ScanningOutputFormat::IncludeTree, CASOpts, CAS, Cache); std::atomic NumRunning(0); @@ -1116,10 +1115,9 @@ scanAndUpdateCC1Inline(const char *Exec, ArrayRef InputArgs, if (!DB || !Cache) return 1; - tooling::dependencies::DependencyScanningService Service( - tooling::dependencies::ScanningMode::DependencyDirectivesScan, - tooling::dependencies::ScanningOutputFormat::IncludeTree, CASOpts, DB, - Cache); + dependencies::DependencyScanningService Service( + dependencies::ScanningMode::DependencyDirectivesScan, + dependencies::ScanningOutputFormat::IncludeTree, CASOpts, DB, Cache); llvm::IntrusiveRefCntPtr UnderlyingFS = llvm::vfs::createPhysicalFileSystem(); UnderlyingFS = diff --git a/clang/tools/libclang/CDependencies.cpp b/clang/tools/libclang/CDependencies.cpp index 63b29446c4281..2efa9fb417cbb 100644 --- a/clang/tools/libclang/CDependencies.cpp +++ b/clang/tools/libclang/CDependencies.cpp @@ -18,12 +18,12 @@ #include "clang-c/Dependencies.h" +#include "clang/DependencyScanning/DependencyScanningService.h" +#include "clang/DependencyScanning/DependencyScanningWorker.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/SerializedDiagnosticPrinter.h" #include "clang/Options/Options.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" +#include "clang/Tooling/DependencyScanningTool.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CAS/CASProvidingFileSystem.h" #include "llvm/Option/ArgList.h" @@ -31,6 +31,7 @@ #include "llvm/Support/Process.h" using namespace clang; +using namespace clang::dependencies; using namespace clang::tooling::dependencies; namespace { diff --git a/clang/unittests/CAS/IncludeTreeTest.cpp b/clang/unittests/CAS/IncludeTreeTest.cpp index 382a6a092815a..0300a5f7e2814 100644 --- a/clang/unittests/CAS/IncludeTreeTest.cpp +++ b/clang/unittests/CAS/IncludeTreeTest.cpp @@ -1,6 +1,6 @@ #include "clang/CAS/IncludeTree.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" -#include "clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h" +#include "clang/DependencyScanning/ScanAndUpdateArgs.h" +#include "clang/Tooling/DependencyScanningTool.h" #include "llvm/CAS/CASProvidingFileSystem.h" #include "llvm/CAS/ObjectStore.h" #include "llvm/Support/Error.h" @@ -11,9 +11,10 @@ using namespace clang; using namespace clang::cas; +using namespace clang::dependencies; using namespace tooling; -using namespace dependencies; +using namespace tooling::dependencies; TEST(IncludeTree, IncludeTreeScan) { StringRef PathSep = llvm::sys::path::get_separator(); diff --git a/clang/unittests/CMakeLists.txt b/clang/unittests/CMakeLists.txt index efa4190105d46..e6dc83c4d568f 100644 --- a/clang/unittests/CMakeLists.txt +++ b/clang/unittests/CMakeLists.txt @@ -80,6 +80,7 @@ add_subdirectory(CAS) add_subdirectory(Lex) add_subdirectory(Parse) add_subdirectory(Driver) +add_subdirectory(DependencyScanning) if(CLANG_ENABLE_STATIC_ANALYZER) add_subdirectory(Analysis) add_subdirectory(StaticAnalyzer) diff --git a/clang/unittests/DependencyScanning/CMakeLists.txt b/clang/unittests/DependencyScanning/CMakeLists.txt new file mode 100644 index 0000000000000..40425820d4d08 --- /dev/null +++ b/clang/unittests/DependencyScanning/CMakeLists.txt @@ -0,0 +1,11 @@ +add_clang_unittest(ClangDependencyScanningTests + DependencyScanningFilesystemTest.cpp + DependencyScanningWorkerTest.cpp + CLANG_LIBS + clangDependencyScanning + clangFrontend # For TextDiagnosticPrinter. + LLVM_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} + Option + Support + ) diff --git a/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp b/clang/unittests/DependencyScanning/DependencyScanningFilesystemTest.cpp similarity index 89% rename from clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp rename to clang/unittests/DependencyScanning/DependencyScanningFilesystemTest.cpp index b7184c8013cbc..5ae49bdd4bfb9 100644 --- a/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp +++ b/clang/unittests/DependencyScanning/DependencyScanningFilesystemTest.cpp @@ -6,15 +6,15 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" +#include "clang/DependencyScanning/DependencyScanningFilesystem.h" #include "clang/CAS/CASOptions.h" +#include "clang/DependencyScanning/DependencyScanningService.h" #include "llvm/ADT/SmallString.h" #include "llvm/CAS/CachingOnDiskFileSystem.h" #include "llvm/Support/VirtualFileSystem.h" #include "gtest/gtest.h" -using namespace clang::tooling::dependencies; +using namespace clang::dependencies; TEST(DependencyScanningFilesystem, OpenFileAndGetBufferRepeatedly) { auto InMemoryFS = llvm::makeIntrusiveRefCnt(); @@ -23,8 +23,8 @@ TEST(DependencyScanningFilesystem, OpenFileAndGetBufferRepeatedly) { DependencyScanningService Service( ScanningMode::DependencyDirectivesScan, ScanningOutputFormat::Make, - clang::CASOptions(), nullptr, nullptr, - ScanningOptimizations::Default, /*EagerLoadModules=*/false, + clang::CASOptions(), nullptr, nullptr, ScanningOptimizations::Default, + /*EagerLoadModules=*/false, /*TraceVFS=*/false, llvm::sys::toTimeT(std::chrono::system_clock::now()), /*CacheNegativeStats=*/true); DependencyScanningWorkerFilesystem DepFS(Service, InMemoryFS); @@ -62,8 +62,8 @@ TEST(DependencyScanningWorkerFilesystem, CacheStatusFailures) { DependencyScanningService Service( ScanningMode::DependencyDirectivesScan, ScanningOutputFormat::Make, - clang::CASOptions(), nullptr, nullptr, - ScanningOptimizations::Default, /*EagerLoadModules=*/false, + clang::CASOptions(), nullptr, nullptr, ScanningOptimizations::Default, + /*EagerLoadModules=*/false, /*TraceVFS=*/false, llvm::sys::toTimeT(std::chrono::system_clock::now()), /*CacheNegativeStats=*/true); DependencyScanningWorkerFilesystem DepFS(Service, InstrumentingFS); @@ -93,8 +93,8 @@ TEST(DependencyScanningFilesystem, CacheGetRealPath) { DependencyScanningService Service( ScanningMode::DependencyDirectivesScan, ScanningOutputFormat::Make, - clang::CASOptions(), nullptr, nullptr, - ScanningOptimizations::Default, /*EagerLoadModules=*/false, + clang::CASOptions(), nullptr, nullptr, ScanningOptimizations::Default, + /*EagerLoadModules=*/false, /*TraceVFS=*/false, llvm::sys::toTimeT(std::chrono::system_clock::now()), /*CacheNegativeStats=*/true); DependencyScanningWorkerFilesystem DepFS(Service, InstrumentingFS); @@ -131,9 +131,9 @@ TEST(DependencyScanningFilesystem, RealPathAndStatusInvariants) { InMemoryFS->addFile("/foo.c", 0, llvm::MemoryBuffer::getMemBuffer("")); InMemoryFS->addFile("/bar.c", 0, llvm::MemoryBuffer::getMemBuffer("")); - DependencyScanningService Service( - ScanningMode::DependencyDirectivesScan, ScanningOutputFormat::Make, - clang::CASOptions(), nullptr, nullptr); + DependencyScanningService Service(ScanningMode::DependencyDirectivesScan, + ScanningOutputFormat::Make, + clang::CASOptions(), nullptr, nullptr); DependencyScanningWorkerFilesystem DepFS(Service, InMemoryFS); // Success. @@ -188,8 +188,8 @@ TEST(DependencyScanningFilesystem, CacheStatOnExists) { InMemoryFS->addFile("/bar", 0, llvm::MemoryBuffer::getMemBuffer("")); DependencyScanningService Service( ScanningMode::DependencyDirectivesScan, ScanningOutputFormat::Make, - clang::CASOptions(), nullptr, nullptr, - ScanningOptimizations::Default, /*EagerLoadModules=*/false, + clang::CASOptions(), nullptr, nullptr, ScanningOptimizations::Default, + /*EagerLoadModules=*/false, /*TraceVFS=*/false, llvm::sys::toTimeT(std::chrono::system_clock::now()), /*CacheNegativeStats=*/true); DependencyScanningWorkerFilesystem DepFS(Service, InstrumentingFS); @@ -216,8 +216,8 @@ TEST(DependencyScanningFilesystem, CacheStatFailures) { DependencyScanningService Service( ScanningMode::DependencyDirectivesScan, ScanningOutputFormat::Make, - clang::CASOptions(), nullptr, nullptr, - ScanningOptimizations::Default, /*EagerLoadModules=*/false, + clang::CASOptions(), nullptr, nullptr, ScanningOptimizations::Default, + /*EagerLoadModules=*/false, /*TraceVFS=*/false, llvm::sys::toTimeT(std::chrono::system_clock::now()), /*CacheNegativeStats=*/true); DependencyScanningWorkerFilesystem DepFS(Service, InstrumentingFS); @@ -248,8 +248,8 @@ TEST(DependencyScanningFilesystem, DiagnoseStaleStatFailures) { DependencyScanningService Service( ScanningMode::DependencyDirectivesScan, ScanningOutputFormat::Make, - clang::CASOptions(), nullptr, nullptr, - ScanningOptimizations::Default, /*EagerLoadModules=*/false, + clang::CASOptions(), nullptr, nullptr, ScanningOptimizations::Default, + /*EagerLoadModules=*/false, /*TraceVFS=*/false, llvm::sys::toTimeT(std::chrono::system_clock::now()), /*CacheNegativeStats=*/true); DependencyScanningWorkerFilesystem DepFS(Service, InMemoryFS); @@ -279,8 +279,8 @@ TEST(DependencyScanningFilesystem, DiagnoseCachedFileSizeChange) { DependencyScanningService Service( ScanningMode::DependencyDirectivesScan, ScanningOutputFormat::Make, - clang::CASOptions(), nullptr, nullptr, - ScanningOptimizations::Default, /*EagerLoadModules=*/false, + clang::CASOptions(), nullptr, nullptr, ScanningOptimizations::Default, + /*EagerLoadModules=*/false, /*TraceVFS=*/false, llvm::sys::toTimeT(std::chrono::system_clock::now()), /*CacheNegativeStats=*/true); DependencyScanningWorkerFilesystem DepFS(Service, InMemoryFS1); @@ -316,9 +316,9 @@ TEST(DependencyScanningFilesystem, DoNotDiagnoseDirSizeChange) { llvm::IntrusiveRefCntPtr FS = llvm::vfs::createPhysicalFileSystem(); - DependencyScanningService Service( - ScanningMode::DependencyDirectivesScan, ScanningOutputFormat::Make, - clang::CASOptions(), nullptr, nullptr); + DependencyScanningService Service(ScanningMode::DependencyDirectivesScan, + ScanningOutputFormat::Make, + clang::CASOptions(), nullptr, nullptr); DependencyScanningWorkerFilesystem DepFS(Service, FS); // Trigger the file system cache. diff --git a/clang/unittests/DependencyScanning/DependencyScanningWorkerTest.cpp b/clang/unittests/DependencyScanning/DependencyScanningWorkerTest.cpp new file mode 100644 index 0000000000000..c761f4ea484cb --- /dev/null +++ b/clang/unittests/DependencyScanning/DependencyScanningWorkerTest.cpp @@ -0,0 +1,98 @@ +//===- DependencyScanningWorkerTest.cpp -----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/DependencyScanning/DependencyScanningWorker.h" +#include "clang/DependencyScanning/DependencyScanningUtils.h" +#include "llvm/Support/FormatVariadic.h" +#include "gtest/gtest.h" +#include + +using namespace clang; +using namespace dependencies; + +TEST(DependencyScanner, ScanDepsWithDiagConsumer) { + StringRef CWD = "/root"; + + auto VFS = llvm::makeIntrusiveRefCnt(); + VFS->setCurrentWorkingDirectory(CWD); + auto Sept = llvm::sys::path::get_separator(); + std::string HeaderPath = + std::string(llvm::formatv("{0}root{0}header.h", Sept)); + std::string TestPath = std::string(llvm::formatv("{0}root{0}test.cpp", Sept)); + std::string AsmPath = std::string(llvm::formatv("{0}root{0}test.s", Sept)); + + VFS->addFile(HeaderPath, 0, llvm::MemoryBuffer::getMemBuffer("\n")); + VFS->addFile(TestPath, 0, + llvm::MemoryBuffer::getMemBuffer("#include \"header.h\"\n")); + VFS->addFile(AsmPath, 0, llvm::MemoryBuffer::getMemBuffer("")); + + DependencyScanningService Service(ScanningMode::DependencyDirectivesScan, + ScanningOutputFormat::Make, CASOptions(), + nullptr, nullptr); + DependencyScanningWorker Worker(Service, VFS); + + llvm::DenseSet AlreadySeen; + FullDependencyConsumer DC(AlreadySeen); + CallbackActionController AC(nullptr); + + struct EnsureFinishedConsumer : public DiagnosticConsumer { + bool Finished = false; + void finish() override { Finished = true; } + }; + + { + // Check that a successful scan calls DiagConsumer.finish(). + std::vector Args = {"clang", + "-target", + "x86_64-apple-macosx10.7", + "-c", + "test.cpp", + "-o" + "test.cpp.o"}; + + EnsureFinishedConsumer DiagConsumer; + bool Success = Worker.computeDependencies(CWD, Args, DC, AC, DiagConsumer); + + EXPECT_TRUE(Success); + EXPECT_EQ(DiagConsumer.getNumErrors(), 0u); + EXPECT_TRUE(DiagConsumer.Finished); + } + + { + // Check that an invalid command-line, which never enters the scanning + // action calls DiagConsumer.finish(). + std::vector Args = {"clang", "-invalid-arg"}; + EnsureFinishedConsumer DiagConsumer; + bool Success = Worker.computeDependencies(CWD, Args, DC, AC, DiagConsumer); + + EXPECT_FALSE(Success); + EXPECT_GE(DiagConsumer.getNumErrors(), 1u); + EXPECT_TRUE(DiagConsumer.Finished); + } + + { + // Check that a valid command line that produces no scanning jobs calls + // DiagConsumer.finish(). + std::vector Args = {"clang", + "-target", + "x86_64-apple-macosx10.7", + "-c", + "-x", + "assembler", + "test.s", + "-o" + "test.cpp.o"}; + + EnsureFinishedConsumer DiagConsumer; + bool Success = Worker.computeDependencies(CWD, Args, DC, AC, DiagConsumer); + + EXPECT_FALSE(Success); + EXPECT_EQ(DiagConsumer.getNumErrors(), 1u); + EXPECT_TRUE(DiagConsumer.Finished); + } +} diff --git a/clang/unittests/Tooling/CMakeLists.txt b/clang/unittests/Tooling/CMakeLists.txt index 51ca7f03a2615..dd9cf7ec879b7 100644 --- a/clang/unittests/Tooling/CMakeLists.txt +++ b/clang/unittests/Tooling/CMakeLists.txt @@ -14,8 +14,7 @@ add_clang_unittest(ToolingTests LookupTest.cpp QualTypeNamesTest.cpp RangeSelectorTest.cpp - DependencyScanning/DependencyScannerTest.cpp - DependencyScanning/DependencyScanningFilesystemTest.cpp + DependencyScannerTest.cpp RecursiveASTVisitorTests/Attr.cpp RecursiveASTVisitorTests/BitfieldInitializer.cpp RecursiveASTVisitorTests/CallbacksLeaf.cpp diff --git a/clang/unittests/Tooling/DependencyScanning/DependencyScannerTest.cpp b/clang/unittests/Tooling/DependencyScannerTest.cpp similarity index 84% rename from clang/unittests/Tooling/DependencyScanning/DependencyScannerTest.cpp rename to clang/unittests/Tooling/DependencyScannerTest.cpp index 8c54210e4ba7a..fc29f1236d174 100644 --- a/clang/unittests/Tooling/DependencyScanning/DependencyScannerTest.cpp +++ b/clang/unittests/Tooling/DependencyScannerTest.cpp @@ -9,13 +9,13 @@ #include "clang/AST/ASTConsumer.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclGroup.h" +#include "clang/DependencyScanning/DependencyScanningWorker.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Tooling/CompilationDatabase.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" +#include "clang/Tooling/DependencyScanningTool.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CAS/CASFileSystem.h" @@ -33,7 +33,8 @@ using namespace clang; using namespace clang::cas; using namespace tooling; -using namespace dependencies; +using namespace clang::dependencies; +using namespace tooling::dependencies; namespace { @@ -364,88 +365,6 @@ TEST(DependencyScanner, ScanDepsWithModuleLookup) { EXPECT_EQ(InterceptFS->ReadFiles, std::vector{"test.m"}); } -TEST(DependencyScanner, ScanDepsWithDiagConsumer) { - StringRef CWD = "/root"; - - auto VFS = llvm::makeIntrusiveRefCnt(); - VFS->setCurrentWorkingDirectory(CWD); - auto Sept = llvm::sys::path::get_separator(); - std::string HeaderPath = - std::string(llvm::formatv("{0}root{0}header.h", Sept)); - std::string TestPath = std::string(llvm::formatv("{0}root{0}test.cpp", Sept)); - std::string AsmPath = std::string(llvm::formatv("{0}root{0}test.s", Sept)); - - VFS->addFile(HeaderPath, 0, llvm::MemoryBuffer::getMemBuffer("\n")); - VFS->addFile(TestPath, 0, - llvm::MemoryBuffer::getMemBuffer("#include \"header.h\"\n")); - VFS->addFile(AsmPath, 0, llvm::MemoryBuffer::getMemBuffer("")); - - DependencyScanningService Service(ScanningMode::DependencyDirectivesScan, - ScanningOutputFormat::Make, CASOptions(), - nullptr, nullptr); - DependencyScanningWorker Worker(Service, VFS); - - llvm::DenseSet AlreadySeen; - FullDependencyConsumer DC(AlreadySeen); - CallbackActionController AC(nullptr); - - struct EnsureFinishedConsumer : public DiagnosticConsumer { - bool Finished = false; - void finish() override { Finished = true; } - }; - - { - // Check that a successful scan calls DiagConsumer.finish(). - std::vector Args = {"clang", - "-target", - "x86_64-apple-macosx10.7", - "-c", - "test.cpp", - "-o" - "test.cpp.o"}; - - EnsureFinishedConsumer DiagConsumer; - bool Success = Worker.computeDependencies(CWD, Args, DC, AC, DiagConsumer); - - EXPECT_TRUE(Success); - EXPECT_EQ(DiagConsumer.getNumErrors(), 0u); - EXPECT_TRUE(DiagConsumer.Finished); - } - - { - // Check that an invalid command-line, which never enters the scanning - // action calls DiagConsumer.finish(). - std::vector Args = {"clang", "-invalid-arg"}; - EnsureFinishedConsumer DiagConsumer; - bool Success = Worker.computeDependencies(CWD, Args, DC, AC, DiagConsumer); - - EXPECT_FALSE(Success); - EXPECT_GE(DiagConsumer.getNumErrors(), 1u); - EXPECT_TRUE(DiagConsumer.Finished); - } - - { - // Check that a valid command line that produces no scanning jobs calls - // DiagConsumer.finish(). - std::vector Args = {"clang", - "-target", - "x86_64-apple-macosx10.7", - "-c", - "-x", - "assembler", - "test.s", - "-o" - "test.cpp.o"}; - - EnsureFinishedConsumer DiagConsumer; - bool Success = Worker.computeDependencies(CWD, Args, DC, AC, DiagConsumer); - - EXPECT_FALSE(Success); - EXPECT_EQ(DiagConsumer.getNumErrors(), 1u); - EXPECT_TRUE(DiagConsumer.Finished); - } -} - TEST(DependencyScanner, NoNegativeCache) { StringRef CWD = "/root"; @@ -525,8 +444,9 @@ TEST(DependencyScanner, NoNegativeCacheCAS) { llvm::MemoryBuffer::getMemBuffer("#include \"header.h\"")); DependencyScanningService Service( - ScanningMode::DependencyDirectivesScan, ScanningOutputFormat::FullIncludeTree, - CASOptions(), DB, Cache, ScanningOptimizations::Default, + ScanningMode::DependencyDirectivesScan, + ScanningOutputFormat::FullIncludeTree, CASOptions(), DB, Cache, + ScanningOptimizations::Default, /*EagerLoadModules=*/false, /*TraceVFS=*/false, llvm::sys::toTimeT(std::chrono::system_clock::now()), /*CacheNegativeStats=*/false); diff --git a/clang/unittests/libclang/DependencyScanningCAPITests.cpp b/clang/unittests/libclang/DependencyScanningCAPITests.cpp index c33f55aa9603f..b1b6daf077533 100644 --- a/clang/unittests/libclang/DependencyScanningCAPITests.cpp +++ b/clang/unittests/libclang/DependencyScanningCAPITests.cpp @@ -7,12 +7,11 @@ //===----------------------------------------------------------------------===// #include "clang-c/Dependencies.h" -#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" +#include "clang/DependencyScanning/DependencyScanningService.h" #include "gtest/gtest.h" using namespace clang; -using namespace tooling; -using namespace dependencies; +using namespace clang::dependencies; TEST(DependencyScanningCAPITests, DependencyScanningFSCacheOutOfDate) { // This test is setup to have two out-of-date file system cache entries,