r328053 - [Modules] Honor -fmodule-name when handling private framework modules

Bruno Cardoso Lopes via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 20 15:36:39 PDT 2018


Author: bruno
Date: Tue Mar 20 15:36:39 2018
New Revision: 328053

URL: http://llvm.org/viewvc/llvm-project?rev=328053&view=rev
Log:
[Modules] Honor -fmodule-name when handling private framework modules

When skipping building the module for a private framework module,
LangOpts.CurrentModule isn't enough for implict modules builds; for
instance, in case a private module is built while building a public one,
LangOpts.CurrentModule doesn't reflect the -fmodule-name being passed
down, but instead the module name which triggered the build.

Store the actual -fmodule-name in LangOpts.ModuleName and actually
check a name was provided during compiler invocation in order to
skip building the private module.

rdar://problem/38434694

Added:
    cfe/trunk/test/Modules/Inputs/bad-private-include/
    cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/
    cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Headers/
    cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Headers/Bad.h
    cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/
    cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.modulemap
    cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.private.modulemap
    cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/
    cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/BadPrivate.h
    cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/Shared.h
    cfe/trunk/test/Modules/bad-private-include.m
Modified:
    cfe/trunk/include/clang/Basic/LangOptions.h
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp

Modified: cfe/trunk/include/clang/Basic/LangOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.h?rev=328053&r1=328052&r2=328053&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.h (original)
+++ cfe/trunk/include/clang/Basic/LangOptions.h Tue Mar 20 15:36:39 2018
@@ -141,10 +141,14 @@ public:
   /// If none is specified, abort (GCC-compatible behaviour).
   std::string OverflowHandler;
 
+  /// The module currently being compiled as speficied by -fmodule-name.
+  std::string ModuleName;
+
   /// \brief The name of the current module, of which the main source file
   /// is a part. If CompilingModule is set, we are compiling the interface
   /// of this module, otherwise we are compiling an implementation file of
-  /// it.
+  /// it. This starts as ModuleName in case -fmodule-name is provided and
+  /// changes during compilation to reflect the current module.
   std::string CurrentModule;
 
   /// \brief The names of any features to enable in module 'requires' decls

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=328053&r1=328052&r2=328053&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Tue Mar 20 15:36:39 2018
@@ -1090,6 +1090,10 @@ compileModuleImpl(CompilerInstance &Impo
       }),
       PPOpts.Macros.end());
 
+  // If the original compiler invocation had -fmodule-name, pass it through.
+  Invocation->getLangOpts()->ModuleName =
+      ImportingInstance.getInvocation().getLangOpts()->ModuleName;
+
   // Note the name of the module we're building.
   Invocation->getLangOpts()->CurrentModule = ModuleName;
 

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=328053&r1=328052&r2=328053&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Tue Mar 20 15:36:39 2018
@@ -2372,7 +2372,8 @@ static void ParseLangArgs(LangOptions &O
   Opts.DebuggerCastResultToId = Args.hasArg(OPT_fdebugger_cast_result_to_id);
   Opts.DebuggerObjCLiteral = Args.hasArg(OPT_fdebugger_objc_literal);
   Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack);
-  Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name_EQ);
+  Opts.ModuleName = Args.getLastArgValue(OPT_fmodule_name_EQ);
+  Opts.CurrentModule = Opts.ModuleName;
   Opts.AppExt = Args.hasArg(OPT_fapplication_extension);
   Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature);
   std::sort(Opts.ModuleFeatures.begin(), Opts.ModuleFeatures.end());

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=328053&r1=328052&r2=328053&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Tue Mar 20 15:36:39 2018
@@ -115,18 +115,19 @@ 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) {
+// The -fmodule-name option 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 ModuleName) {
   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 &&
+  if (M->getTopLevelModule()->IsFramework && CurrentModule == ModuleName &&
       !CurrentModule.endswith("_Private") && TopLevelName.endswith("_Private"))
     TopLevelName = TopLevelName.drop_back(8);
 
@@ -1875,7 +1876,8 @@ void Preprocessor::HandleIncludeDirectiv
   // are processing this module textually (because we're building the module).
   if (ShouldEnter && File && SuggestedModule && getLangOpts().Modules &&
       !isForModuleBuilding(SuggestedModule.getModule(),
-                           getLangOpts().CurrentModule)) {
+                           getLangOpts().CurrentModule,
+                           getLangOpts().ModuleName)) {
     // 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
@@ -2022,7 +2024,8 @@ 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 &&
-          isForModuleBuilding(M, getLangOpts().CurrentModule))
+          isForModuleBuilding(M, getLangOpts().CurrentModule,
+                              getLangOpts().ModuleName))
         return;
 
       makeModuleVisible(M, HashLoc);
@@ -2063,7 +2066,8 @@ void Preprocessor::HandleIncludeDirectiv
     // include headers in the specified module. We are not building the
     // specified module.
     if (getLangOpts().CompilingPCH &&
-        isForModuleBuilding(M, getLangOpts().CurrentModule))
+        isForModuleBuilding(M, getLangOpts().CurrentModule,
+                            getLangOpts().ModuleName))
       return;
 
     assert(!CurLexerSubmodule && "should not have marked this as a module yet");

Added: cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Headers/Bad.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Headers/Bad.h?rev=328053&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Headers/Bad.h (added)
+++ cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Headers/Bad.h Tue Mar 20 15:36:39 2018
@@ -0,0 +1 @@
+#import <Bad/Shared.h>
\ No newline at end of file

Added: cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.modulemap
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.modulemap?rev=328053&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.modulemap (added)
+++ cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.modulemap Tue Mar 20 15:36:39 2018
@@ -0,0 +1,5 @@
+framework module Bad {
+  umbrella header "Bad.h"
+  export *
+  module * { export * }
+}

Added: cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.private.modulemap
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.private.modulemap?rev=328053&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.private.modulemap (added)
+++ cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.private.modulemap Tue Mar 20 15:36:39 2018
@@ -0,0 +1,5 @@
+framework module Bad_Private {
+  umbrella header "BadPrivate.h"
+  export *
+  module * { export * }
+}

Added: cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/BadPrivate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/BadPrivate.h?rev=328053&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/BadPrivate.h (added)
+++ cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/BadPrivate.h Tue Mar 20 15:36:39 2018
@@ -0,0 +1 @@
+#import <Bad/Shared.h>
\ No newline at end of file

Added: cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/Shared.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/Shared.h?rev=328053&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/Shared.h (added)
+++ cfe/trunk/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/Shared.h Tue Mar 20 15:36:39 2018
@@ -0,0 +1,3 @@
+struct SomeDecl {
+  int x;
+};

Added: cfe/trunk/test/Modules/bad-private-include.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/bad-private-include.m?rev=328053&view=auto
==============================================================================
--- cfe/trunk/test/Modules/bad-private-include.m (added)
+++ cfe/trunk/test/Modules/bad-private-include.m Tue Mar 20 15:36:39 2018
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t.cache
+// RUN: %clang_cc1 -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps -F %S/Inputs/bad-private-include %s -verify
+
+// expected-no-diagnostics
+
+ at import Bad;




More information about the cfe-commits mailing list