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

2023-07-17 Thread Jan Svoboda via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbe014563f2f4: [clang][modules][deps] Parse 
FW_Private module map even after loading FW PCM 
(authored by jansvoboda11).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150478/new/

https://reviews.llvm.org/D150478

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Lex/HeaderSearch.cpp
  clang/test/Modules/no-check-relocated-fw-private.c


Index: clang/test/Modules/no-check-relocated-fw-private.c
===
--- /dev/null
+++ clang/test/Modules/no-check-relocated-fw-private.c
@@ -0,0 +1,23 @@
+// 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 
+
+//--- 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  // expected-remark{{importing module 'FW1'}} \
+// expected-remark{{importing module 'FW2'}}
+#import  // expected-remark{{importing module 
'FW2_Private'}}
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache 
-fimplicit-module-maps \
+// RUN:   -F %t/frameworks1 -F %t/frameworks2 -fsyntax-only %t/tu.c \
+// RUN:   -fno-modules-check-relocated -Rmodule-import -verify
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1783,9 +1783,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:
@@ -1794,10 +1791,10 @@
   ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr);
 break;
 
-  case LMM_AlreadyLoaded:
   case LMM_NoDirectory:
 return nullptr;
 
+  case LMM_AlreadyLoaded:
   case LMM_NewlyLoaded:
 break;
   }
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2588,6 +2588,10 @@
 defm implicit_modules : BoolFOption<"implicit-modules",
   LangOpts<"ImplicitModules">, DefaultTrue,
   NegFlag, PosFlag, 
BothFlags<[NoXarchOption,CoreOption]>>;
+def fno_modules_check_relocated : Joined<["-"], "fno-modules-check-relocated">,
+  Group, Flags<[CC1Option]>,
+  HelpText<"Skip checks for relocated modules when loading PCM files">,
+  MarshallingInfoNegativeFlag>;
 def fretain_comments_from_system_headers : Flag<["-"], 
"fretain-comments-from-system-headers">, Group, Flags<[CC1Option]>,
   MarshallingInfoFlag>;
 def fmodule_header : Flag <["-"], "fmodule-header">, Group,


Index: clang/test/Modules/no-check-relocated-fw-private.c
===
--- /dev/null
+++ clang/test/Modules/no-check-relocated-fw-private.c
@@ -0,0 +1,23 @@
+// 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 
+
+//--- 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  // expected-remark{{importing module 'FW1'}} \
+// expected-remark{{importing module 'FW2'}}
+#import  // expected-remark{{importing module 'FW2_Private'}}
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -fimplicit-module-maps \
+// RUN:   -F %t/frameworks1 -F %t/frameworks2 -fsyntax-only %t/tu.c \
+// RUN:   -fno-modules-check-relocated -Rmodule-import -verify
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1783,9 +1783,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 

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

2023-07-11 Thread Jan Svoboda via Phabricator via cfe-commits
jansvoboda11 updated this revision to Diff 539127.
jansvoboda11 added a comment.

Expose new preprocessor option as a `-cc1` flag, move test from `ClangScanDeps` 
to `Modules` directory.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150478/new/

https://reviews.llvm.org/D150478

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Lex/HeaderSearch.cpp
  clang/test/Modules/no-check-relocated-fw-private.c


Index: clang/test/Modules/no-check-relocated-fw-private.c
===
--- /dev/null
+++ clang/test/Modules/no-check-relocated-fw-private.c
@@ -0,0 +1,23 @@
+// 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 
+
+//--- 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  // expected-remark{{importing module 'FW1'}} \
+// expected-remark{{importing module 'FW2'}}
+#import  // expected-remark{{importing module 
'FW2_Private'}}
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache 
-fimplicit-module-maps \
+// RUN:   -F %t/frameworks1 -F %t/frameworks2 -fsyntax-only %t/tu.c \
+// RUN:   -fno-modules-check-relocated -Rmodule-import -verify
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1783,9 +1783,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:
@@ -1794,10 +1791,10 @@
   ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr);
 break;
 
-  case LMM_AlreadyLoaded:
   case LMM_NoDirectory:
 return nullptr;
 
+  case LMM_AlreadyLoaded:
   case LMM_NewlyLoaded:
 break;
   }
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2570,6 +2570,10 @@
 defm implicit_modules : BoolFOption<"implicit-modules",
   LangOpts<"ImplicitModules">, DefaultTrue,
   NegFlag, PosFlag, 
BothFlags<[NoXarchOption,CoreOption]>>;
+def fno_modules_check_relocated : Joined<["-"], "fno-modules-check-relocated">,
+  Group, Flags<[CC1Option]>,
+  HelpText<"Skip checks for relocated modules when loading PCM files">,
+  MarshallingInfoNegativeFlag>;
 def fretain_comments_from_system_headers : Flag<["-"], 
"fretain-comments-from-system-headers">, Group, Flags<[CC1Option]>,
   MarshallingInfoFlag>;
 def fmodule_header : Flag <["-"], "fmodule-header">, Group,


Index: clang/test/Modules/no-check-relocated-fw-private.c
===
--- /dev/null
+++ clang/test/Modules/no-check-relocated-fw-private.c
@@ -0,0 +1,23 @@
+// 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 
+
+//--- 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  // expected-remark{{importing module 'FW1'}} \
+// expected-remark{{importing module 'FW2'}}
+#import  // expected-remark{{importing module 'FW2_Private'}}
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -fimplicit-module-maps \
+// RUN:   -F %t/frameworks1 -F %t/frameworks2 -fsyntax-only %t/tu.c \
+// RUN:   -fno-modules-check-relocated -Rmodule-import -verify
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1783,9 +1783,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 

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

2023-05-15 Thread Ben Langmuir via Phabricator via cfe-commits
benlangmuir accepted this revision.
benlangmuir added a comment.
This revision is now accepted and ready to land.

LGTM. I ran into a similar issue in a downstream branch


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150478/new/

https://reviews.llvm.org/D150478

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2023-05-12 Thread Jan Svoboda via Phabricator via cfe-commits
jansvoboda11 added inline comments.



Comment at: clang/lib/Lex/HeaderSearch.cpp:1787
   case LMM_NoDirectory:
 return nullptr;
 

We should probably `break` for `LMM_AlreadyLoaded` instead of returning null.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150478/new/

https://reviews.llvm.org/D150478

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2023-05-12 Thread Jan Svoboda via Phabricator via cfe-commits
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 
, 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 
+
+//--- 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 
+#import 
+
+//--- 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:


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 
+
+//--- 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 
+#import 
+
+//--- cdb.json.template
+[{
+  "file": "DIR/tu.c",
+