Rename IsMissingRequirement to IsUnimportable and set it for shadowed
modules too.
This more accurately reflects the semantics of this flag, as distinct
from "IsAvailable", which (in an explicit modules world) only describes
whether a module is buildable, not whether it's importable.
diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp
index 5fd7d30..22e1da4 100644
--- a/clang/lib/Basic/Module.cpp
+++ b/clang/lib/Basic/Module.cpp
@@ -37,7 +37,7 @@
Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
bool IsFramework, bool IsExplicit, unsigned VisibilityID)
: Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
- VisibilityID(VisibilityID), IsMissingRequirement(false),
+ VisibilityID(VisibilityID), IsUnimportable(false),
HasIncompatibleModuleFile(false), IsAvailable(true),
IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
IsSystem(false), IsExternC(false), IsInferred(false),
@@ -46,17 +46,12 @@
NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
HasUmbrellaDir(false), NameVisibility(Hidden) {
if (Parent) {
- if (!Parent->isAvailable())
- IsAvailable = false;
- if (Parent->IsSystem)
- IsSystem = true;
- if (Parent->IsExternC)
- IsExternC = true;
- if (Parent->NoUndeclaredIncludes)
- NoUndeclaredIncludes = true;
- if (Parent->ModuleMapIsPrivate)
- ModuleMapIsPrivate = true;
- IsMissingRequirement = Parent->IsMissingRequirement;
+ IsAvailable = Parent->isAvailable();
+ IsUnimportable = Parent->isUnimportable();
+ IsSystem = Parent->IsSystem;
+ IsExternC = Parent->IsExternC;
+ NoUndeclaredIncludes = Parent->NoUndeclaredIncludes;
+ ModuleMapIsPrivate = Parent->ModuleMapIsPrivate;
Parent->SubModuleIndex[Name] = Parent->SubModules.size();
Parent->SubModules.push_back(this);
@@ -132,6 +127,29 @@
return HasFeature;
}
+bool Module::isUnimportable(const LangOptions &LangOpts,
+ const TargetInfo &Target, Requirement &Req,
+ Module *&ShadowingModule) const {
+ if (!IsUnimportable)
+ return false;
+
+ for (const Module *Current = this; Current; Current = Current->Parent) {
+ if (Current->ShadowingModule) {
+ ShadowingModule = Current->ShadowingModule;
+ return true;
+ }
+ for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
+ if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
+ Current->Requirements[I].second) {
+ Req = Current->Requirements[I];
+ return true;
+ }
+ }
+ }
+
+ llvm_unreachable("could not find a reason why module is unimportable");
+}
+
bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
Requirement &Req,
UnresolvedHeaderDirective &MissingHeader,
@@ -139,18 +157,12 @@
if (IsAvailable)
return true;
+ if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
+ return false;
+
+ // FIXME: All missing headers are listed on the top-level module. Should we
+ // just look there?
for (const Module *Current = this; Current; Current = Current->Parent) {
- if (Current->ShadowingModule) {
- ShadowingModule = Current->ShadowingModule;
- return false;
- }
- for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
- if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
- Current->Requirements[I].second) {
- Req = Current->Requirements[I];
- return false;
- }
- }
if (!Current->MissingHeaders.empty()) {
MissingHeader = Current->MissingHeaders.front();
return false;
@@ -287,12 +299,12 @@
if (hasFeature(Feature, LangOpts, Target) == RequiredState)
return;
- markUnavailable(/*MissingRequirement*/true);
+ markUnavailable(/*Unimportable*/true);
}
-void Module::markUnavailable(bool MissingRequirement) {
- auto needUpdate = [MissingRequirement](Module *M) {
- return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
+void Module::markUnavailable(bool Unimportable) {
+ auto needUpdate = [Unimportable](Module *M) {
+ return M->IsAvailable || (!M->IsUnimportable && Unimportable);
};
if (!needUpdate(this))
@@ -308,7 +320,7 @@
continue;
Current->IsAvailable = false;
- Current->IsMissingRequirement |= MissingRequirement;
+ Current->IsUnimportable |= Unimportable;
for (submodule_iterator Sub = Current->submodule_begin(),
SubEnd = Current->submodule_end();
Sub != SubEnd; ++Sub) {
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 470429c..0140a75 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1576,7 +1576,7 @@
Stack.push_back(M);
while (!Stack.empty()) {
Module *Current = Stack.pop_back_val();
- if (Current->IsMissingRequirement) continue;
+ if (Current->IsUnimportable) continue;
Current->IsAvailable = true;
Stack.insert(Stack.end(),
Current->submodule_begin(), Current->submodule_end());
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index bff4e11..2c79bb2 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -282,7 +282,7 @@
// resolved. (Such a module still can't be built though, except from
// preprocessed source.)
if (!Header.Size && !Header.ModTime)
- Mod->markUnavailable();
+ Mod->markUnavailable(/*Unimportable=*/false);
}
}
@@ -1094,7 +1094,7 @@
new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework,
/*IsExplicit=*/false, NumCreatedModules++);
Result->ShadowingModule = ShadowingModule;
- Result->IsAvailable = false;
+ Result->markUnavailable(/*Unimportable*/true);
ModuleScopeIDs[Result] = CurrentModuleScopeID;
ShadowModules.push_back(Result);
@@ -2096,9 +2096,9 @@
// If the module meets all requirements but is still unavailable, mark the
// whole tree as unavailable to prevent it from building.
- if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
+ if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
ActiveModule->Parent) {
- ActiveModule->getTopLevelModule()->markUnavailable();
+ ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
ActiveModule->getTopLevelModule()->MissingHeaders.append(
ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 62dd233..e2f89f5 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -5539,9 +5539,9 @@
// imported module file.
CurrentModule->Requirements.clear();
CurrentModule->MissingHeaders.clear();
- CurrentModule->IsMissingRequirement =
- ParentModule && ParentModule->IsMissingRequirement;
- CurrentModule->IsAvailable = !CurrentModule->IsMissingRequirement;
+ CurrentModule->IsUnimportable =
+ ParentModule && ParentModule->IsUnimportable;
+ CurrentModule->IsAvailable = !CurrentModule->IsUnimportable;
break;
}