[clang] [llvm] [clang][modules] Separate parsing of modulemaps (PR #119740)

via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 12 10:39:36 PST 2024


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff 4b825c7417f72ee88ee3e4316d0c01ed463f1241 12f19b16945b66e75a32cade1f7cb7aac8424b12 --extensions c,cpp,h -- clang/include/clang/Lex/ModuleMapFile.h clang/lib/Lex/ModuleMapFile.cpp clang/include/clang/Basic/Module.h clang/include/clang/Lex/ModuleMap.h clang/lib/Lex/ModuleMap.cpp clang/test/Modules/export_as_test.c llvm/include/llvm/ADT/STLExtras.h
``````````

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/clang/include/clang/Lex/ModuleMapFile.h b/clang/include/clang/Lex/ModuleMapFile.h
index 8b79897876..b6e1917399 100644
--- a/clang/include/clang/Lex/ModuleMapFile.h
+++ b/clang/include/clang/Lex/ModuleMapFile.h
@@ -123,8 +123,7 @@ struct ConflictDecl {
   StringRef Message;
 };
 
-using TopLevelDecl =
-    std::variant<ModuleDecl, ExternModuleDecl>;
+using TopLevelDecl = std::variant<ModuleDecl, ExternModuleDecl>;
 
 struct ModuleMapFile {
   std::vector<TopLevelDecl> Decls;
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 11b38db9eb..122b3010f4 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -1458,329 +1458,338 @@ bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
 //----------------------------------------------------------------------------//
 
 namespace clang {
-  class ModuleMapParser {
-    modulemap::ModuleMapFile &MMF;
-    SourceManager &SourceMgr;
-
-    DiagnosticsEngine &Diags;
-    ModuleMap ⤅
-
-    /// The current module map file.
-    FileID ModuleMapFID;
-
-    /// Source location of most recent parsed module declaration
-    SourceLocation CurrModuleDeclLoc;
-
-    /// The directory that file names in this module map file should
-    /// be resolved relative to.
-    DirectoryEntryRef Directory;
-
-    /// Whether this module map is in a system header directory.
-    bool IsSystem;
-
-    /// Whether an error occurred.
-    bool HadError = false;
-
-    /// The active module.
-    Module *ActiveModule = nullptr;
-
-    /// Whether a module uses the 'requires excluded' hack to mark its
-    /// contents as 'textual'.
-    ///
-    /// On older Darwin SDK versions, 'requires excluded' is used to mark the
-    /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
-    /// non-modular headers.  For backwards compatibility, we continue to
-    /// support this idiom for just these modules, and map the headers to
-    /// 'textual' to match the original intent.
-    llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
-
-    void handleModuleDecl(const modulemap::ModuleDecl &MD);
-    void handleExternModuleDecl(const modulemap::ExternModuleDecl &EMD);
-    void handleRequiresDecl(const modulemap::RequiresDecl &RD);
-    void handleHeaderDecl(const modulemap::HeaderDecl &HD);
-    void handleUmbrellaDirDecl(const modulemap::UmbrellaDirDecl &UDD);
-    void handleExportDecl(const modulemap::ExportDecl &ED);
-    void handleExportAsDecl(const modulemap::ExportAsDecl &EAD);
-    void handleUseDecl(const modulemap::UseDecl &UD);
-    void handleLinkDecl(const modulemap::LinkDecl &LD);
-    void handleConfigMacros(const modulemap::ConfigMacrosDecl &CMD);
-    void handleConflict(const modulemap::ConflictDecl &CD);
-    void handleInferredModuleDecl(const modulemap::ModuleDecl &MD);
-
-    /// Private modules are canonicalized as Foo_Private. Clang provides extra
-    /// module map search logic to find the appropriate private module when PCH
-    /// is used with implicit module maps. Warn when private modules are written
-    /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
-    void diagnosePrivateModules(SourceLocation StartLoc);
-
-    using Attributes = ModuleMap::Attributes;
-
-  public:
-    ModuleMapParser(modulemap::ModuleMapFile &MMF,
-                    SourceManager &SourceMgr, DiagnosticsEngine &Diags,
-                    ModuleMap &Map, FileID ModuleMapFID,
-                    DirectoryEntryRef Directory, bool IsSystem)
-        : MMF(MMF), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
-          ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {}
-
-    bool parseModuleMapFile();
+class ModuleMapParser {
+  modulemap::ModuleMapFile &MMF;
+  SourceManager &SourceMgr;
+
+  DiagnosticsEngine &Diags;
+  ModuleMap ⤅
+
+  /// The current module map file.
+  FileID ModuleMapFID;
+
+  /// Source location of most recent parsed module declaration
+  SourceLocation CurrModuleDeclLoc;
+
+  /// The directory that file names in this module map file should
+  /// be resolved relative to.
+  DirectoryEntryRef Directory;
+
+  /// Whether this module map is in a system header directory.
+  bool IsSystem;
+
+  /// Whether an error occurred.
+  bool HadError = false;
+
+  /// The active module.
+  Module *ActiveModule = nullptr;
+
+  /// Whether a module uses the 'requires excluded' hack to mark its
+  /// contents as 'textual'.
+  ///
+  /// On older Darwin SDK versions, 'requires excluded' is used to mark the
+  /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
+  /// non-modular headers.  For backwards compatibility, we continue to
+  /// support this idiom for just these modules, and map the headers to
+  /// 'textual' to match the original intent.
+  llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
+
+  void handleModuleDecl(const modulemap::ModuleDecl &MD);
+  void handleExternModuleDecl(const modulemap::ExternModuleDecl &EMD);
+  void handleRequiresDecl(const modulemap::RequiresDecl &RD);
+  void handleHeaderDecl(const modulemap::HeaderDecl &HD);
+  void handleUmbrellaDirDecl(const modulemap::UmbrellaDirDecl &UDD);
+  void handleExportDecl(const modulemap::ExportDecl &ED);
+  void handleExportAsDecl(const modulemap::ExportAsDecl &EAD);
+  void handleUseDecl(const modulemap::UseDecl &UD);
+  void handleLinkDecl(const modulemap::LinkDecl &LD);
+  void handleConfigMacros(const modulemap::ConfigMacrosDecl &CMD);
+  void handleConflict(const modulemap::ConflictDecl &CD);
+  void handleInferredModuleDecl(const modulemap::ModuleDecl &MD);
+
+  /// Private modules are canonicalized as Foo_Private. Clang provides extra
+  /// module map search logic to find the appropriate private module when PCH
+  /// is used with implicit module maps. Warn when private modules are written
+  /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
+  void diagnosePrivateModules(SourceLocation StartLoc);
+
+  using Attributes = ModuleMap::Attributes;
+
+public:
+  ModuleMapParser(modulemap::ModuleMapFile &MMF, SourceManager &SourceMgr,
+                  DiagnosticsEngine &Diags, ModuleMap &Map, FileID ModuleMapFID,
+                  DirectoryEntryRef Directory, bool IsSystem)
+      : MMF(MMF), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
+        ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {}
+
+  bool parseModuleMapFile();
   };
 
-} // namespace clang
+  } // namespace clang
 
 /// Private modules are canonicalized as Foo_Private. Clang provides extra
 /// module map search logic to find the appropriate private module when PCH
 /// is used with implicit module maps. Warn when private modules are written
 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
-void ModuleMapParser::diagnosePrivateModules(SourceLocation StartLoc) {
-  auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
-                             const Module *M, SourceRange ReplLoc) {
-    auto D = Diags.Report(ActiveModule->DefinitionLoc,
-                          diag::note_mmap_rename_top_level_private_module);
-    D << BadName << M->Name;
-    D << FixItHint::CreateReplacement(ReplLoc, Canonical);
-  };
-
-  for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
-    auto const *M = E->getValue();
-    if (M->Directory != ActiveModule->Directory)
-      continue;
+  void ModuleMapParser::diagnosePrivateModules(SourceLocation StartLoc) {
+    auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
+                               const Module *M, SourceRange ReplLoc) {
+      auto D = Diags.Report(ActiveModule->DefinitionLoc,
+                            diag::note_mmap_rename_top_level_private_module);
+      D << BadName << M->Name;
+      D << FixItHint::CreateReplacement(ReplLoc, Canonical);
+    };
+
+    for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
+      auto const *M = E->getValue();
+      if (M->Directory != ActiveModule->Directory)
+        continue;
 
-    SmallString<128> FullName(ActiveModule->getFullModuleName());
-    if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private"))
-      continue;
-    SmallString<128> FixedPrivModDecl;
-    SmallString<128> Canonical(M->Name);
-    Canonical.append("_Private");
-
-    // Foo.Private -> Foo_Private
-    if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
-        M->Name == ActiveModule->Parent->Name) {
-      Diags.Report(ActiveModule->DefinitionLoc,
-                   diag::warn_mmap_mismatched_private_submodule)
-          << FullName;
-
-      SourceLocation FixItInitBegin = CurrModuleDeclLoc;
-      if (StartLoc.isValid())
-        FixItInitBegin = StartLoc;
-
-      if (ActiveModule->Parent->IsFramework)
-        FixedPrivModDecl.append("framework ");
-      FixedPrivModDecl.append("module ");
-      FixedPrivModDecl.append(Canonical);
-
-      GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
-                      SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
-      continue;
-    }
+      SmallString<128> FullName(ActiveModule->getFullModuleName());
+      if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private"))
+        continue;
+      SmallString<128> FixedPrivModDecl;
+      SmallString<128> Canonical(M->Name);
+      Canonical.append("_Private");
+
+      // Foo.Private -> Foo_Private
+      if (ActiveModule->Parent && ActiveModule->Name == "Private" &&
+          !M->Parent && M->Name == ActiveModule->Parent->Name) {
+        Diags.Report(ActiveModule->DefinitionLoc,
+                     diag::warn_mmap_mismatched_private_submodule)
+            << FullName;
+
+        SourceLocation FixItInitBegin = CurrModuleDeclLoc;
+        if (StartLoc.isValid())
+          FixItInitBegin = StartLoc;
+
+        if (ActiveModule->Parent->IsFramework)
+          FixedPrivModDecl.append("framework ");
+        FixedPrivModDecl.append("module ");
+        FixedPrivModDecl.append(Canonical);
+
+        GenNoteAndFixIt(
+            FullName, FixedPrivModDecl, M,
+            SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
+        continue;
+      }
 
-    // FooPrivate and whatnots -> Foo_Private
-    if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
-        ActiveModule->Name != Canonical) {
-      Diags.Report(ActiveModule->DefinitionLoc,
-                   diag::warn_mmap_mismatched_private_module_name)
-          << ActiveModule->Name;
-      GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
-                      SourceRange(ActiveModule->DefinitionLoc));
+      // FooPrivate and whatnots -> Foo_Private
+      if (!ActiveModule->Parent && !M->Parent &&
+          M->Name != ActiveModule->Name && ActiveModule->Name != Canonical) {
+        Diags.Report(ActiveModule->DefinitionLoc,
+                     diag::warn_mmap_mismatched_private_module_name)
+            << ActiveModule->Name;
+        GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
+                        SourceRange(ActiveModule->DefinitionLoc));
+      }
     }
   }
