oontvoo updated this revision to Diff 252205. oontvoo added a comment. Fix build errors
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/ASTBitCodes.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 @@ -1599,6 +1599,8 @@ const HeaderFileInfo &HFI; ArrayRef<ModuleMap::KnownHeader> KnownHeaders; UnresolvedModule Unresolved; + uint32_t UID; + uint32_t FileIndex; }; using data_type_ref = const data_type &; @@ -1676,6 +1678,10 @@ } LE.write<uint32_t>(Offset); + // Write this file UID and its index into the array where it was written. + LE.write<uint32_t>(Data.UID); + LE.write<uint32_t>(Data.FileIndex); + auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) { if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) { uint32_t Value = (ModID << 2) | (unsigned)Role; @@ -1800,7 +1806,8 @@ Filename, File->getSize(), getTimestampForOutput(File) }; HeaderFileInfoTrait::data_type Data = { - *HFI, HS.getModuleMap().findAllModulesForHeader(File), {} + *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}, + File->getUID(), UID, }; Generator.insert(Key, Data, GeneratorTrait); ++NumHeaderSearchEntries; @@ -2634,6 +2641,18 @@ Stream.EmitRecord(SUBMODULE_IMPORTS, Record); } + // Emit the imported header's UIDs. + { + auto it = PP->Submodules.find(Mod); + if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty() ) { + RecordData Record; + for (auto FileUID : it->second.IncludedFiles) { + Record.push_back(FileUID); + } + Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record); + } + } + // Emit the exports. if (!Mod->Exports.empty()) { RecordData Record; Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -1898,6 +1898,13 @@ HFI.Framework = HS->getUniqueFrameworkName(FrameworkName); } + // Read the file old UID + { + HFI.UID = endian::readNext<uint32_t, little, unaligned>(d); + //TODO: seems the index is not needed + const uint32_t OldIndex = endian::readNext<uint32_t, little, unaligned>(d); + } + assert((End - d) % 4 == 0 && "Wrong data length in HeaderFileInfo deserialization"); while (d != End) { @@ -9271,6 +9278,37 @@ for (auto *ND : PendingMergedDefinitionsToDeduplicate) getContext().deduplicateMergedDefinitonsFor(ND); PendingMergedDefinitionsToDeduplicate.clear(); + + // Fix up the HeaderSearchInfo UIDs. + if (!PendingImportedHeaders.empty()){ + std::map<unsigned, unsigned> OldToNewUID; + + // These HFIs were deserialized and assigned their "old" + // UID. + // We need to update them and populate the OldToNewUID map + // for use next. + HeaderSearch& HS = PP.getHeaderSearchInfo(); + for (unsigned NewUID = 0; NewUID < HS.FileInfo.size(); ++NewUID) { + OldToNewUID[HS.FileInfo[NewUID].UID] = NewUID; + HS.FileInfo[NewUID].UID = NewUID; + } + + const auto& Iter = PendingImportedHeaders.begin(); + for (unsigned I = 0; I < PendingImportedHeaders.size(); ++I){ + ModuleFile* ModFile = Iter[I].first; + auto& HeaderUIDs = Iter[I].second; + Module *M = HS.lookupModule(ModFile->ModuleName); + + Preprocessor::SubmoduleState& SubState = PP.Submodules[M]; + for (unsigned OldUid : HeaderUIDs) { + auto NewUIDIt = OldToNewUID.find(OldUid); + assert(NewUIDIt != OldToNewUID.end()); + + SubState.IncludedFiles.insert(NewUIDIt->second); + } + } + PendingImportedHeaders.clear(); + } } void ASTReader::diagnoseOdrViolations() { Index: clang/lib/Lex/HeaderSearch.cpp =================================================================== --- clang/lib/Lex/HeaderSearch.cpp +++ clang/lib/Lex/HeaderSearch.cpp @@ -1253,60 +1253,21 @@ // 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; - }; + assert(FileInfo.UID == File->getUID()); // 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(FileInfo.UID))return false; + else { + // Mark as 'included'. + PP.setIncludeVisible(FileInfo.UID); + } } // 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,12 @@ /// IDs have not yet been deserialized to the global IDs of those macros. PendingMacroIDsMap PendingMacroIDs; + /// Mapping from ModuleFile to a list of its imported headers' (old) UID. + /// These UIDs are yet to be mapped to their corresponding HeaderFileInfo + using PendingImportedHeadersMap = + llvm::MapVector<ModuleFile*, SmallVector<unsigned, 8>>; + PendingImportedHeadersMap PendingImportedHeaders; + using GlobalPreprocessedEntityMapType = ContinuousRangeMap<unsigned, ModuleFile *, 4>; Index: clang/include/clang/Serialization/ASTBitCodes.h =================================================================== --- clang/include/clang/Serialization/ASTBitCodes.h +++ clang/include/clang/Serialization/ASTBitCodes.h @@ -781,6 +781,9 @@ /// Specifies the name of the module that will eventually /// re-export the entities in this module. SUBMODULE_EXPORT_AS = 17, + + // Specifies the headers' UID imported by this submodule. + SUBMODULE_IMPORTED_HEADERS = 18, }; /// Record types used within a comments block. 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> @@ -128,6 +129,8 @@ class Preprocessor { friend class VAOptDefinitionContext; friend class VariadicMacroScopeGuard; + friend class ASTWriter; + friend class ASTReader; llvm::unique_function<void(const clang::Token &)> OnToken; std::shared_ptr<PreprocessorOptions> PPOpts; @@ -743,6 +746,9 @@ /// The set of modules that are visible within the submodule. VisibleModuleSet VisibleModules; + /// The set of UIDs from the included headers for the submodule. + std::set<unsigned> IncludedFiles; + // FIXME: CounterValue? // FIXME: PragmaPushMacroInfo? }; @@ -1038,6 +1044,15 @@ OnToken = std::move(F); } + void setIncludeVisible(const unsigned UID) { + CurSubmoduleState->IncludedFiles.insert(UID); + } + + bool isIncludeVisible(const unsigned UID) { + return CurSubmoduleState->IncludedFiles.find(UID) != + 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,13 @@ /// of the framework. StringRef Framework; + /// The file UID used during [de]serialization. + unsigned UID = 0; + 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) {} /// Retrieve the controlling macro for this header file, if /// any. @@ -157,6 +160,7 @@ /// by a \#include or \#include_next, (sub-)framework lookup, etc. class HeaderSearch { friend class DirectoryLookup; + friend class ASTReader; /// Header-search options used to initialize this header search. std::shared_ptr<HeaderSearchOptions> HSOpts;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits