manmanren updated this revision to Diff 67431.
manmanren added a comment.

Add comments for setting IsSystem to true.


https://reviews.llvm.org/D23125

Files:
  include/clang/Basic/DiagnosticDriverKinds.td
  include/clang/Driver/Options.td
  include/clang/Lex/HeaderSearchOptions.h
  lib/Driver/Tools.cpp
  lib/Frontend/CompilerInstance.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Serialization/ASTReader.cpp
  test/Driver/modules.m
  test/Modules/Inputs/prebuilt-module/a.h
  test/Modules/Inputs/prebuilt-module/module.modulemap
  test/Modules/prebuilt-module.m

Index: test/Modules/prebuilt-module.m
===================================================================
--- test/Modules/prebuilt-module.m
+++ test/Modules/prebuilt-module.m
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t
+//
+// RUN: %clang_cc1 -fmodules -x objective-c -I %S/Inputs/prebuilt-module -triple %itanium_abi_triple -emit-module %S/Inputs/prebuilt-module/module.modulemap -fmodule-name=prebuilt -o %t/prebuilt.pcm
+// RUN: %clang_cc1 -fmodules -fmodules-use-prebuilt-modules -fdisable-module-hash -fmodules-cache-path=%t/ %s -verify
+
+// expected-no-diagnostics
+@import prebuilt;
+int test() {
+  return a;
+}
Index: test/Modules/Inputs/prebuilt-module/module.modulemap
===================================================================
--- test/Modules/Inputs/prebuilt-module/module.modulemap
+++ test/Modules/Inputs/prebuilt-module/module.modulemap
@@ -0,0 +1 @@
+module prebuilt { header "a.h" }
Index: test/Modules/Inputs/prebuilt-module/a.h
===================================================================
--- test/Modules/Inputs/prebuilt-module/a.h
+++ test/Modules/Inputs/prebuilt-module/a.h
@@ -0,0 +1 @@
+const int a = 1;
Index: test/Driver/modules.m
===================================================================
--- test/Driver/modules.m
+++ test/Driver/modules.m
@@ -39,6 +39,16 @@
 // RUN: %clang -fmodules-disable-diagnostic-validation -### %s 2>&1 | FileCheck -check-prefix=MODULES_DISABLE_DIAGNOSTIC_VALIDATION %s
 // MODULES_DISABLE_DIAGNOSTIC_VALIDATION: -fmodules-disable-diagnostic-validation
 
+// RUN: %clang -fmodules -### %s 2>&1 | FileCheck -check-prefix=MODULES_USE_PREBUILT_MODULES_DEFAULT %s
+// MODULES_USE_PREBUILT_MODULES_DEFAULT-NOT: -fmodules-use-prebuilt-modules
+
+// RUN: %clang -fmodules -fmodules-use-prebuilt-modules -### %s 2>&1 | FileCheck -check-prefix=MODULES_USE_PREBUILT_MODULES %s
+// MODULES_USE_PREBUILT_MODULES: "-fdisable-module-hash"
+// MODULES_USE_PREBUILT_MODULES: "-fmodules-use-prebuilt-modules"
+
+// RUN: %clang -fmodules -fmodules-use-prebuilt-modules -fimplicit-module-maps -### %s 2>&1 | FileCheck -check-prefix=MODULES_USE_PREBUILT_MODULES_ERR %s
+// MODULES_USE_PREBUILT_MODULES_ERR: option '-fmodules-use-prebuilt-modules' conflicts with '-fimplicit-module-maps'
+
 // RUN: %clang -fmodules -fmodule-map-file=foo.map -fmodule-map-file=bar.map -### %s 2>&1 | FileCheck -check-prefix=CHECK-MODULE-MAP-FILES %s
 // CHECK-MODULE-MAP-FILES: "-fmodules"
 // CHECK-MODULE-MAP-FILES: "-fmodule-map-file=foo.map"
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -492,6 +492,11 @@
   }
 }
 
+static bool isPrebuiltModule(Preprocessor &PP, ModuleKind MK) {
+  return (MK == MK_ExplicitModule || MK == MK_ImplicitModule) &&
+      PP.getHeaderSearchInfo().getHeaderSearchOpts().ModulesUsePrebuiltModules;
+}
+
 /// \brief Check the preprocessor options deserialized from the control block
 /// against the preprocessor options in an existing preprocessor.
 ///
@@ -2194,7 +2199,8 @@
       // All user input files reside at the index range [0, NumUserInputs), and
       // system input files reside at [NumUserInputs, NumInputs). For explicitly
       // loaded module files, ignore missing inputs.
-      if (!DisableValidation && F.Kind != MK_ExplicitModule) {
+      if (!DisableValidation && F.Kind != MK_ExplicitModule &&
+          !isPrebuiltModule(PP, F.Kind)) {
         bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
 
         // If we are reading a module, we will create a verification timestamp,
@@ -2225,7 +2231,8 @@
           bool IsSystem = I >= NumUserInputs;
           InputFileInfo FI = readInputFileInfo(F, I+1);
           Listener->visitInputFile(FI.Filename, IsSystem, FI.Overridden,
-                                   F.Kind == MK_ExplicitModule);
+                                   F.Kind == MK_ExplicitModule ||
+                                   isPrebuiltModule(PP, F.Kind));
         }
       }
 