-}
 
-void ModuleMapParser::handleModuleDecl(const modulemap::ModuleDecl &MD) {
-  if (MD.Id.front().first == "*")
-    return handleInferredModuleDecl(MD);
-
-  CurrModuleDeclLoc = MD.Location;
+  void ModuleMapParser::handleModuleDecl(const modulemap::ModuleDecl &MD) {
+    if (MD.Id.front().first == "*")
+      return handleInferredModuleDecl(MD);
+
+    CurrModuleDeclLoc = MD.Location;
+
+    Module *PreviousActiveModule = ActiveModule;
+    if (MD.Id.size() > 1) {
+      // This module map defines a submodule. Go find the module of which it
+      // is a submodule.
+      ActiveModule = nullptr;
+      const Module *TopLevelModule = nullptr;
+      for (unsigned I = 0, N = MD.Id.size() - 1; I != N; ++I) {
+        if (Module *Next =
+                Map.lookupModuleQualified(MD.Id[I].first, ActiveModule)) {
+          if (I == 0)
+            TopLevelModule = Next;
+          ActiveModule = Next;
+          continue;
+        }
 
-  Module *PreviousActiveModule = ActiveModule;
-  if (MD.Id.size() > 1) {
-    // This module map defines a submodule. Go find the module of which it
-    // is a submodule.
-    ActiveModule = nullptr;
-    const Module *TopLevelModule = nullptr;
-    for (unsigned I = 0, N = MD.Id.size() - 1; I != N; ++I) {
-      if (Module *Next = Map.lookupModuleQualified(MD.Id[I].first, ActiveModule)) {
-        if (I == 0)
-          TopLevelModule = Next;
-        ActiveModule = Next;
-        continue;
+        Diags.Report(MD.Id[I].second, diag::err_mmap_missing_parent_module)
+            << MD.Id[I].first << (ActiveModule != nullptr)
+            << (ActiveModule
+                    ? ActiveModule->getTopLevelModule()->getFullModuleName()
+                    : "");
+        HadError = true;
       }
 
-      Diags.Report(MD.Id[I].second, diag::err_mmap_missing_parent_module)
-          << MD.Id[I].first << (ActiveModule != nullptr)
-          << (ActiveModule
-                  ? ActiveModule->getTopLevelModule()->getFullModuleName()
-                  : "");
-      HadError = true;
+      if (TopLevelModule &&
+          ModuleMapFID != Map.getContainingModuleMapFileID(TopLevelModule)) {
+        assert(ModuleMapFID !=
+                   Map.getModuleMapFileIDForUniquing(TopLevelModule) &&
+               "submodule defined in same file as 'module *' that allowed its "
+               "top-level module");
+        Map.addAdditionalModuleMapFile(
+            TopLevelModule, *SourceMgr.getFileEntryRefForID(ModuleMapFID));
+      }
     }
 
-    if (TopLevelModule &&
-        ModuleMapFID != Map.getContainingModuleMapFileID(TopLevelModule)) {
-      assert(ModuleMapFID !=
-                 Map.getModuleMapFileIDForUniquing(TopLevelModule) &&
-             "submodule defined in same file as 'module *' that allowed its "
-             "top-level module");
-      Map.addAdditionalModuleMapFile(
-          TopLevelModule, *SourceMgr.getFileEntryRefForID(ModuleMapFID));
-    }
-  }
+    StringRef ModuleName = MD.Id.back().first;
+    SourceLocation ModuleNameLoc = MD.Id.back().second;
+
+    // Determine whether this (sub)module has already been defined.
+    Module *ShadowingModule = nullptr;
+    if (Module *Existing =
+            Map.lookupModuleQualified(ModuleName, ActiveModule)) {
+      // We might see a (re)definition of a module that we already have a
+      // definition for in four cases:
+      //  - If we loaded one definition from an AST file and we've just found a
+      //    corresponding definition in a module map file, or
+      bool LoadedFromASTFile = Existing->IsFromModuleFile;
+      //  - If we previously inferred this module from different module map
+      //  file.
+      bool Inferred = Existing->IsInferred;
+      //  - If we're building a framework that vends a module map, we might've
+      //    previously seen the one in intermediate products and now the system
+      //    one.
+      // FIXME: If we're parsing module map file that looks like this:
+      //          framework module FW { ... }
+      //          module FW.Sub { ... }
+      //        We can't check the framework qualifier, since it's not attached
+      //        to the definition of Sub. Checking that qualifier on \c Existing
+      //        is not correct either, since we might've previously seen:
+      //          module FW { ... }
+      //          module FW.Sub { ... }
+      //        We should enforce consistency of redefinitions so that we can
+      //        rely that \c Existing is part of a framework iff the
+      //        redefinition of FW we have just skipped had it too. Once we do
+      //        that, stop checking the local framework qualifier and only rely
+      //        on \c Existing.
+      bool PartOfFramework = MD.Framework || Existing->isPartOfFramework();
+      //  - If we're building a (preprocessed) module and we've just loaded the
+      //    module map file from which it was created.
+      bool ParsedAsMainInput =
+          Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
+          Map.LangOpts.CurrentModule == ModuleName &&
+          SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
+              SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
+      if (LoadedFromASTFile || Inferred || PartOfFramework ||
+          ParsedAsMainInput) {
+        ActiveModule = PreviousActiveModule;
+        // Skip the module definition.
+        return;
+      }
 
-  StringRef ModuleName = MD.Id.back().first;
-  SourceLocation ModuleNameLoc = MD.Id.back().second;
-
-  // Determine whether this (sub)module has already been defined.
-  Module *ShadowingModule = nullptr;
-  if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
-    // We might see a (re)definition of a module that we already have a
-    // definition for in four cases:
-    //  - If we loaded one definition from an AST file and we've just found a
-    //    corresponding definition in a module map file, or
-    bool LoadedFromASTFile = Existing->IsFromModuleFile;
-    //  - If we previously inferred this module from different module map file.
-    bool Inferred = Existing->IsInferred;
-    //  - If we're building a framework that vends a module map, we might've
-    //    previously seen the one in intermediate products and now the system
-    //    one.
-    // FIXME: If we're parsing module map file that looks like this:
-    //          framework module FW { ... }
-    //          module FW.Sub { ... }
-    //        We can't check the framework qualifier, since it's not attached to
-    //        the definition of Sub. Checking that qualifier on \c Existing is
-    //        not correct either, since we might've previously seen:
-    //          module FW { ... }
-    //          module FW.Sub { ... }
-    //        We should enforce consistency of redefinitions so that we can rely
-    //        that \c Existing is part of a framework iff the redefinition of FW
-    //        we have just skipped had it too. Once we do that, stop checking
-    //        the local framework qualifier and only rely on \c Existing.
-    bool PartOfFramework = MD.Framework || Existing->isPartOfFramework();
-    //  - If we're building a (preprocessed) module and we've just loaded the
-    //    module map file from which it was created.
-    bool ParsedAsMainInput =
-        Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
-        Map.LangOpts.CurrentModule == ModuleName &&
-        SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
-            SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
-    if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) {
-      ActiveModule = PreviousActiveModule;
-      // Skip the module definition.
-      return;
+      if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
+        ShadowingModule = Existing;
+      } else {
+        // This is not a shawdowed module decl, it is an illegal redefinition.
+        Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
+            << ModuleName;
+        Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
+        HadError = true;
+        return;
+      }
     }
 
-    if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
-      ShadowingModule = Existing;
+    // Start defining this module.
+    if (ShadowingModule) {
+      ActiveModule =
+          Map.createShadowedModule(ModuleName, MD.Framework, ShadowingModule);
     } else {
-      // This is not a shawdowed module decl, it is an illegal redefinition.
-      Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
-          << ModuleName;
-      Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
-      HadError = true;
-      return;
+      ActiveModule = Map.findOrCreateModuleFirst(ModuleName, ActiveModule,
+                                                 MD.Framework, MD.Explicit);
     }
-  }
-
-  // Start defining this module.
-  if (ShadowingModule) {
-    ActiveModule =
-        Map.createShadowedModule(ModuleName, MD.Framework, ShadowingModule);
-  } else {
-    ActiveModule = Map.findOrCreateModuleFirst(ModuleName, ActiveModule,
-                                               MD.Framework, MD.Explicit);
-  }
 
-  ActiveModule->DefinitionLoc = ModuleNameLoc;
-  if (MD.Attrs.IsSystem || IsSystem)
-    ActiveModule->IsSystem = true;
-  if (MD.Attrs.IsExternC)
-    ActiveModule->IsExternC = true;
-  if (MD.Attrs.NoUndeclaredIncludes)
-    ActiveModule->NoUndeclaredIncludes = true;
-  ActiveModule->Directory = Directory;
-
-  StringRef MapFileName(
-      SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());
-  if (MapFileName.ends_with("module.private.modulemap") ||
-      MapFileName.ends_with("module_private.map")) {
-    ActiveModule->ModuleMapIsPrivate = true;
-  }
+    ActiveModule->DefinitionLoc = ModuleNameLoc;
+    if (MD.Attrs.IsSystem || IsSystem)
+      ActiveModule->IsSystem = true;
+    if (MD.Attrs.IsExternC)
+      ActiveModule->IsExternC = true;
+    if (MD.Attrs.NoUndeclaredIncludes)
+      ActiveModule->NoUndeclaredIncludes = true;
+    ActiveModule->Directory = Directory;
+
+    StringRef MapFileName(
+        SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());
+    if (MapFileName.ends_with("module.private.modulemap") ||
+        MapFileName.ends_with("module_private.map")) {
+      ActiveModule->ModuleMapIsPrivate = true;
+    }
 
-  // Private modules named as FooPrivate, Foo.Private or similar are likely a
-  // user error; provide warnings, notes and fixits to direct users to use
-  // Foo_Private instead.
-  SourceLocation StartLoc =
-      SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
-  if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
-      !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
-                       StartLoc) &&
-      !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
-                       StartLoc) &&
-      ActiveModule->ModuleMapIsPrivate)
-    diagnosePrivateModules(MD.Location);
+    // Private modules named as FooPrivate, Foo.Private or similar are likely a
+    // user error; provide warnings, notes and fixits to direct users to use
+    // Foo_Private instead.
+    SourceLocation StartLoc =
+        SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
+    if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
+        !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
+                         StartLoc) &&
+        !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
+                         StartLoc) &&
+        ActiveModule->ModuleMapIsPrivate)
+      diagnosePrivateModules(MD.Location);
+
+    for (const modulemap::Decl &Decl : MD.Decls) {
+      std::visit(
+          llvm::overloaded{
+              [&](const modulemap::RequiresDecl &RD) {
+                handleRequiresDecl(RD);
+              },
+              [&](const modulemap::HeaderDecl &HD) { handleHeaderDecl(HD); },
+              [&](const modulemap::UmbrellaDirDecl &UDD) {
+                handleUmbrellaDirDecl(UDD);
+              },
+              [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },
+              [&](const modulemap::ExportDecl &ED) { handleExportDecl(ED); },
+              [&](const modulemap::ExportAsDecl &EAD) {
+                handleExportAsDecl(EAD);
+              },
+              [&](const modulemap::ExternModuleDecl &EMD) {
+                handleExternModuleDecl(EMD);
+              },
+              [&](const modulemap::UseDecl &UD) { handleUseDecl(UD); },
+              [&](const modulemap::LinkDecl &LD) { handleLinkDecl(LD); },
+              [&](const modulemap::ConfigMacrosDecl &CMD) {
+                handleConfigMacros(CMD);
+              },
+              [&](const modulemap::ConflictDecl &CD) { handleConflict(CD); },
+              [&](const modulemap::ExcludeDecl &ED) {
+                Diags.Report(ED.Location, diag::err_mmap_expected_member);
+              }},
+          Decl);
+    }
 
-  for (const modulemap::Decl &Decl : MD.Decls) {
-    std::visit(
-        llvm::overloaded{
-            [&](const modulemap::RequiresDecl &RD) { handleRequiresDecl(RD); },
-            [&](const modulemap::HeaderDecl &HD) { handleHeaderDecl(HD); },
-            [&](const modulemap::UmbrellaDirDecl &UDD) {
-              handleUmbrellaDirDecl(UDD);
-            },
-            [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },
-            [&](const modulemap::ExportDecl &ED) { handleExportDecl(ED); },
-            [&](const modulemap::ExportAsDecl &EAD) {
-              handleExportAsDecl(EAD);
-            },
-            [&](const modulemap::ExternModuleDecl &EMD) {
-              handleExternModuleDecl(EMD);
-            },
-            [&](const modulemap::UseDecl &UD) { handleUseDecl(UD); },
-            [&](const modulemap::LinkDecl &LD) { handleLinkDecl(LD); },
-            [&](const modulemap::ConfigMacrosDecl &CMD) {
-              handleConfigMacros(CMD);
-            },
-            [&](const modulemap::ConflictDecl &CD) { handleConflict(CD); },
-            [&](const modulemap::ExcludeDecl &ED) {
-              Diags.Report(ED.Location, diag::err_mmap_expected_member);
-            }},
-        Decl);
-  }
+    // If the active module is a top-level framework, and there are no link
+    // libraries, automatically link against the framework.
+    if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
+        ActiveModule->LinkLibraries.empty())
+      inferFrameworkLink(ActiveModule);
+
+    // If the module meets all requirements but is still unavailable, mark the
+    // whole tree as unavailable to prevent it from building.
+    if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
+        ActiveModule->Parent) {
+      ActiveModule->getTopLevelModule()->markUnavailable(
+          /*Unimportable=*/false);
+      ActiveModule->getTopLevelModule()->MissingHeaders.append(
+          ActiveModule->MissingHeaders.begin(),
+          ActiveModule->MissingHeaders.end());
+    }
 
-  // If the active module is a top-level framework, and there are no link
-  // libraries, automatically link against the framework.
-  if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
-      ActiveModule->LinkLibraries.empty())
-    inferFrameworkLink(ActiveModule);
-
-  // If the module meets all requirements but is still unavailable, mark the
-  // whole tree as unavailable to prevent it from building.
-  if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
-      ActiveModule->Parent) {
-    ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
-    ActiveModule->getTopLevelModule()->MissingHeaders.append(
-      ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
+    // We're done parsing this module. Pop back to the previous module.
+    ActiveModule = PreviousActiveModule;
   }
 
-  // We're done parsing this module. Pop back to the previous module.
-  ActiveModule = PreviousActiveModule;
-}
-
-void ModuleMapParser::handleExternModuleDecl(
-    const modulemap::ExternModuleDecl &EMD) {
-  StringRef FileNameRef = EMD.Path;
-  SmallString<128> ModuleMapFileName;
-  if (llvm::sys::path::is_relative(FileNameRef)) {
-    ModuleMapFileName += Directory.getName();
-    llvm::sys::path::append(ModuleMapFileName, EMD.Path);
-    FileNameRef = ModuleMapFileName;
+  void ModuleMapParser::handleExternModuleDecl(
+      const modulemap::ExternModuleDecl &EMD) {
+    StringRef FileNameRef = EMD.Path;
+    SmallString<128> ModuleMapFileName;
+    if (llvm::sys::path::is_relative(FileNameRef)) {
+      ModuleMapFileName += Directory.getName();
+      llvm::sys::path::append(ModuleMapFileName, EMD.Path);
+      FileNameRef = ModuleMapFileName;
+    }
+    if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))
+      Map.parseModuleMapFile(
+          *File, IsSystem,
+          Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
+              ? Directory
+              : File->getDir(),
+          FileID(), nullptr, EMD.Location);
   }
-  if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))
-    Map.parseModuleMapFile(
-        *File, IsSystem,
-        Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
-            ? Directory
-            : File->getDir(),
-        FileID(), nullptr, EMD.Location);
-}
 
 /// Whether to add the requirement \p Feature to the module \p M.
 ///
@@ -1811,7 +1820,6 @@ static bool shouldAddRequirement(Module *M, StringRef Feature,
   return true;
 }
 
-
 void ModuleMapParser::handleRequiresDecl(const modulemap::RequiresDecl &RD) {
 
   for (const modulemap::RequiresFeature &RF : RD.Features) {
@@ -1889,14 +1897,15 @@ static bool compareModuleHeaders(const Module::Header &A,
   return A.NameAsWritten < B.NameAsWritten;
 }
 
-void ModuleMapParser::handleUmbrellaDirDecl(const modulemap::UmbrellaDirDecl &UDD) {
+void ModuleMapParser::handleUmbrellaDirDecl(
+    const modulemap::UmbrellaDirDecl &UDD) {
   std::string DirName = std::string(UDD.Path);
   std::string DirNameAsWritten = DirName;
 
   // Check whether we already have an umbrella.
   if (!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
     Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)
-      << ActiveModule->getFullModuleName();
+        << ActiveModule->getFullModuleName();
     HadError = true;
     return;
   }
@@ -1914,7 +1923,7 @@ void ModuleMapParser::handleUmbrellaDirDecl(const modulemap::UmbrellaDirDecl &UD
 
   if (!Dir) {
     Diags.Report(UDD.Location, diag::warn_mmap_umbrella_dir_not_found)
-      << DirName;
+        << DirName;
     return;
   }
 
@@ -1945,7 +1954,7 @@ void ModuleMapParser::handleUmbrellaDirDecl(const modulemap::UmbrellaDirDecl &UD
 
   if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
     Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)
-      << OwningModule->getFullModuleName();
+        << OwningModule->getFullModuleName();
     HadError = true;
     return;
   }
@@ -1955,9 +1964,7 @@ void ModuleMapParser::handleUmbrellaDirDecl(const modulemap::UmbrellaDirDecl &UD
 }
 
 void ModuleMapParser::handleExportDecl(const modulemap::ExportDecl &ED) {
-  Module::UnresolvedExportDecl Unresolved = {
-    ED.Location, ED.Id, ED.Wildcard
-  };
+  Module::UnresolvedExportDecl Unresolved = {ED.Location, ED.Id, ED.Wildcard};
   ActiveModule->UnresolvedExports.push_back(Unresolved);
 }
 
@@ -1967,11 +1974,11 @@ void ModuleMapParser::handleExportAsDecl(const modulemap::ExportAsDecl &EAD) {
   if (!ActiveModule->ExportAsModule.empty()) {
     if (ActiveModule->ExportAsModule == ModName.first) {
       Diags.Report(ModName.second, diag::warn_mmap_redundant_export_as)
-        << ActiveModule->Name << ModName.first;
+          << ActiveModule->Name << ModName.first;
     } else {
       Diags.Report(ModName.second, diag::err_mmap_conflicting_export_as)
-        << ActiveModule->Name << ActiveModule->ExportAsModule
-        << ModName.first;
+          << ActiveModule->Name << ActiveModule->ExportAsModule
+          << ModName.first;
     }
   }
 
@@ -2016,7 +2023,8 @@ void ModuleMapParser::handleConflict(const modulemap::ConflictDecl &CD) {
   ActiveModule->UnresolvedConflicts.push_back(Conflict);
 }
 
-void ModuleMapParser::handleInferredModuleDecl(const modulemap::ModuleDecl &MD) {
+void ModuleMapParser::handleInferredModuleDecl(
+    const modulemap::ModuleDecl &MD) {
   SourceLocation StarLoc = MD.Id.front().second;
 
   // Inferred modules must be submodules.
@@ -2027,8 +2035,7 @@ void ModuleMapParser::handleInferredModuleDecl(const modulemap::ModuleDecl &MD)
 
   if (ActiveModule) {
     // Inferred modules must have umbrella directories.
-    if (ActiveModule->IsAvailable &&
-        !ActiveModule->getEffectiveUmbrellaDir()) {
+    if (ActiveModule->IsAvailable && !ActiveModule->getEffectiveUmbrellaDir()) {
       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
       return;
     }

``````````

</details>


https://github.com/llvm/llvm-project/pull/119740


More information about the llvm-commits mailing list