Author: bruno Date: Thu Feb 15 16:12:57 2018 New Revision: 325305 URL: http://llvm.org/viewvc/llvm-project?rev=325305&view=rev Log: [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 Added: cfe/trunk/test/Modules/module-name-private.m Modified: cfe/trunk/lib/Lex/PPDirectives.cpp Modified: cfe/trunk/lib/Lex/PPDirectives.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=325305&r1=325304&r2=325305&view=diff ============================================================================== --- cfe/trunk/lib/Lex/PPDirectives.cpp (original) +++ cfe/trunk/lib/Lex/PPDirectives.cpp Thu Feb 15 16:12:57 2018 @@ -115,6 +115,24 @@ static bool isReservedId(StringRef Text, 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::HandleIncludeDirectiv // 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::HandleIncludeDirectiv // 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::HandleIncludeDirectiv // 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"); Added: cfe/trunk/test/Modules/module-name-private.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/module-name-private.m?rev=325305&view=auto ============================================================================== --- cfe/trunk/test/Modules/module-name-private.m (added) +++ cfe/trunk/test/Modules/module-name-private.m Thu Feb 15 16:12:57 2018 @@ -0,0 +1,12 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-canonical -fsyntax-only %s -Wprivate-module -fmodule-name=A -Rmodule-build + +// Because of -fmodule-name=A, no module (A or A_Private) is supposed to be +// built and -Rmodule-build should not produce any output. + +// expected-no-diagnostics + +#import <A/a.h> +#import <A/aprivate.h> + +int foo() { return APRIVATE; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits