summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2018-02-16 00:12:57 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2018-02-16 00:12:57 +0000
commit5bccc5270ec917e090abb5d79c82d9e686ebe542 (patch)
treee7a66fd84c2984c5d208e44311df6d036aa4ca7d /clang/lib/Lex
parentea33dee38c86348bdad35c68aed64b9fbcd47be5 (diff)
downloadbcm5719-llvm-5bccc5270ec917e090abb5d79c82d9e686ebe542.tar.gz
bcm5719-llvm-5bccc5270ec917e090abb5d79c82d9e686ebe542.zip
[Modules] Extend -fmodule-name semantic for frameworks with private modules
Assume Foo.framework with two module maps and two modules Foo and Foo_Private. Framework authors need to skip building both Foo and Foo_Private when using -fmodule-name=Foo, since both are part of the framework and used interchangeably during compilation. rdar://problem/37500098 llvm-svn: 325305
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r--clang/lib/Lex/PPDirectives.cpp26
1 files changed, 22 insertions, 4 deletions
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 405d19bb285..a901a20b75c 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -115,6 +115,24 @@ static bool isReservedId(StringRef Text, const LangOptions &Lang) {
return false;
}
+// The -fmodule-name option (represented here by \p CurrentModule) tells the
+// compiler to textually include headers in the specified module, meaning clang
+// won't build the specified module. This is useful in a number of situations,
+// for instance, when building a library that vends a module map, one might want
+// to avoid hitting intermediate build products containig the the module map or
+// avoid finding the system installed modulemap for that library.
+static bool isForModuleBuilding(Module *M, StringRef CurrentModule) {
+ StringRef TopLevelName = M->getTopLevelModuleName();
+
+ // When building framework Foo, we wanna make sure that Foo *and* Foo_Private
+ // are textually included and no modules are built for both.
+ if (M->getTopLevelModule()->IsFramework &&
+ !CurrentModule.endswith("_Private") && TopLevelName.endswith("_Private"))
+ TopLevelName = TopLevelName.drop_back(8);
+
+ return TopLevelName == CurrentModule;
+}
+
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) {
const LangOptions &Lang = PP.getLangOpts();
StringRef Text = II->getName();
@@ -1856,8 +1874,8 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// there is one. Don't do so if precompiled module support is disabled or we
// are processing this module textually (because we're building the module).
if (ShouldEnter && File && SuggestedModule && getLangOpts().Modules &&
- SuggestedModule.getModule()->getTopLevelModuleName() !=
- getLangOpts().CurrentModule) {
+ !isForModuleBuilding(SuggestedModule.getModule(),
+ getLangOpts().CurrentModule)) {
// If this include corresponds to a module but that module is
// unavailable, diagnose the situation and bail out.
// FIXME: Remove this; loadModule does the same check (but produces
@@ -2004,7 +2022,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// ShouldEnter is false because we are skipping the header. In that
// case, We are not importing the specified module.
if (SkipHeader && getLangOpts().CompilingPCH &&
- M->getTopLevelModuleName() == getLangOpts().CurrentModule)
+ isForModuleBuilding(M, getLangOpts().CurrentModule))
return;
makeModuleVisible(M, HashLoc);
@@ -2045,7 +2063,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// include headers in the specified module. We are not building the
// specified module.
if (getLangOpts().CompilingPCH &&
- M->getTopLevelModuleName() == getLangOpts().CurrentModule)
+ isForModuleBuilding(M, getLangOpts().CurrentModule))
return;
assert(!CurLexerSubmodule && "should not have marked this as a module yet");
OpenPOWER on IntegriCloud