[PATCH] D150478: [clang][modules][deps] Parse "FW_Private" module map even after loading "FW" PCM

Jan Svoboda via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri May 12 13:41:59 PDT 2023


jansvoboda11 created this revision.
jansvoboda11 added reviewers: benlangmuir, Bigcheese.
Herald added a subscriber: ributzka.
Herald added a project: All.
jansvoboda11 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

When Clang loads a PCM that depends on another PCM describing framework module "FW", `ModuleMap` registers "FW" as known, without seeing the module that defines it (or the adjacent "FW_Private" module). Later, when looking at a header from "FW_Private", `ModuleMap` returns early due to having knowledge about "FW" and never associates that header with "FW_Private", leading to it being treated as textual. This behavior is caused by D150292 <https://reviews.llvm.org/D150292>, where the scanner stops calling `HeaderSearch::lookupModule()` eagerly for every loaded PCM.

This patch skips an early check when trying to figure out the framework module for a header, which ensures the "FW" and (most importantly) "FW_Private" module maps can be parsed even after loading "FW" from a PCM. Note that the `HeaderSearch::loadModuleMapFile()` function we not call unconditionally has caching behavior of its own, meaning it will avoid parsing module map file repeatedly.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D150478

Files:
  clang/lib/Lex/HeaderSearch.cpp
  clang/test/ClangScanDeps/modules-private-framework-submodule.c


Index: clang/test/ClangScanDeps/modules-private-framework-submodule.c
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/modules-private-framework-submodule.c
@@ -0,0 +1,54 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+//--- frameworks1/FW1.framework/Modules/module.modulemap
+framework module FW1 { header "FW1.h" }
+//--- frameworks1/FW1.framework/Headers/FW1.h
+#import <FW2/FW2.h>
+
+//--- frameworks2/FW2.framework/Modules/module.modulemap
+framework module FW2 { header "FW2.h" }
+//--- frameworks2/FW2.framework/Modules/module.private.modulemap
+framework module FW2_Private { header "FW2_Private.h" }
+//--- frameworks2/FW2.framework/Headers/FW2.h
+//--- frameworks2/FW2.framework/PrivateHeaders/FW2_Private.h
+
+//--- tu.c
+#import <FW1/FW1.h>
+#import <FW2/FW2_Private.h>
+
+//--- cdb.json.template
+[{
+  "file": "DIR/tu.c",
+  "directory": "DIR",
+  "command": "clang -fmodules -fmodules-cache-path=DIR/cache -fimplicit-module-maps -F DIR/frameworks1 -F DIR/frameworks2 -c DIR/tu.c -o DIR/tu.o"
+}]
+
+// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
+// RUN: clang-scan-deps -format experimental-full -compilation-database %t/cdb.json > %t/result.json
+// RUN: cat %t/result.json | FileCheck %s -DPREFIX=%/t
+
+// CHECK:       "translation-units": [
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "commands": [
+// CHECK-NEXT:         {
+// CHECK-NEXT:           "clang-context-hash": "{{.*}}",
+// CHECK-NEXT:           "clang-module-deps": [
+// CHECK-NEXT:             {
+// CHECK-NEXT:               "context-hash": "{{.*}}",
+// CHECK-NEXT:               "module-name": "FW1"
+// CHECK-NEXT:             },
+// CHECK-NEXT:             {
+// CHECK-NEXT:               "context-hash": "{{.*}}",
+// CHECK-NEXT:               "module-name": "FW2_Private"
+// CHECK-NEXT:             }
+// CHECK-NEXT:           ],
+// CHECK:                "file-deps": [
+// CHECK-NEXT:             "[[PREFIX]]/tu.c"
+// CHECK-NEXT:           ],
+// CHECK-NEXT:           "input-file": "[[PREFIX]]/tu.c"
+// CHECK:              }
+// CHECK:            ]
+// CHECK:          }
+// CHECK:        ]
+// CHECK:      }
Index: clang/lib/Lex/HeaderSearch.cpp
===================================================================
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1774,9 +1774,6 @@
 
 Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
                                           bool IsSystem) {
-  if (Module *Module = ModMap.findModule(Name))
-    return Module;
-
   // Try to load a module map file.
   switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) {
   case LMM_InvalidModuleMap:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150478.521782.patch
Type: text/x-patch
Size: 2735 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230512/da03fcd4/attachment-0001.bin>


More information about the cfe-commits mailing list