[Modules] Allow missing header before a missing requirement

And make the module unavailable without breaking any parent modules.

If there's a missing requirement after we've already seen a missing
header, still update the IsMissingRequiement bit correctly.  Also,
diagnose missing requirements before missing headers, since the
existence of the header is moot if there are missing requirements.

llvm-svn: 242055
This commit is contained in:
Ben Langmuir
2015-07-13 19:48:52 +00:00
parent 7ddd501b71
commit 75a7e43581
3 changed files with 26 additions and 7 deletions

View File

@@ -82,10 +82,6 @@ bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
return true;
for (const Module *Current = this; Current; Current = Current->Parent) {
if (!Current->MissingHeaders.empty()) {
MissingHeader = Current->MissingHeaders.front();
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) {
@@ -93,6 +89,10 @@ bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
return false;
}
}
if (!Current->MissingHeaders.empty()) {
MissingHeader = Current->MissingHeaders.front();
return false;
}
}
llvm_unreachable("could not find a reason why module is unavailable");
@@ -184,7 +184,11 @@ void Module::addRequirement(StringRef Feature, bool RequiredState,
}
void Module::markUnavailable(bool MissingRequirement) {
if (!IsAvailable)
auto needUpdate = [MissingRequirement](Module *M) {
return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
};
if (!needUpdate(this))
return;
SmallVector<Module *, 2> Stack;
@@ -193,7 +197,7 @@ void Module::markUnavailable(bool MissingRequirement) {
Module *Current = Stack.back();
Stack.pop_back();
if (!Current->IsAvailable)
if (!needUpdate(Current))
continue;
Current->IsAvailable = false;
@@ -201,7 +205,7 @@ void Module::markUnavailable(bool MissingRequirement) {
for (submodule_iterator Sub = Current->submodule_begin(),
SubEnd = Current->submodule_end();
Sub != SubEnd; ++Sub) {
if ((*Sub)->IsAvailable)
if (needUpdate(*Sub))
Stack.push_back(*Sub);
}
}