summaryrefslogtreecommitdiffstats
path: root/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-08-18 23:42:23 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-08-18 23:42:23 +0000
commit52dd46213d6c78575cfa543afe7db83fdbd4b36c (patch)
tree0d9474f9710541cdb3a2079ca6cd96645f060d31 /lib/Lex/ModuleMap.cpp
parent673861a3c68537a1bd889860e4cec5773ecdc754 (diff)
[modules] Fix HeaderFileInfo serialization to store all the known owning modules for a header, not just the current favourite.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@245390 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/ModuleMap.cpp')
-rw-r--r--lib/Lex/ModuleMap.cpp45
1 files changed, 31 insertions, 14 deletions
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 9554d3ba45..d619b52bef 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -359,6 +359,13 @@ ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
return MakeResult(Result);
}
+ return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
+}
+
+ModuleMap::KnownHeader
+ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
+ assert(!Headers.count(File) && "already have a module for this header");
+
SmallVector<const DirectoryEntry *, 2> SkippedDirs;
KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
if (H) {
@@ -419,19 +426,22 @@ ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
UmbrellaDirs[SkippedDirs[I]] = Result;
}
- Headers[File].push_back(KnownHeader(Result, NormalHeader));
-
- // If a header corresponds to an unavailable module, don't report
- // that it maps to anything.
- if (!Result->isAvailable())
- return KnownHeader();
-
- return MakeResult(Headers[File].back());
+ KnownHeader Header(Result, NormalHeader);
+ Headers[File].push_back(Header);
+ return Header;
}
return KnownHeader();
}
+ArrayRef<ModuleMap::KnownHeader>
+ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
+ auto It = Headers.find(File);
+ if (It == Headers.end())
+ return None;
+ return It->second;
+}
+
bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
return isHeaderUnavailableInModule(Header, nullptr);
}
@@ -787,14 +797,21 @@ static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
void ModuleMap::addHeader(Module *Mod, Module::Header Header,
ModuleHeaderRole Role) {
- if (!(Role & TextualHeader)) {
- bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
- HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
- isCompilingModuleHeader);
- }
- Headers[Header.Entry].push_back(KnownHeader(Mod, Role));
+ KnownHeader KH(Mod, Role);
+
+ // Only add each header to the headers list once.
+ // FIXME: Should we diagnose if a header is listed twice in the
+ // same module definition?
+ auto &HeaderList = Headers[Header.Entry];
+ for (auto H : HeaderList)
+ if (H == KH)
+ return;
+ HeaderList.push_back(KH);
Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
+
+ bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
+ HeaderInfo.MarkFileModuleHeader(Header.Entry, Role, isCompilingModuleHeader);
}
void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {