r325305 - [Modules] Extend -fmodule-name semantic for frameworks with private modules

Bruno Cardoso Lopes via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 15 16:12:58 PST 2018


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; }




More information about the cfe-commits mailing list