]> granicus.if.org Git - clang/commitdiff
[Modules] Allow missing header before a missing requirement
authorBen Langmuir <blangmuir@apple.com>
Mon, 13 Jul 2015 19:48:52 +0000 (19:48 +0000)
committerBen Langmuir <blangmuir@apple.com>
Mon, 13 Jul 2015 19:48:52 +0000 (19:48 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@242055 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Basic/Module.cpp
test/Modules/Inputs/module.map
test/Modules/requires.m

index 1a48a6c6a8d117e59c455943d0a2c1f04e7cd35c..3846fecebf5d0beb9b66ea2e6acd11d683d187fb 100644 (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);
     }
   }
index ffaa53e18e28895a4aa3dab0db877a3d443532d1..904c65c2dbf43763992043d52413398ce41b72f1 100644 (file)
@@ -336,3 +336,14 @@ module ImportNameInDir {
   header "ImportNameInDir.h"
   export *
 }
+
+module RequiresWithMissingHeader {
+  module HeaderBefore {
+    header "RequiresWithMissingHeader-Missing1.h"
+    requires missing
+  }
+  module HeaderAfter {
+    requires missing
+    header "RequiresWithMissingHeader-Missing2.h"
+  }
+}
index 155c6aec5dc4f0ca7cbb2d74965ef85359e84c5a..1a013727108b74050baa34864aacfa433f453227 100644 (file)
@@ -6,3 +6,7 @@
 @import DependsOnModule.NotObjC; // expected-error{{module 'DependsOnModule.NotObjC' is incompatible with feature 'objc'}}
 @import DependsOnModule.CustomReq1; // OK
 @import DependsOnModule.CustomReq2; // expected-error{{module 'DependsOnModule.CustomReq2' requires feature 'custom_req2'}}
+
+@import RequiresWithMissingHeader; // OK
+@import RequiresWithMissingHeader.HeaderBefore; // expected-error{{module 'RequiresWithMissingHeader.HeaderBefore' requires feature 'missing'}}
+@import RequiresWithMissingHeader.HeaderAfter; // expected-error{{module 'RequiresWithMissingHeader.HeaderAfter' requires feature 'missing'}}