@@ -2255,7 +2262,7 @@
           //
           // FIXME: Allow this for files explicitly specified with -include-pch.
           bool AllowCompatibleConfigurationMismatch =
-              F.Kind == MK_ExplicitModule;
+              F.Kind == MK_ExplicitModule || isPrebuiltModule(PP, F.Kind);
           const HeaderSearchOptions &HSOpts =
               PP.getHeaderSearchInfo().getHeaderSearchOpts();
 
@@ -2269,7 +2276,8 @@
           }
 
           if (DisableValidation ||
-              (AllowConfigurationMismatch && Result == ConfigurationMismatch))
+              ((AllowConfigurationMismatch || isPrebuiltModule(PP, F.Kind)) &&
+               Result == ConfigurationMismatch))
             Result = Success;
 
           // If we can't load the module, exit early since we likely
@@ -2417,7 +2425,8 @@
       if (M && M->Directory) {
         // If we're implicitly loading a module, the base directory can't
         // change between the build and use.
-        if (F.Kind != MK_ExplicitModule) {
+        if (F.Kind != MK_ExplicitModule &&
+            !isPrebuiltModule(PP, F.Kind)) {
           const DirectoryEntry *BuildDir =
               PP.getFileManager().getDirectory(Blob);
           if (!BuildDir || BuildDir != M->Directory) {
@@ -3225,7 +3234,7 @@
   unsigned Idx = 0;
   F.ModuleMapPath = ReadPath(F, Record, Idx);
 
-  if (F.Kind == MK_ExplicitModule) {
+  if (F.Kind == MK_ExplicitModule || isPrebuiltModule(PP, F.Kind)) {
     // For an explicitly-loaded module, we don't care whether the original
     // module map file exists or matches.
     return Success;
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -1367,6 +1367,8 @@
   Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
   Opts.ModulesValidateDiagnosticOptions =
       !Args.hasArg(OPT_fmodules_disable_diagnostic_validation);
+  Opts.ModulesUsePrebuiltModules =
+      Args.hasArg(OPT_fmodules_use_prebuilt_modules);
   Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps);
   Opts.ModuleMapFileHomeIsCwd = Args.hasArg(OPT_fmodule_map_file_home_is_cwd);
   Opts.ModuleCachePruneInterval =
Index: lib/Frontend/CompilerInstance.cpp
===================================================================
--- lib/Frontend/CompilerInstance.cpp
+++ lib/Frontend/CompilerInstance.cpp
@@ -1433,18 +1433,26 @@
   } else {
     // Search for a module with the given name.
     Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
-    if (!Module) {
+    HeaderSearchOptions &HSOpts =
+        PP->getHeaderSearchInfo().getHeaderSearchOpts();
+    if (!Module && !HSOpts.ModulesUsePrebuiltModules) {
       getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
       << ModuleName
       << SourceRange(ImportLoc, ModuleNameLoc);
       ModuleBuildFailed = true;
       return ModuleLoadResult();
     }
+    std::string ModuleFileName;
+    if (HSOpts.ModulesUsePrebuiltModules)
+      // Try to load the pcm file without a module map.
+      ModuleFileName =
+          PP->getHeaderSearchInfo().getModuleFileName(ModuleName, "");
+    else
+      ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module);
 
-    std::string ModuleFileName =
-        PP->getHeaderSearchInfo().getModuleFileName(Module);
     if (ModuleFileName.empty()) {
-      if (Module->HasIncompatibleModuleFile) {
+      if (!HSOpts.ModulesUsePrebuiltModules &&
+          Module->HasIncompatibleModuleFile) {
         // We tried and failed to load a module file for this module. Fall
         // back to textual inclusion for its headers.
         return ModuleLoadResult(nullptr, /*missingExpected*/true);
@@ -1465,16 +1473,42 @@
       Timer.init("Loading " + ModuleFileName, *FrontendTimerGroup);
     llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr);
 
-    // Try to load the module file.
+    // Try to load the module file. If we are using prebuilt modules, we
+    // don't have the module map files and don't know how to rebuild modules.
     unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
     switch (ModuleManager->ReadAST(ModuleFileName,
                                    serialization::MK_ImplicitModule,
-                                   ImportLoc, ARRFlags)) {
-    case ASTReader::Success:
+                                   ImportLoc,
+                                   HSOpts.ModulesUsePrebuiltModules ?
+                                   ASTReader::ARR_ConfigurationMismatch :
+                                   ARRFlags)) {
+    case ASTReader::Success: {
+      if (HSOpts.ModulesUsePrebuiltModules && !Module) {
+        // Create a Module if we are using the prebuilt modules.
+        Module = PP->getHeaderSearchInfo().getModuleMap().findOrCreateModule(
+            ModuleName, nullptr, false/*IsFramework*/,
+            false/*IsExplicit*/).first;
+        // FIXME: Since we are mostly prebuilding system modules, we set
+        // IsSystem to true here. This is not always the correct choice,
+        // and IsSystem can affect diagnostics.
+        Module->IsSystem = true;
+        Module->IsFromModuleFile = true;
+      }
       break;
+    }
 
     case ASTReader::OutOfDate:
     case ASTReader::Missing: {
+      if (HSOpts.ModulesUsePrebuiltModules) {
+        // We can't rebuild the module without a module map. Throw diagnostics
+        // here if using prebuilt modules.
+        getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
+        << ModuleName
+        << SourceRange(ImportLoc, ModuleNameLoc);
+        ModuleBuildFailed = true;
+        return ModuleLoadResult();
+      }
+
       // The module file is missing or out-of-date. Build it.
       assert(Module && "missing module file");
       // Check whether there is a cycle in the module graph.
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -5297,9 +5297,16 @@
 
   // -fmodule-maps enables implicit reading of module map files. By default,
   // this is enabled if we are using precompiled modules.
+  bool IsPrebuilt = Args.getLastArg(options::OPT_fmodules_use_prebuilt_modules);
   if (Args.hasFlag(options::OPT_fimplicit_module_maps,
-                   options::OPT_fno_implicit_module_maps, HaveModules)) {
-    CmdArgs.push_back("-fimplicit-module-maps");
+                   options::OPT_fno_implicit_module_maps,
+                   HaveModules && !IsPrebuilt)) {
+    // When using prebuilt modules, the default is no implicit module maps;
+    // if user specifies implicit module maps, emit error.
+    if (IsPrebuilt)
+      D.Diag(diag::err_drv_modules_use_prebuilt_modules_conflicts_implicit);
+    else
+      CmdArgs.push_back("-fimplicit-module-maps");
   }
 
   // -fmodules-decluse checks that modules used are declared so (off by
@@ -5406,6 +5413,12 @@
   Args.AddLastArg(CmdArgs, options::OPT_fmodules_validate_system_headers);
   Args.AddLastArg(CmdArgs, options::OPT_fmodules_disable_diagnostic_validation);
 
+  if (Args.getLastArg(options::OPT_fmodules_use_prebuilt_modules)) {
+    // When using prebuilt modules, we disable module hash.
+    CmdArgs.push_back("-fdisable-module-hash");
+    Args.AddLastArg(CmdArgs, options::OPT_fmodules_use_prebuilt_modules);
+  }
+
   // -faccess-control is default.
   if (Args.hasFlag(options::OPT_fno_access_control,
                    options::OPT_faccess_control, false))
Index: include/clang/Lex/HeaderSearchOptions.h
===================================================================
--- include/clang/Lex/HeaderSearchOptions.h
+++ include/clang/Lex/HeaderSearchOptions.h
@@ -174,6 +174,8 @@
 
   unsigned ModulesValidateDiagnosticOptions : 1;
 
+  unsigned ModulesUsePrebuiltModules : 1;
+
   HeaderSearchOptions(StringRef _Sysroot = "/")
       : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0),
         ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0),
@@ -183,7 +185,8 @@
         UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
         ModulesValidateOncePerBuildSession(false),
         ModulesValidateSystemHeaders(false),
-        UseDebugInfo(false), ModulesValidateDiagnosticOptions(true) {}
+        UseDebugInfo(false), ModulesValidateDiagnosticOptions(true),
+        ModulesUsePrebuiltModules(false) {}
 
   /// AddPath - Add the \p Path path to the specified \p Group list.
   void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -860,6 +860,9 @@
 def fmodules_disable_diagnostic_validation : Flag<["-"], "fmodules-disable-diagnostic-validation">,
   Group<i_Group>, Flags<[CC1Option]>,
   HelpText<"Disable validation of the diagnostic options when loading the module">;
+def fmodules_use_prebuilt_modules : Flag<["-"], "fmodules-use-prebuilt-modules">,
+  Group<i_Group>, Flags<[CC1Option]>,
+  HelpText<"Use prebuilt modules without loading any module map">;
 def fmodules_validate_system_headers : Flag<["-"], "fmodules-validate-system-headers">,
   Group<i_Group>, Flags<[CC1Option]>,
   HelpText<"Validate the system headers that a module depends on when loading the module">;
Index: include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- include/clang/Basic/DiagnosticDriverKinds.td
+++ include/clang/Basic/DiagnosticDriverKinds.td
@@ -232,6 +232,8 @@
 def err_drv_modules_validate_once_requires_timestamp : Error<
   "option '-fmodules-validate-once-per-build-session' requires "
   "'-fbuild-session-timestamp=<seconds since Epoch>' or '-fbuild-session-file=<file>'">;
+def err_drv_modules_use_prebuilt_modules_conflicts_implicit : Error<
+  "option '-fmodules-use-prebuilt-modules' conflicts with '-fimplicit-module-maps'">;
 
 def err_test_module_file_extension_format : Error<
   "-ftest-module-file-extension argument '%0' is not of the required form "
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to