1 //===- DependencyScanningTool.h - clang-scan-deps service -----------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H 10 #define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H 11 12 #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" 13 #include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" 14 #include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" 15 #include "clang/Tooling/JSONCompilationDatabase.h" 16 #include "llvm/ADT/StringSet.h" 17 #include <string> 18 19 namespace clang { 20 namespace tooling { 21 namespace dependencies { 22 23 /// The full dependencies and module graph for a specific input. 24 struct FullDependencies { 25 /// The identifier of the C++20 module this translation unit exports. 26 /// 27 /// If the translation unit is not a module then \c ID.ModuleName is empty. 28 ModuleID ID; 29 30 /// A collection of absolute paths to files that this translation unit 31 /// directly depends on, not including transitive dependencies. 32 std::vector<std::string> FileDeps; 33 34 /// A collection of prebuilt modules this translation unit directly depends 35 /// on, not including transitive dependencies. 36 std::vector<PrebuiltModuleDep> PrebuiltModuleDeps; 37 38 /// A list of modules this translation unit directly depends on, not including 39 /// transitive dependencies. 40 /// 41 /// This may include modules with a different context hash when it can be 42 /// determined that the differences are benign for this compilation. 43 std::vector<ModuleID> ClangModuleDeps; 44 45 /// The original command line of the TU (excluding the compiler executable). 46 std::vector<std::string> OriginalCommandLine; 47 48 /// Get the full command line. 49 /// 50 /// \param LookupModuleOutput This function is called to fill in 51 /// "-fmodule-file=", "-o" and other output 52 /// arguments for dependencies. 53 std::vector<std::string> getCommandLine( 54 llvm::function_ref<std::string(const ModuleID &, ModuleOutputKind)> 55 LookupOutput) const; 56 57 /// Get the full command line, excluding -fmodule-file=" arguments. 58 std::vector<std::string> getCommandLineWithoutModulePaths() const; 59 }; 60 61 struct FullDependenciesResult { 62 FullDependencies FullDeps; 63 std::vector<ModuleDeps> DiscoveredModules; 64 }; 65 66 /// The high-level implementation of the dependency discovery tool that runs on 67 /// an individual worker thread. 68 class DependencyScanningTool { 69 public: 70 /// Construct a dependency scanning tool. 71 DependencyScanningTool(DependencyScanningService &Service, 72 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = 73 llvm::vfs::createPhysicalFileSystem()); 74 75 /// Print out the dependency information into a string using the dependency 76 /// file format that is specified in the options (-MD is the default) and 77 /// return it. If \p ModuleName isn't empty, this function returns the 78 /// dependency information of module \p ModuleName. 79 /// 80 /// \returns A \c StringError with the diagnostic output if clang errors 81 /// occurred, dependency file contents otherwise. 82 llvm::Expected<std::string> 83 getDependencyFile(const std::vector<std::string> &CommandLine, StringRef CWD, 84 llvm::Optional<StringRef> ModuleName = None); 85 86 /// Collect the full module dependency graph for the input, ignoring any 87 /// modules which have already been seen. If \p ModuleName isn't empty, this 88 /// function returns the full dependency information of module \p ModuleName. 89 /// 90 /// \param AlreadySeen This stores modules which have previously been 91 /// reported. Use the same instance for all calls to this 92 /// function for a single \c DependencyScanningTool in a 93 /// single build. Use a different one for different tools, 94 /// and clear it between builds. 95 /// 96 /// \returns a \c StringError with the diagnostic output if clang errors 97 /// occurred, \c FullDependencies otherwise. 98 llvm::Expected<FullDependenciesResult> 99 getFullDependencies(const std::vector<std::string> &CommandLine, 100 StringRef CWD, const llvm::StringSet<> &AlreadySeen, 101 llvm::Optional<StringRef> ModuleName = None); 102 103 private: 104 DependencyScanningWorker Worker; 105 }; 106 107 } // end namespace dependencies 108 } // end namespace tooling 109 } // end namespace clang 110 111 #endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H 112