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_DEPENDENCY_SCANNING_TOOL_H 10 #define LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_TOOL_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 name of the C++20 module this translation unit exports. This may 26 /// include `:` for C++20 module partitons. 27 /// 28 /// If the translation unit is not a module then this will be empty. 29 std::string ExportedModuleName; 30 31 /// The context hash represents the set of compiler options that may make one 32 /// version of a module incompatible with another. This includes things like 33 /// language mode, predefined macros, header search paths, etc... 34 /// 35 /// Modules with the same name but a different \c ContextHash should be 36 /// treated as separate modules for the purpose of a build. 37 std::string ContextHash; 38 39 /// A collection of absolute paths to files that this translation unit 40 /// directly depends on, not including transitive dependencies. 41 std::vector<std::string> FileDeps; 42 43 /// A list of modules this translation unit directly depends on, not including 44 /// transitive dependencies. 45 /// 46 /// This may include modules with a different context hash when it can be 47 /// determined that the differences are benign for this compilation. 48 std::vector<ClangModuleDep> ClangModuleDeps; 49 50 /// A partial addtional set of command line arguments that can be used to 51 /// build this translation unit. 52 /// 53 /// Call \c getFullAdditionalCommandLine() to get a command line suitable for 54 /// appending to the original command line to pass to clang. 55 std::vector<std::string> AdditionalNonPathCommandLine; 56 57 /// Gets the full addtional command line suitable for appending to the 58 /// original command line to pass to clang. 59 /// 60 /// \param LookupPCMPath this function is called to fill in `-fmodule-file=` 61 /// flags and for the `-o` flag. It needs to return a 62 /// path for where the PCM for the given module is to 63 /// be located. 64 /// \param LookupModuleDeps this fucntion is called to collect the full 65 /// transitive set of dependencies for this 66 /// compilation. 67 std::vector<std::string> getAdditionalCommandLine( 68 std::function<StringRef(ClangModuleDep)> LookupPCMPath, 69 std::function<const ModuleDeps &(ClangModuleDep)> LookupModuleDeps) const; 70 }; 71 72 struct FullDependenciesResult { 73 FullDependencies FullDeps; 74 std::vector<ModuleDeps> DiscoveredModules; 75 }; 76 77 /// The high-level implementation of the dependency discovery tool that runs on 78 /// an individual worker thread. 79 class DependencyScanningTool { 80 public: 81 /// Construct a dependency scanning tool. 82 DependencyScanningTool(DependencyScanningService &Service); 83 84 /// Print out the dependency information into a string using the dependency 85 /// file format that is specified in the options (-MD is the default) and 86 /// return it. 87 /// 88 /// \returns A \c StringError with the diagnostic output if clang errors 89 /// occurred, dependency file contents otherwise. 90 llvm::Expected<std::string> 91 getDependencyFile(const tooling::CompilationDatabase &Compilations, 92 StringRef CWD); 93 94 /// Collect the full module depenedency graph for the input, ignoring any 95 /// modules which have already been seen. 96 /// 97 /// \param AlreadySeen this is used to not report modules that have previously 98 /// been reported. Use the same `llvm::StringSet<>` for all 99 /// calls to `getFullDependencies` for a single 100 /// `DependencyScanningTool` for a single build. Use a 101 /// different one for different tools, and clear it between 102 /// builds. 103 /// 104 /// \returns a \c StringError with the diagnostic output if clang errors 105 /// occurred, \c FullDependencies otherwise. 106 llvm::Expected<FullDependenciesResult> 107 getFullDependencies(const tooling::CompilationDatabase &Compilations, 108 StringRef CWD, const llvm::StringSet<> &AlreadySeen); 109 110 private: 111 DependencyScanningWorker Worker; 112 }; 113 114 } // end namespace dependencies 115 } // end namespace tooling 116 } // end namespace clang 117 118 #endif // LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_TOOL_H 119