aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
authorJan Svoboda <jan_svoboda@apple.com>2023-07-06 19:27:48 -0700
committerJan Svoboda <jan_svoboda@apple.com>2023-07-17 13:50:25 -0700
commitdba2b5c9314e1d127ee5200e739e6c8ca53a9831 (patch)
tree7bbf79447e41049fea247176b85e59874a5afaf5 /clang/lib/Lex/ModuleMap.cpp
parentbe014563f2f492658abcfa68cfaffc58a4ed7d9a (diff)
downloadllvm-dba2b5c9314e1d127ee5200e739e6c8ca53a9831.zip
llvm-dba2b5c9314e1d127ee5200e739e6c8ca53a9831.tar.gz
llvm-dba2b5c9314e1d127ee5200e739e6c8ca53a9831.tar.bz2
[clang][modules] Skip submodule & framework re-definitions in module maps
Before D150478, there were situations when Clang avoided parsing a module map because it was likely to re-define an already defined module (either by a PCM or by previously-found module map). Since Clang no longer performs that check and does parse the extra module map (due to the FW/FW_Private issue described in D150478), this patch re-implements the same semantics by skipping the duplicate definition of the framework module while parsing the module map. Depends on D150478. Reviewed By: benlangmuir Differential Revision: https://reviews.llvm.org/D150479
Diffstat (limited to 'clang/lib/Lex/ModuleMap.cpp')
-rw-r--r--clang/lib/Lex/ModuleMap.cpp21
1 files changed, 19 insertions, 2 deletions
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index c97642e..4f713fe 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -2016,12 +2016,28 @@ void ModuleMapParser::parseModuleDecl() {
Module *ShadowingModule = nullptr;
if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
// We might see a (re)definition of a module that we already have a
- // definition for in three cases:
+ // definition for in four cases:
// - If we loaded one definition from an AST file and we've just found a
// corresponding definition in a module map file, or
bool LoadedFromASTFile = Existing->IsFromModuleFile;
// - If we previously inferred this module from different module map file.
bool Inferred = Existing->IsInferred;
+ // - If we're building a framework that vends a module map, we might've
+ // previously seen the one in intermediate products and now the system
+ // one.
+ // FIXME: If we're parsing module map file that looks like this:
+ // framework module FW { ... }
+ // module FW.Sub { ... }
+ // We can't check the framework qualifier, since it's not attached to
+ // the definition of Sub. Checking that qualifier on \c Existing is
+ // not correct either, since we might've previously seen:
+ // module FW { ... }
+ // module FW.Sub { ... }
+ // We should enforce consistency of redefinitions so that we can rely
+ // that \c Existing is part of a framework iff the redefinition of FW
+ // we have just skipped had it too. Once we do that, stop checking
+ // the local framework qualifier and only rely on \c Existing.
+ bool PartOfFramework = Framework || Existing->isPartOfFramework();
// - If we're building a (preprocessed) module and we've just loaded the
// module map file from which it was created.
bool ParsedAsMainInput =
@@ -2029,7 +2045,8 @@ void ModuleMapParser::parseModuleDecl() {
Map.LangOpts.CurrentModule == ModuleName &&
SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
- if (!ActiveModule && (LoadedFromASTFile || Inferred || ParsedAsMainInput)) {
+ if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) {
+ ActiveModule = PreviousActiveModule;
// Skip the module definition.
skipUntil(MMToken::RBrace);
if (Tok.is(MMToken::RBrace))