diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h @@ -22,19 +22,10 @@ /// The full dependencies and module graph for a specific input. struct FullDependencies { - /// The name of the C++20 module this translation unit exports. This may - /// include `:` for C++20 module partitons. + /// The identifier of the C++20 module this translation unit exports. /// - /// If the translation unit is not a module then this will be empty. - std::string ExportedModuleName; - - /// The context hash represents the set of compiler options that may make one - /// version of a module incompatible with another. This includes things like - /// language mode, predefined macros, header search paths, etc... - /// - /// Modules with the same name but a different \c ContextHash should be - /// treated as separate modules for the purpose of a build. - std::string ContextHash; + /// 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. @@ -45,7 +36,7 @@ /// /// 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; + std::vector ClangModuleDeps; /// A partial addtional set of command line arguments that can be used to /// build this translation unit. @@ -65,8 +56,8 @@ /// transitive set of dependencies for this /// compilation. std::vector getAdditionalCommandLine( - std::function LookupPCMPath, - std::function LookupModuleDeps) const; + std::function LookupPCMPath, + std::function LookupModuleDeps) const; }; struct FullDependenciesResult { diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h --- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h @@ -28,16 +28,9 @@ class DependencyConsumer; -/// This is used to refer to a specific module. -/// -/// See \c ModuleDeps for details about what these members mean. -struct ClangModuleDep { - std::string ModuleName; - std::string ContextHash; -}; - -struct ModuleDeps { - /// The name of the module. This may include `:` for C++20 module partitons, +/// This is used to identify a specific module. +struct ModuleID { + /// The name of the module. This may include `:` for C++20 module partitions, /// or a header-name for C++20 header units. std::string ModuleName; @@ -48,6 +41,11 @@ /// Modules with the same name but a different \c ContextHash should be /// treated as separate modules for the purpose of a build. std::string ContextHash; +}; + +struct ModuleDeps { + /// The identifier of the module. + ModuleID ID; /// The path to the modulemap file which defines this module. /// @@ -62,12 +60,12 @@ /// on, not including transitive dependencies. llvm::StringSet<> FileDeps; - /// A list of modules this module directly depends on, not including - /// transitive dependencies. + /// A list of module identifiers this module 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; + std::vector ClangModuleDeps; /// A partial command line that can be used to build this module. /// @@ -89,8 +87,8 @@ /// transitive set of dependencies for this /// compilation. std::vector getFullCommandLine( - std::function LookupPCMPath, - std::function LookupModuleDeps) const; + std::function LookupPCMPath, + std::function LookupModuleDeps) const; }; namespace detail { @@ -98,9 +96,9 @@ /// modules in \c Modules transitively, along with other needed arguments to /// use explicitly built modules. void appendCommonModuleArguments( - llvm::ArrayRef Modules, - std::function LookupPCMPath, - std::function LookupModuleDeps, + llvm::ArrayRef Modules, + std::function LookupPCMPath, + std::function LookupModuleDeps, std::vector &Result); } // namespace detail diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp @@ -14,8 +14,8 @@ namespace dependencies{ std::vector FullDependencies::getAdditionalCommandLine( - std::function LookupPCMPath, - std::function LookupModuleDeps) const { + std::function LookupPCMPath, + std::function LookupModuleDeps) const { std::vector Ret = AdditionalNonPathCommandLine; dependencies::detail::appendCommonModuleArguments( @@ -109,7 +109,7 @@ } void handleModuleDependency(ModuleDeps MD) override { - ClangModuleDeps[MD.ContextHash + MD.ModuleName] = std::move(MD); + ClangModuleDeps[MD.ID.ContextHash + MD.ID.ModuleName] = std::move(MD); } void handleContextHash(std::string Hash) override { @@ -119,14 +119,14 @@ FullDependenciesResult getFullDependencies() const { FullDependencies FD; - FD.ContextHash = std::move(ContextHash); + FD.ID.ContextHash = std::move(ContextHash); FD.FileDeps.assign(Dependencies.begin(), Dependencies.end()); for (auto &&M : ClangModuleDeps) { auto &MD = M.second; if (MD.ImportedByMainFile) - FD.ClangModuleDeps.push_back({MD.ModuleName, ContextHash}); + FD.ClangModuleDeps.push_back({MD.ID.ModuleName, ContextHash}); } FullDependenciesResult FDR; diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -18,8 +18,8 @@ using namespace dependencies; std::vector ModuleDeps::getFullCommandLine( - std::function LookupPCMPath, - std::function LookupModuleDeps) const { + std::function LookupPCMPath, + std::function LookupModuleDeps) const { std::vector Ret = NonPathCommandLine; // TODO: Build full command line. That also means capturing the original @@ -32,21 +32,21 @@ } void dependencies::detail::appendCommonModuleArguments( - llvm::ArrayRef Modules, - std::function LookupPCMPath, - std::function LookupModuleDeps, + llvm::ArrayRef Modules, + std::function LookupPCMPath, + std::function LookupModuleDeps, std::vector &Result) { llvm::StringSet<> AlreadyAdded; - std::function)> AddArgs = - [&](llvm::ArrayRef Modules) { - for (const ClangModuleDep &CMD : Modules) { - if (!AlreadyAdded.insert(CMD.ModuleName + CMD.ContextHash).second) + std::function)> AddArgs = + [&](llvm::ArrayRef Modules) { + for (const ModuleID &MID : Modules) { + if (!AlreadyAdded.insert(MID.ModuleName + MID.ContextHash).second) continue; - const ModuleDeps &M = LookupModuleDeps(CMD); + const ModuleDeps &M = LookupModuleDeps(MID); // Depth first traversal. AddArgs(M.ClangModuleDeps); - Result.push_back(("-fmodule-file=" + LookupPCMPath(CMD)).str()); + Result.push_back(("-fmodule-file=" + LookupPCMPath(MID)).str()); if (!M.ClangModuleMapFile.empty()) { Result.push_back("-fmodule-map-file=" + M.ClangModuleMapFile); } @@ -133,7 +133,7 @@ auto ModI = MDC.Deps.insert( std::make_pair(MDC.ContextHash + M->getFullModuleName(), ModuleDeps{})); - if (!ModI.first->second.ModuleName.empty()) + if (!ModI.first->second.ID.ModuleName.empty()) return; ModuleDeps &MD = ModI.first->second; @@ -144,9 +144,9 @@ .getContainingModuleMapFile(M); MD.ClangModuleMapFile = std::string(ModuleMap ? ModuleMap->getName() : ""); - MD.ModuleName = M->getFullModuleName(); + MD.ID.ModuleName = M->getFullModuleName(); MD.ImplicitModulePCMPath = std::string(M->getASTFile()->getName()); - MD.ContextHash = MDC.ContextHash; + MD.ID.ContextHash = MDC.ContextHash; serialization::ModuleFile *MF = MDC.Instance.getASTReader()->getModuleManager().lookup(M->getASTFile()); MDC.Instance.getASTReader()->visitInputFiles( 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 @@ -222,16 +222,16 @@ return llvm::json::Array(Strings); } -static llvm::json::Array toJSONSorted(std::vector V) { - llvm::sort(V, [](const ClangModuleDep &A, const ClangModuleDep &B) { +static llvm::json::Array toJSONSorted(std::vector V) { + llvm::sort(V, [](const ModuleID &A, const ModuleID &B) { return std::tie(A.ModuleName, A.ContextHash) < std::tie(B.ModuleName, B.ContextHash); }); llvm::json::Array Ret; - for (const ClangModuleDep &CMD : V) + for (const ModuleID &MID : V) Ret.push_back(llvm::json::Object( - {{"module-name", CMD.ModuleName}, {"context-hash", CMD.ContextHash}})); + {{"module-name", MID.ModuleName}, {"context-hash", MID.ContextHash}})); return Ret; } @@ -244,26 +244,25 @@ InputDeps ID; ID.FileName = std::string(Input); - ID.ContextHash = std::move(FD.ContextHash); + ID.ContextHash = std::move(FD.ID.ContextHash); ID.FileDeps = std::move(FD.FileDeps); ID.ModuleDeps = std::move(FD.ClangModuleDeps); std::unique_lock ul(Lock); for (const ModuleDeps &MD : FDR.DiscoveredModules) { - auto I = Modules.find({MD.ContextHash, MD.ModuleName, 0}); + auto I = Modules.find({MD.ID, 0}); if (I != Modules.end()) { I->first.InputIndex = std::min(I->first.InputIndex, InputIndex); continue; } - Modules.insert( - I, {{MD.ContextHash, MD.ModuleName, InputIndex}, std::move(MD)}); + Modules.insert(I, {{MD.ID, InputIndex}, std::move(MD)}); } if (FullCommandLine) ID.AdditonalCommandLine = FD.getAdditionalCommandLine( - [&](ClangModuleDep CMD) { return lookupPCMPath(CMD); }, - [&](ClangModuleDep CMD) -> const ModuleDeps & { - return lookupModuleDeps(CMD); + [&](ModuleID MID) { return lookupPCMPath(MID); }, + [&](ModuleID MID) -> const ModuleDeps & { + return lookupModuleDeps(MID); }); Inputs.push_back(std::move(ID)); @@ -271,13 +270,13 @@ void printFullOutput(raw_ostream &OS) { // Sort the modules by name to get a deterministic order. - std::vector ModuleNames; + std::vector ModuleIDs; for (auto &&M : Modules) - ModuleNames.push_back(M.first); - llvm::sort(ModuleNames, - [](const ContextModulePair &A, const ContextModulePair &B) { - return std::tie(A.ModuleName, A.InputIndex) < - std::tie(B.ModuleName, B.InputIndex); + ModuleIDs.push_back(M.first); + llvm::sort(ModuleIDs, + [](const IndexedModuleID &A, const IndexedModuleID &B) { + return std::tie(A.ID.ModuleName, A.InputIndex) < + std::tie(B.ID.ModuleName, B.InputIndex); }); llvm::sort(Inputs, [](const InputDeps &A, const InputDeps &B) { @@ -287,20 +286,20 @@ using namespace llvm::json; Array OutModules; - for (auto &&ModName : ModuleNames) { - auto &MD = Modules[ModName]; + for (auto &&ModID : ModuleIDs) { + auto &MD = Modules[ModID]; Object O{ - {"name", MD.ModuleName}, - {"context-hash", MD.ContextHash}, + {"name", MD.ID.ModuleName}, + {"context-hash", MD.ID.ContextHash}, {"file-deps", toJSONSorted(MD.FileDeps)}, {"clang-module-deps", toJSONSorted(MD.ClangModuleDeps)}, {"clang-modulemap-file", MD.ClangModuleMapFile}, {"command-line", FullCommandLine ? MD.getFullCommandLine( - [&](ClangModuleDep CMD) { return lookupPCMPath(CMD); }, - [&](ClangModuleDep CMD) -> const ModuleDeps & { - return lookupModuleDeps(CMD); + [&](ModuleID MID) { return lookupPCMPath(MID); }, + [&](ModuleID MID) -> const ModuleDeps & { + return lookupModuleDeps(MID); }) : MD.NonPathCommandLine}, }; @@ -328,33 +327,31 @@ } private: - StringRef lookupPCMPath(ClangModuleDep CMD) { - return Modules[ContextModulePair{CMD.ContextHash, CMD.ModuleName, 0}] - .ImplicitModulePCMPath; + StringRef lookupPCMPath(ModuleID MID) { + return Modules[IndexedModuleID{MID, 0}].ImplicitModulePCMPath; } - const ModuleDeps &lookupModuleDeps(ClangModuleDep CMD) { - auto I = - Modules.find(ContextModulePair{CMD.ContextHash, CMD.ModuleName, 0}); + const ModuleDeps &lookupModuleDeps(ModuleID MID) { + auto I = Modules.find(IndexedModuleID{MID, 0}); assert(I != Modules.end()); return I->second; }; - struct ContextModulePair { - std::string ContextHash; - std::string ModuleName; + struct IndexedModuleID { + ModuleID ID; mutable size_t InputIndex; - bool operator==(const ContextModulePair &Other) const { - return ContextHash == Other.ContextHash && ModuleName == Other.ModuleName; + bool operator==(const IndexedModuleID &Other) const { + return ID.ModuleName == Other.ID.ModuleName && + ID.ContextHash == Other.ID.ContextHash; } }; - struct ContextModulePairHasher { - std::size_t operator()(const ContextModulePair &CMP) const { + struct IndexedModuleIDHasher { + std::size_t operator()(const IndexedModuleID &IMID) const { using llvm::hash_combine; - return hash_combine(CMP.ContextHash, CMP.ModuleName); + return hash_combine(IMID.ID.ModuleName, IMID.ID.ContextHash); } }; @@ -362,12 +359,12 @@ std::string FileName; std::string ContextHash; std::vector FileDeps; - std::vector ModuleDeps; + std::vector ModuleDeps; std::vector AdditonalCommandLine; }; std::mutex Lock; - std::unordered_map + std::unordered_map Modules; std::vector Inputs; };