summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2014-04-18 22:07:31 +0000
committerBen Langmuir <blangmuir@apple.com>2014-04-18 22:07:31 +0000
commitec8c975214ceb9f59301e2abcd084fcdff06fbcd (patch)
tree52c5c5952a7ba7061df3421293c7679fa5a32193
parentb5d368e838934c1347063a20302acb0afea5f3ab (diff)
downloadbcm5719-llvm-ec8c975214ceb9f59301e2abcd084fcdff06fbcd.tar.gz
bcm5719-llvm-ec8c975214ceb9f59301e2abcd084fcdff06fbcd.zip
Don't build modules with (submodules with) missing headers
Unless they are in submodules that aren't available anyway, due to requirements not being met. Also, mark children as unavailable when the parent is. llvm-svn: 206664
-rw-r--r--clang/include/clang/Basic/Module.h12
-rw-r--r--clang/lib/Basic/Module.cpp5
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp3
-rw-r--r--clang/lib/Lex/ModuleMap.cpp12
-rw-r--r--clang/test/Modules/Inputs/submodules/module.map8
-rw-r--r--clang/test/Modules/missing-header.m13
-rw-r--r--clang/test/Modules/submodules.cpp5
7 files changed, 48 insertions, 10 deletions
diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h
index 49be4ecb4d4..98f86df6d56 100644
--- a/clang/include/clang/Basic/Module.h
+++ b/clang/include/clang/Basic/Module.h
@@ -123,8 +123,13 @@ public:
/// will be false to indicate that this (sub)module is not available.
SmallVector<Requirement, 2> Requirements;
- /// \brief Whether this module is available in the current
- /// translation unit.
+ /// \brief Whether this module is missing a feature from \c Requirements.
+ unsigned IsMissingRequirement : 1;
+
+ /// \brief Whether this module is available in the current translation unit.
+ ///
+ /// If the module is missing headers or does not meet all requirements then
+ /// this bit will be 0.
unsigned IsAvailable : 1;
/// \brief Whether this module was loaded from a module file.
@@ -407,6 +412,9 @@ public:
const LangOptions &LangOpts,
const TargetInfo &Target);
+ /// \brief Mark this module and all of its submodules as unavailable.
+ void markUnavailable();
+
/// \brief Find the submodule with the given name.
///
/// \returns The submodule if found, or NULL otherwise.
diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp
index d5c02d84058..6f29fae03a5 100644
--- a/clang/lib/Basic/Module.cpp
+++ b/clang/lib/Basic/Module.cpp
@@ -160,6 +160,11 @@ void Module::addRequirement(StringRef Feature, bool RequiredState,
if (hasFeature(Feature, LangOpts, Target) == RequiredState)
return;
+ IsMissingRequirement = true;
+ markUnavailable();
+}
+
+void Module::markUnavailable() {
if (!IsAvailable)
return;
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 1092c56ed59..3d65ae32c01 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -288,7 +288,8 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
if (!Module->isAvailable(CI.getLangOpts(), CI.getTarget(), Requirement,
MissingHeader)) {
if (MissingHeader.FileNameLoc.isValid()) {
- CI.getDiagnostics().Report(diag::err_module_header_missing)
+ CI.getDiagnostics().Report(MissingHeader.FileNameLoc,
+ diag::err_module_header_missing)
<< MissingHeader.IsUmbrella << MissingHeader.FileName;
} else {
CI.getDiagnostics().Report(diag::err_module_unavailable)
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 27ba7620ff5..0e712b0dce6 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -1477,6 +1477,15 @@ void ModuleMapParser::parseModuleDecl() {
inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
}
+ // 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 &&
+ ActiveModule->Parent) {
+ ActiveModule->getTopLevelModule()->markUnavailable();
+ ActiveModule->getTopLevelModule()->MissingHeaders.append(
+ ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
+ }
+
// We're done parsing this module. Pop back to the previous module.
ActiveModule = PreviousActiveModule;
}
@@ -1705,9 +1714,8 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// If we find a module that has a missing header, we mark this module as
// unavailable and store the header directive for displaying diagnostics.
- // Other submodules in the same module can still be used.
Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
- ActiveModule->IsAvailable = false;
+ ActiveModule->markUnavailable();
ActiveModule->MissingHeaders.push_back(Header);
}
}
diff --git a/clang/test/Modules/Inputs/submodules/module.map b/clang/test/Modules/Inputs/submodules/module.map
index 15931031abb..8677ea0c80b 100644
--- a/clang/test/Modules/Inputs/submodules/module.map
+++ b/clang/test/Modules/Inputs/submodules/module.map
@@ -15,3 +15,11 @@ module missing_headers {
module missing { header "missing.h" }
module not_missing { header "not_missing.h" }
}
+
+module missing_unavailable_headers {
+ module missing {
+ requires !objc
+ header "missing.h"
+ }
+ module not_missing { }
+}
diff --git a/clang/test/Modules/missing-header.m b/clang/test/Modules/missing-header.m
new file mode 100644
index 00000000000..c2c1673ac5b
--- /dev/null
+++ b/clang/test/Modules/missing-header.m
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -x objective-c -fmodules-cache-path=%t -fmodules -I %S/Inputs/submodules %s 2>&1 | FileCheck %s
+
+// FIXME: cannot use -verify, because the error from inside the module build has
+// a different source manager than the verifier.
+
+@import missing_unavailable_headers; // OK
+@import missing_unavailable_headers.not_missing; // OK
+// CHECK-NOT: missing_unavailable_headers
+
+@import missing_headers;
+// CHECK: module.map:15:27: error: header 'missing.h' not found
+// CHECK: could not build module 'missing_headers'
diff --git a/clang/test/Modules/submodules.cpp b/clang/test/Modules/submodules.cpp
index a18138c7099..7ef785c936c 100644
--- a/clang/test/Modules/submodules.cpp
+++ b/clang/test/Modules/submodules.cpp
@@ -32,8 +32,3 @@ extern MyTypeA import_self_test_a; // expected-error {{must be imported from mod
// expected-note@import-self-a.h:1 {{here}}
extern MyTypeC import_self_test_c;
extern MyTypeD import_self_test_d;
-
-// expected-error@Inputs/submodules/module.map:15{{header 'missing.h' not found}}
-@import missing_headers.missing;
-@import missing_headers.not_missing;
-void f() { NotMissingFunction(); };
OpenPOWER on IntegriCloud