oontvoo updated this revision to Diff 252110. oontvoo added a comment. Updated the reader to read the UIDs first, then we'll build up the Importers list at the end.
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/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,21 @@ HFI.Framework = HS->getUniqueFrameworkName(FrameworkName); } + { + const uint32_t ImportersCount = endian::readNext<uint32_t, little>(d)); + if (ImportersCount > 0) { + + // TODO: I don't think this is right because these importers + // are NOT guaranteed to be read/loaded before this header??? + // + // 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)); + } + } + } + assert((End - d) % 4 == 0 && "Wrong data length in HeaderFileInfo deserialization"); while (d != End) { 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/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