oontvoo updated this revision to Diff 252117. oontvoo marked an inline comment as done. oontvoo added a comment.
Add a PendingHeaderSearch set Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75951/new/ https://reviews.llvm.org/D75951 Files: clang/include/clang/Lex/HeaderSearch.h clang/include/clang/Lex/Preprocessor.h clang/include/clang/Serialization/ASTReader.h clang/lib/Lex/HeaderSearch.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp
Index: clang/lib/Serialization/ASTWriter.cpp =================================================================== --- clang/lib/Serialization/ASTWriter.cpp +++ clang/lib/Serialization/ASTWriter.cpp @@ -1676,6 +1676,14 @@ } LE.write<uint32_t>(Offset); + // Writes the number of importers. + LE.write<uint32_t>(Data.HFI.Importers.size()); + if (!Data.HFI.Importers.empty()){ + for (const FileEntry* F : Data.HFI.Importers) { + LE.write<unsigned>(F->getUID()); + } + } + auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) { if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) { uint32_t Value = (ModID << 2) | (unsigned)Role; Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -1898,6 +1898,20 @@ HFI.Framework = HS->getUniqueFrameworkName(FrameworkName); } + { + const uint32_t ImportersCount = endian::readNext<uint32_t, little>(d)); + if (ImportersCount > 0) { + // Read the file UIDs and temporarily save it because we don't have + // the FileEntry for these yet. + for (int i = 0; i < ImportersCount; ++i) { + HFI.ImportersUIDs.push_back(endian::readNext<uint32_t, little>(d)); + } + // TODO: This is a little inefficient. But don't know of a way to + // stores only this HFI. + Reader.addPendingHeaderSearch(HS); + } + } + assert((End - d) % 4 == 0 && "Wrong data length in HeaderFileInfo deserialization"); while (d != End) { @@ -9068,7 +9082,7 @@ while (!PendingIdentifierInfos.empty() || !PendingFunctionTypes.empty() || !PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() || !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() || - !PendingUpdateRecords.empty()) { + !PendingUpdateRecords.empty() || !PendingHeaderSearch.empty()) { // If any identifiers with corresponding top-level declarations have // been loaded, load those declarations now. using TopLevelDeclsMap = @@ -9143,6 +9157,17 @@ } PendingMacroIDs.clear(); + for (auto PendingHS : PendingHeaderSearch) { + for (HeaderFileInfo& HFI : PendingHS->FileInfo){ + if (!HFI.FinishedLoadingImporters) { + for (uint32_t FUID : HFI.ImporterUIDs) { + // TODO: find the FileEntry based on UID?? + } + HFI.FinishedLoadingImporters = true; + } + } + } + // Wire up the DeclContexts for Decls that we delayed setting until // recursive loading is completed. while (!PendingDeclContextInfos.empty()) { Index: clang/lib/Lex/HeaderSearch.cpp =================================================================== --- clang/lib/Lex/HeaderSearch.cpp +++ clang/lib/Lex/HeaderSearch.cpp @@ -1253,60 +1253,22 @@ // Get information about this file. HeaderFileInfo &FileInfo = getFileInfo(File); - // FIXME: this is a workaround for the lack of proper modules-aware support - // for #import / #pragma once - auto TryEnterImported = [&]() -> bool { - if (!ModulesEnabled) - return false; - // Ensure FileInfo bits are up to date. - ModMap.resolveHeaderDirectives(File); - // Modules with builtins are special; multiple modules use builtins as - // modular headers, example: - // - // module stddef { header "stddef.h" export * } - // - // After module map parsing, this expands to: - // - // module stddef { - // header "/path_to_builtin_dirs/stddef.h" - // textual "stddef.h" - // } - // - // It's common that libc++ and system modules will both define such - // submodules. Make sure cached results for a builtin header won't - // prevent other builtin modules to potentially enter the builtin header. - // Note that builtins are header guarded and the decision to actually - // enter them is postponed to the controlling macros logic below. - bool TryEnterHdr = false; - if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader) - TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() && - ModuleMap::isBuiltinHeader( - llvm::sys::path::filename(File->getName())); - - // Textual headers can be #imported from different modules. Since ObjC - // headers find in the wild might rely only on #import and do not contain - // controlling macros, be conservative and only try to enter textual headers - // if such macro is present. - if (!FileInfo.isModuleHeader && - FileInfo.getControllingMacro(ExternalLookup)) - TryEnterHdr = true; - return TryEnterHdr; - }; - // If this is a #import directive, check that we have not already imported // this header. if (isImport) { // If this has already been imported, don't import it again. FileInfo.isImport = true; + } - // Has this already been #import'ed or #include'd? - if (FileInfo.NumIncludes && !TryEnterImported()) - return false; - } else { - // Otherwise, if this is a #include of a file that was previously #import'd - // or if this is the second #include of a #pragma once file, ignore it. - if (FileInfo.isImport && !TryEnterImported()) - return false; + if (FileInfo.isPragmaOnce || FileInfo.isImport) { + if (PP.isIncludeVisible(File))return false; + else { + // Mark as 'included'. + PP.setIncludeVisible(File); + + // Also record the importer. + FileInfo.Importers.push_back(PP.getCurrentFileLexer()->getFileEntry()); + } } // Next, check to see if the file is wrapped with #ifndef guards. If so, and Index: clang/include/clang/Serialization/ASTReader.h =================================================================== --- clang/include/clang/Serialization/ASTReader.h +++ clang/include/clang/Serialization/ASTReader.h @@ -736,6 +736,8 @@ /// IDs have not yet been deserialized to the global IDs of those macros. PendingMacroIDsMap PendingMacroIDs; + llvm::SmallPtrSet<HeaderSearch*> PendingHeaderSearch; + using GlobalPreprocessedEntityMapType = ContinuousRangeMap<unsigned, ModuleFile *, 4>; @@ -2198,6 +2200,11 @@ void addPendingMacro(IdentifierInfo *II, ModuleFile *M, uint64_t MacroDirectivesOffset); + /// Add a HeaderSearch to the set of pending objects to be looked at later. + void addPendingHeaderSearch(HeaderSearch* HS) { + PendingHeaderSearch.insert(HS); + } + /// Read the set of macros defined by this external macro source. void ReadDefinedMacros() override; Index: clang/include/clang/Lex/Preprocessor.h =================================================================== --- clang/include/clang/Lex/Preprocessor.h +++ clang/include/clang/Lex/Preprocessor.h @@ -51,6 +51,7 @@ #include <cstdint> #include <map> #include <memory> +#include <set> #include <string> #include <utility> #include <vector> @@ -743,6 +744,9 @@ /// The set of modules that are visible within the submodule. VisibleModuleSet VisibleModules; + /// The included header for the submodule. + std::set<const FileEntry *> IncludedFiles; + // FIXME: CounterValue? // FIXME: PragmaPushMacroInfo? }; @@ -1038,6 +1042,15 @@ OnToken = std::move(F); } + void setIncludeVisible(const FileEntry *File) { + CurSubmoduleState->IncludedFiles.insert(File); + } + + bool isIncludeVisible(const FileEntry *File) { + return CurSubmoduleState->IncludedFiles.find(File) != + CurSubmoduleState->IncludedFiles.end(); + } + bool isMacroDefined(StringRef Id) { return isMacroDefined(&Identifiers.get(Id)); } Index: clang/include/clang/Lex/HeaderSearch.h =================================================================== --- clang/include/clang/Lex/HeaderSearch.h +++ clang/include/clang/Lex/HeaderSearch.h @@ -110,10 +110,20 @@ /// of the framework. StringRef Framework; + /// List of files that import this header. + SmallVector<const FileEntry *, 16> Importers; + + /// List of the importers' UIDs. + /// Note that this should only be available while reading the + /// AST. + SmallVector<uint32_t, 16> ImporterUIDs; + + bool FinishedLoadingImporters; + HeaderFileInfo() : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), External(false), isModuleHeader(false), isCompilingModuleHeader(false), - Resolved(false), IndexHeaderMapHeader(false), IsValid(false) {} + Resolved(false), IndexHeaderMapHeader(false), IsValid(false), FinishedLoadingImporters(false) {} /// Retrieve the controlling macro for this header file, if /// any.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits