Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
Show First 20 Lines • Show All 369 Lines • ▼ Show 20 Lines | void ModuleDepCollectorPP::EndOfMainFile() { | ||||
if (!MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude.empty()) | if (!MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude.empty()) | ||||
MDC.addFileDep(MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude); | MDC.addFileDep(MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude); | ||||
for (const Module *M : | for (const Module *M : | ||||
MDC.ScanInstance.getPreprocessor().getAffectingClangModules()) | MDC.ScanInstance.getPreprocessor().getAffectingClangModules()) | ||||
if (!MDC.isPrebuiltModule(M)) | if (!MDC.isPrebuiltModule(M)) | ||||
DirectModularDeps.insert(M); | DirectModularDeps.insert(M); | ||||
for (const Module *M : DirectModularDeps) { | for (const Module *M : DirectModularDeps) | ||||
// A top-level module might not be actually imported as a module when | |||||
// -fmodule-name is used to compile a translation unit that imports this | |||||
// module. In that case it can be skipped. The appropriate header | |||||
// dependencies will still be reported as expected. | |||||
if (!M->getASTFile()) | |||||
continue; | |||||
handleTopLevelModule(M); | handleTopLevelModule(M); | ||||
} | |||||
MDC.Consumer.handleDependencyOutputOpts(*MDC.Opts); | MDC.Consumer.handleDependencyOutputOpts(*MDC.Opts); | ||||
for (auto &&I : MDC.ModularDeps) | for (auto &&I : MDC.ModularDeps) | ||||
MDC.Consumer.handleModuleDependency(*I.second); | MDC.Consumer.handleModuleDependency(*I.second); | ||||
for (auto &&I : MDC.FileDeps) | for (auto &&I : MDC.FileDeps) | ||||
MDC.Consumer.handleFileDependency(I); | MDC.Consumer.handleFileDependency(I); | ||||
Show All 10 Lines | ModuleID ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { | ||||
if (!ModI.second) | if (!ModI.second) | ||||
return ModI.first->second->ID; | return ModI.first->second->ID; | ||||
ModI.first->second = std::make_unique<ModuleDeps>(); | ModI.first->second = std::make_unique<ModuleDeps>(); | ||||
ModuleDeps &MD = *ModI.first->second; | ModuleDeps &MD = *ModI.first->second; | ||||
MD.ID.ModuleName = M->getFullModuleName(); | MD.ID.ModuleName = M->getFullModuleName(); | ||||
MD.ImportedByMainFile = DirectModularDeps.contains(M); | MD.ImportedByMainFile = DirectModularDeps.contains(M); | ||||
MD.ImplicitModulePCMPath = std::string(M->getASTFile()->getName()); | |||||
MD.IsSystem = M->IsSystem; | MD.IsSystem = M->IsSystem; | ||||
ModuleMap &ModMapInfo = | ModuleMap &ModMapInfo = | ||||
MDC.ScanInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); | MDC.ScanInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); | ||||
Optional<FileEntryRef> ModuleMap = ModMapInfo.getModuleMapFileForUniquing(M); | Optional<FileEntryRef> ModuleMap = ModMapInfo.getModuleMapFileForUniquing(M); | ||||
if (ModuleMap) { | if (ModuleMap) { | ||||
SmallString<128> Path = ModuleMap->getNameAsRequested(); | SmallString<128> Path = ModuleMap->getNameAsRequested(); | ||||
ModMapInfo.canonicalizeModuleMapPath(Path); | ModMapInfo.canonicalizeModuleMapPath(Path); | ||||
MD.ClangModuleMapFile = std::string(Path); | MD.ClangModuleMapFile = std::string(Path); | ||||
} | } | ||||
serialization::ModuleFile *MF = | for (const auto &E : MDC.ScanInstance.SortedFiles[M->getFullModuleName()]) { | ||||
MDC.ScanInstance.getASTReader()->getModuleManager().lookup( | if (E.FE->getName().endswith("__inferred_module.map")) { | ||||
M->getASTFile()); | |||||
MDC.ScanInstance.getASTReader()->visitInputFiles( | |||||
*MF, true, true, [&](const serialization::InputFile &IF, bool isSystem) { | |||||
// __inferred_module.map is the result of the way in which an implicit | |||||
// module build handles inferred modules. It adds an overlay VFS with | |||||
// this file in the proper directory and relies on the rest of Clang to | |||||
// handle it like normal. With explicitly built modules we don't need | |||||
// to play VFS tricks, so replace it with the correct module map. | |||||
if (IF.getFile()->getName().endswith("__inferred_module.map")) { | |||||
MDC.addFileDep(MD, ModuleMap->getName()); | MDC.addFileDep(MD, ModuleMap->getName()); | ||||
return; | continue; | ||||
} | |||||
MDC.addFileDep(MD, E.FE->getName()); | |||||
} | |||||
if (M->NoUndeclaredIncludes) { | |||||
for (const auto &E : MDC.ScanInstance.SortedFiles[M->getFullModuleName()]) { | |||||
if (E.FE->getName().endswith("__inferred_module.map")) | |||||
continue; | |||||
// The top-level modulemap of this module will be the input file. We | |||||
// don't need to specify it as a module map. | |||||
if (E.FE == ModuleMap) | |||||
continue; | |||||
MD.ModuleMapFileDeps.push_back(E.FE->getName().str()); | |||||
} | |||||
} | } | ||||
MDC.addFileDep(MD, IF.getFile()->getName()); | |||||
}); | |||||
llvm::DenseSet<const Module *> SeenDeps; | |||||
addAllSubmodulePrebuiltDeps(M, MD, SeenDeps); | |||||
addAllSubmoduleDeps(M, MD, SeenDeps); | |||||
addAllAffectingClangModules(M, MD, SeenDeps); | |||||
MDC.ScanInstance.getASTReader()->visitTopLevelModuleMaps( | |||||
*MF, [&](const FileEntry *FE) { | |||||
if (FE->getName().endswith("__inferred_module.map")) | |||||
return; | |||||
MD.ModuleMapFileDeps.emplace_back(FE->getName()); | |||||
}); | |||||
CompilerInvocation CI = MDC.makeInvocationForModuleBuildWithoutOutputs( | CompilerInvocation CI = MDC.makeInvocationForModuleBuildWithoutOutputs( | ||||
MD, [&](CompilerInvocation &BuildInvocation) { | MD, [&](CompilerInvocation &BuildInvocation) { | ||||
if (MDC.OptimizeArgs) | // if (MDC.OptimizeArgs) | ||||
optimizeHeaderSearchOpts(BuildInvocation.getHeaderSearchOpts(), | // optimizeHeaderSearchOpts(BuildInvocation.getHeaderSearchOpts(), | ||||
*MDC.ScanInstance.getASTReader(), *MF); | // *MDC.ScanInstance.getASTReader(), *MF); | ||||
}); | }); | ||||
MDC.associateWithContextHash(CI, MD); | MDC.associateWithContextHash(CI, MD); | ||||
// Finish the compiler invocation. Requires dependencies and the context hash. | // Finish the compiler invocation. Requires dependencies and the context hash. | ||||
MDC.addOutputPaths(CI, MD); | MDC.addOutputPaths(CI, MD); | ||||
MD.BuildArguments = CI.getCC1CommandLine(); | MD.BuildArguments = CI.getCC1CommandLine(); | ||||
▲ Show 20 Lines • Show All 131 Lines • Show Last 20 Lines |