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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits