jansvoboda11 created this revision.
Herald added a subscriber: ributzka.
Herald added a project: All.
jansvoboda11 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Let's not create PCM files in the dependency scanner.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D137259
Files:
clang/include/clang/Frontend/CompilerInstance.h
clang/lib/Frontend/CompilerInstance.cpp
clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
Index: clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
===================================================================
--- clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -424,6 +424,7 @@
MD.ClangModuleMapFile = std::string(Path);
}
+ if (MDC.ScanInstance.SortedFiles.find(M->getFullModuleName()) == MDC.ScanInstance.SortedFiles.end()) {
serialization::ModuleFile *MF =
MDC.ScanInstance.getASTReader()->getModuleManager().lookup(
M->getASTFile());
@@ -452,12 +453,32 @@
return;
MD.ModuleMapFileDeps.emplace_back(FE->getName());
});
+ } else {
+ for (const auto &E : MDC.ScanInstance.SortedFiles[M->getFullModuleName()]) {
+ if (E.FE->getName().endswith("__inferred_module.map")) {
+ MDC.addFileDep(MD, ModuleMap->getName());
+ 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());
+ }
+ }
+ }
CompilerInvocation CI = MDC.makeInvocationForModuleBuildWithoutOutputs(
MD, [&](CompilerInvocation &BuildInvocation) {
- if (MDC.OptimizeArgs)
- optimizeHeaderSearchOpts(BuildInvocation.getHeaderSearchOpts(),
- *MDC.ScanInstance.getASTReader(), *MF);
+// if (MDC.OptimizeArgs)
+// optimizeHeaderSearchOpts(BuildInvocation.getHeaderSearchOpts(),
+// *MDC.ScanInstance.getASTReader(), *MF);
});
MDC.associateWithContextHash(CI, MD);
Index: clang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- clang/lib/Frontend/CompilerInstance.cpp
+++ clang/lib/Frontend/CompilerInstance.cpp
@@ -1129,6 +1129,226 @@
return LangOpts.CPlusPlus ? Language::CXX : Language::C;
}
+class Translator {
+ CompilerInstance &A;
+ const CompilerInstance &B;
+
+ llvm::StringSet<> TranslatedModules;
+
+public:
+ Translator(CompilerInstance &A, const CompilerInstance &B) : A(A), B(B) {}
+
+ template <class T> Optional<T> translate(const Optional<T> &BO) {
+ if (!BO)
+ return None;
+ return translate(*BO);
+ }
+
+ template <class T> const T *translate(const T *BP) {
+ if (!BP)
+ return nullptr;
+ return &translate(*BP);
+ }
+
+ template <class T> T *translate(T *BP) {
+ if (!BP)
+ return nullptr;
+ return &translate(*BP);
+ }
+
+ template <class T, class U> llvm::PointerUnion<T, U> translate(llvm::PointerUnion<T, U> BPU) {
+ if (!BPU)
+ return nullptr;
+ if (BPU.template is<T>())
+ return translate(BPU.template get<T>());
+ return translate(BPU.template get<U>());
+ }
+
+ template <class T, unsigned N>
+ SmallVector<T, N> translate(const SmallVector<T, N> &BV) {
+ SmallVector<T, N> AV;
+ AV.reserve(BV.size());
+ for (const T &Entry : BV)
+ AV.push_back(translate(Entry));
+ return AV;
+ }
+
+ template <class T, unsigned N>
+ llvm::SmallSetVector<T, N> translate(const llvm::SmallSetVector<T, N>& BSSV) {
+ llvm::SmallSetVector<T, N> ASSV;
+ for (const auto &Entry : BSSV)
+ ASSV.insert(translate(Entry));
+ return ASSV;
+ }
+
+ const FileEntry &translate(const FileEntry &BFE) {
+ return **A.getFileManager().getFile(BFE.getName());
+ }
+
+ FileEntryRef translate(FileEntryRef BFE) {
+ return *A.getFileManager().getOptionalFileRef(BFE.getName());
+ }
+
+ const DirectoryEntry &translate(const DirectoryEntry &BDE) {
+ return **A.getFileManager().getDirectory(BDE.getName());
+ }
+
+ SourceLocation translate(SourceLocation BLoc) {
+ auto &ASM = A.getSourceManager();
+ auto &BSM = B.getSourceManager();
+
+ auto BFileID = BSM.getFileID(BLoc);
+ auto BFileCharacteristic = BSM.getFileCharacteristic(BLoc);
+ auto *AFileEntry = translate(BSM.getFileEntryForID(BFileID));
+ auto AFileID = ASM.getOrCreateFileID(AFileEntry, BFileCharacteristic);
+
+ auto AOffset = BSM.getFileOffset(BLoc);
+
+ return ASM.getComposedLoc(AFileID, AOffset);
+ }
+
+ Module::Header translate(const Module::Header &BHeader) {
+ return Module::Header{BHeader.NameAsWritten,
+ BHeader.PathRelativeToRootModuleDirectory,
+ translate(BHeader.Entry)};
+ }
+
+ std::vector<Module *> translate(Module::submodule_iterator Begin,
+ Module::submodule_iterator End) {
+ std::vector<Module *> ASubModules;
+ for (auto It = Begin; It != End; ++It)
+ ASubModules.push_back(translate(*It));
+ return ASubModules;
+ }
+
+ Module::UnresolvedHeaderDirective
+ translate(const Module::UnresolvedHeaderDirective &BD) {
+ return {BD.Kind, //
+ translate(BD.FileNameLoc),
+ BD.FileName,
+ BD.IsUmbrella,
+ BD.HasBuiltinHeader,
+ BD.Size,
+ BD.ModTime};
+ }
+
+ Module::ExportDecl translate(const Module::ExportDecl &BED) {
+ return {translate(BED.getPointer()), BED.getInt()};
+ }
+
+ ModuleId translate(const ModuleId &BId) {
+ ModuleId Res;
+ for (const auto &Element : BId)
+ Res.push_back({Element.first, translate(Element.second)});
+ return Res;
+ }
+
+ Module::UnresolvedExportDecl
+ translate(const Module::UnresolvedExportDecl &BUED) {
+ return {translate(BUED.ExportLoc), translate(BUED.Id), BUED.Wildcard};
+ }
+
+ Module::LinkLibrary translate(const Module::LinkLibrary &X) {
+ return X;
+ }
+
+ Module::UnresolvedConflict translate(const Module::UnresolvedConflict &X) {
+ return {translate(X.Id), X.Message};
+ }
+
+ Module::Conflict translate(const Module::Conflict &X) {
+ return {translate(X.Other), X.Message};
+ }
+
+ Module &translate(const Module &BMod) {
+ return translate(const_cast<Module &>(BMod));
+ }
+
+ Module &translate(Module &BMod) {
+ auto &AModMap = A.getPreprocessor().getHeaderSearchInfo().getModuleMap();
+ auto &BHS = B.getPreprocessor().getHeaderSearchInfo();
+
+ auto [AMod, New] = AModMap.findOrCreateModule(
+ BMod.Name, translate(BMod.Parent),
+ BMod.IsFramework, BMod.IsExplicit);
+
+ if (!TranslatedModules.insert(BMod.Name).second)
+ return *AMod;
+
+ // Even if instance A already knows about module, it might not know
+ // information that's figured during compile of the module (e.g. imports).
+ if (!New) {
+ // llvm::errs() << "translating existing module " << BMod.Name << "\n";
+ }
+
+ AMod->Kind = BMod.Kind;
+ AMod->Directory = translate(BMod.Directory);
+ AMod->PresumedModuleMapFile = BMod.PresumedModuleMapFile;
+ AMod->DefinitionLoc = translate(AMod->DefinitionLoc);
+ AMod->Umbrella = translate(BMod.Umbrella);
+ AMod->UmbrellaAsWritten = BMod.UmbrellaAsWritten;
+ AMod->UmbrellaRelativeToRootModuleDirectory = BMod.UmbrellaRelativeToRootModuleDirectory;
+ AMod->ExportAsModule = BMod.ExportAsModule;
+
+ for (Module *BSubMod : BMod.submodules())
+ translate(BSubMod);
+
+ for (const FileEntry *BTopHeader : BMod.getTopHeaders(B.getFileManager()))
+ AMod->addTopHeader(translate(BTopHeader));
+
+ // TODO: Propagate VisibilityID to other data structures.
+
+ for (auto Kind : {Module::HK_Normal, Module::HK_Textual, Module::HK_Private,
+ Module::HK_PrivateTextual, Module::HK_Excluded}) {
+ for (const auto &BH : BMod.Headers[Kind]) {
+ const auto &AH = translate(BH);
+ AModMap.addHeader(AMod, AH, ModuleMap::headerKindToRole(Kind),
+ BHS.getFileInfo(BH.Entry).isModuleHeader);
+ }
+ }
+
+ AMod->UnresolvedHeaders = translate(BMod.UnresolvedHeaders);
+ AMod->MissingHeaders = translate(BMod.MissingHeaders);
+ AMod->Requirements = BMod.Requirements;
+ AMod->ShadowingModule = translate(BMod.ShadowingModule);
+ AMod->IsUnimportable = BMod.IsUnimportable;
+ AMod->HasIncompatibleModuleFile = BMod.HasIncompatibleModuleFile;
+ AMod->IsAvailable = BMod.IsAvailable;
+ AMod->IsFromModuleFile = BMod.IsFromModuleFile;
+ AMod->IsFramework = BMod.IsFramework;
+ AMod->IsExplicit = BMod.IsExplicit;
+ AMod->IsSystem = BMod.IsSystem;
+ AMod->IsExternC = BMod.IsExternC;
+ AMod->IsInferred = BMod.IsInferred;
+ AMod->InferSubmodules = BMod.InferSubmodules;
+ AMod->InferExplicitSubmodules = BMod.InferExplicitSubmodules;
+ AMod->InferExportWildcard = BMod.InferExportWildcard;
+ AMod->ConfigMacrosExhaustive = BMod.ConfigMacrosExhaustive;
+ AMod->NoUndeclaredIncludes = BMod.NoUndeclaredIncludes;
+ AMod->ModuleMapIsPrivate = BMod.ModuleMapIsPrivate;
+ AMod->NameVisibility = BMod.NameVisibility;
+ AMod->InferredSubmoduleLoc = translate(BMod.InferredSubmoduleLoc);
+ AMod->Imports = translate(BMod.Imports);
+ AMod->Exports = translate(BMod.Exports);
+ AMod->UnresolvedExports = translate(BMod.UnresolvedExports);
+ AMod->DirectUses = translate(BMod.DirectUses);
+ AMod->UnresolvedDirectUses = translate(BMod.UnresolvedDirectUses);
+ AMod->UndeclaredUses = translate(BMod.UndeclaredUses);
+ AMod->LinkLibraries = translate(BMod.LinkLibraries);
+ AMod->UseExportAsModuleLinkName = BMod.UseExportAsModuleLinkName;
+ AMod->ConfigMacros = BMod.ConfigMacros;
+ AMod->UnresolvedConflicts = BMod.UnresolvedConflicts;
+ AMod->Conflicts = BMod.Conflicts;
+
+ return *AMod;
+ }
+
+ Module *translateModule(StringRef BName) {
+ return translate(
+ B.getPreprocessor().getHeaderSearchInfo().lookupModule(BName));
+ }
+};
+
/// Compile a module file for the given module, using the options
/// provided by the importing compiler instance. Returns true if the module
/// was built without errors.
@@ -1254,6 +1474,48 @@
[&]() {
GenerateModuleFromModuleMapAction Action;
Instance.ExecuteAction(Action);
+
+ Translator T(ImportingInstance, Instance);
+ T.translateModule(ModuleName);
+ // llvm::errs() << "translated " << ModuleName << "\n";
+
+ std::set<const FileEntry *> AffectingModuleMaps;
+ std::set<const FileEntry *> SkippedModuleMaps;
+
+ auto &SortedFiles = ImportingInstance.SortedFiles[ModuleName];
+ for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size(); I != N; ++I) {
+ // Get this source location entry.
+ const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(I);
+
+ // We only care about file entries that were not overridden.
+ if (!SLoc->isFile())
+ continue;
+ const SrcMgr::FileInfo &File = SLoc->getFile();
+ const SrcMgr::ContentCache *Cache = &File.getContentCache();
+ if (!Cache->OrigEntry)
+ continue;
+
+ if (isModuleMap(File.getFileCharacteristic()) &&
+ !isSystem(File.getFileCharacteristic()) &&
+ !AffectingModuleMaps.empty() &&
+ AffectingModuleMaps.find(Cache->OrigEntry) ==
+ AffectingModuleMaps.end()) {
+ SkippedModuleMaps.insert(Cache->OrigEntry);
+ // Do not emit modulemaps that do not affect current module.
+ continue;
+ }
+
+ CompilerInstance::EntryStruct Entry{
+ T.translate(Cache->OrigEntry),
+ isSystem(File.getFileCharacteristic()),
+ isModuleMap(File.getFileCharacteristic()) &&
+ File.getIncludeLoc().isInvalid()};
+
+ if (Entry.IsSystemFile)
+ SortedFiles.push_back(Entry);
+ else
+ SortedFiles.push_front(Entry);
+ }
},
DesiredStackSize);
@@ -1370,11 +1632,16 @@
if (OutOfDate)
ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate;
+ llvm::errs() << "readASTAfterCompileModule " << Module << " " << Module->getFullModuleName() << " " << Module->Imports.size() << "\n";
+
// Try to read the module file, now that we've compiled it.
ASTReader::ASTReadResult ReadResult =
ImportingInstance.getASTReader()->ReadAST(
ModuleFileName, serialization::MK_ImplicitModule, ImportLoc,
ModuleLoadCapabilities);
+
+ llvm::errs() << "readASTAfterCompileModule " << Module << " " << Module->getFullModuleName() << " " << Module->Imports.size() << "\n";
+
if (ReadResult == ASTReader::Success)
return true;
@@ -1799,6 +2066,8 @@
Module *M =
HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective);
+ assert(M && "no module in findOrCompileModuleAndReadAST");
+
// Select the source and filename for loading the named module.
std::string ModuleFilename;
ModuleSource Source =
@@ -1938,7 +2207,7 @@
// Try to compile and then read the AST.
if (!compileModuleAndReadAST(*this, ImportLoc, ModuleNameLoc, M,
- ModuleFilename)) {
+ ModuleFilename)) { //
assert(getDiagnostics().hasErrorOccurred() &&
"undiagnosed error in compileModuleAndReadAST");
if (getPreprocessorOpts().FailedModules)
Index: clang/include/clang/Frontend/CompilerInstance.h
===================================================================
--- clang/include/clang/Frontend/CompilerInstance.h
+++ clang/include/clang/Frontend/CompilerInstance.h
@@ -179,6 +179,13 @@
CompilerInstance(const CompilerInstance &) = delete;
void operator=(const CompilerInstance &) = delete;
public:
+ struct EntryStruct {
+ Optional<FileEntryRef> FE;
+ bool IsSystemFile;
+ bool IsTopLevelModuleMap;
+ };
+ llvm::StringMap<std::deque<EntryStruct>> SortedFiles;
+
explicit CompilerInstance(
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>(),
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits