Skip to content

Commit 73dba2f

Browse files
committed
[clang][deps] Fix modulemap file path for implementation of module
Use the name "as requested" for the path of the implemented module's modulemap file, just as we do for other modulemap file paths. This fixes fatal errors with modules where we tried to find framework headers relative to the wrong directory when imported by an implementation file of the same module. rdar://104619123 Differential Revision: https://reviews.llvm.org/D142501
1 parent a7bf2e5 commit 73dba2f

File tree

2 files changed

+157
-1
lines changed

2 files changed

+157
-1
lines changed

clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ void ModuleDepCollector::applyDiscoveredDependencies(CompilerInvocation &CI) {
233233
.getModuleMap()
234234
.getModuleMapFileForUniquing(CurrentModule))
235235
CI.getFrontendOpts().ModuleMapFiles.emplace_back(
236-
CurrentModuleMap->getName());
236+
CurrentModuleMap->getNameAsRequested());
237237

238238
SmallVector<ModuleID> DirectDeps;
239239
for (const auto &KV : ModularDeps)
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// Ensure we get the virtual module map path for a module whose implementation
2+
// file we are compiling.
3+
4+
// RUN: rm -rf %t
5+
// RUN: split-file %s %t
6+
7+
//--- real/A.modulemap
8+
framework module A { umbrella header "A.h" }
9+
//--- real/A.private.modulemap
10+
framework module A_Private { umbrella header "A_Private.h" }
11+
12+
//--- frameworks/A.framework/Headers/A.h
13+
struct A { int x; };
14+
//--- frameworks/A.framework/PrivateHeaders/A_Private.h
15+
#import <A/A.h>
16+
17+
//--- frameworks/B.framework/Headers/B.h
18+
#import <A/A.h>
19+
//--- frameworks/B.framework/Modules/module.modulemap
20+
framework module B { umbrella header "B.h" }
21+
22+
//--- overlay.json.template
23+
{
24+
"case-sensitive": "false",
25+
"version": 0,
26+
"roots": [
27+
{
28+
"external-contents": "DIR/real/A.modulemap",
29+
"name": "DIR/frameworks/A.framework/Modules/module.modulemap",
30+
"type": "file"
31+
},
32+
{
33+
"external-contents": "DIR/real/A.private.modulemap",
34+
"name": "DIR/frameworks/A.framework/Modules/module.private.modulemap",
35+
"type": "file"
36+
},
37+
]
38+
}
39+
40+
//--- cdb.json.template
41+
[
42+
{
43+
"file": "DIR/tu1.m",
44+
"directory": "DIR",
45+
"command": "clang -fmodules -fmodules-cache-path=DIR/cache -fmodule-name=A -ivfsoverlay DIR/overlay.json -F DIR/frameworks -fsyntax-only DIR/tu1.m"
46+
},
47+
{
48+
"file": "DIR/tu2.m",
49+
"directory": "DIR",
50+
"command": "clang -fmodules -fmodules-cache-path=DIR/cache -fmodule-name=A -ivfsoverlay DIR/overlay.json -F DIR/frameworks -fsyntax-only DIR/tu2.m"
51+
},
52+
{
53+
"file": "DIR/tu3.m",
54+
"directory": "DIR",
55+
"command": "clang -fmodules -fmodules-cache-path=DIR/cache -fmodule-name=A -ivfsoverlay DIR/overlay.json -F DIR/frameworks -fsyntax-only DIR/tu3.m"
56+
}
57+
]
58+
59+
//--- tu1.m
60+
#import <A/A.h>
61+
62+
//--- tu2.m
63+
#import <A/A_Private.h>
64+
65+
//--- tu3.m
66+
#import <B/B.h>
67+
// The following code triggers a note diagnostic pointing to A.h which is
68+
// resolved relative to the module base directory, which is affected by the
69+
// modulemap path.
70+
struct A { float x; }; // expected-error {{incompatible definitions}} expected-note {{type 'float' here}}
71+
// expected-note@frameworks/A.framework/Headers/A.h:1 {{type 'int' here}}
72+
73+
// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
74+
// RUN: sed -e "s|DIR|%/t|g" %t/overlay.json.template > %t/overlay.json
75+
76+
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full -j 1 > %t/result.json
77+
// RUN: cat %t/result.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t
78+
// CHECK: {
79+
// CHECK: "modules": [
80+
// CHECK: {
81+
// CHECK: "clang-module-deps": []
82+
// CHECK: "command-line": [
83+
// CHECK: "-x"
84+
// CHECK-NEXT: "objective-c"
85+
// CHECK-NEXT: "[[PREFIX]]/frameworks/A.framework/Modules/module.modulemap"
86+
// CHECK: ]
87+
// CHECK: "name": "A"
88+
// CHECK: }
89+
// CHECK: {
90+
// CHECK: "clang-module-deps": [
91+
// CHECK: {
92+
// CHECK: "module-name": "A"
93+
// CHECK: }
94+
// CHECK: ]
95+
// CHECK: "command-line": [
96+
// CHECK: "-fmodule-map-file=[[PREFIX]]/frameworks/A.framework/Modules/module.modulemap",
97+
// CHECK: "-x"
98+
// CHECK-NEXT: "objective-c"
99+
// CHECK-NEXT: "[[PREFIX]]/frameworks/B.framework/Modules/module.modulemap"
100+
// CHECK: ]
101+
// CHECK: "name": "B"
102+
// CHECK: }
103+
104+
// CHECK: "translation-units": [
105+
// CHECK-NEXT: {
106+
// CHECK-NEXT: "commands": [
107+
// CHECK: {
108+
// CHECK: "command-line": [
109+
// CHECK: "-fmodule-map-file=[[PREFIX]]/frameworks/A.framework/Modules/module.modulemap"
110+
// CHECK: "-fmodule-name=A"
111+
// CHECK: ],
112+
// CHECK: "input-file": "[[PREFIX]]/tu1.m"
113+
// CHECK-NEXT: }
114+
// CHECK: ]
115+
// CHECK: }
116+
// CHECK-NEXT: {
117+
// CHECK-NEXT: "commands": [
118+
// CHECK: {
119+
// CHECK: "command-line": [
120+
// CHECK: "-fmodule-map-file=[[PREFIX]]/frameworks/A.framework/Modules/module.modulemap"
121+
// CHECK: "-fmodule-name=A"
122+
// CHECK: ],
123+
// CHECK: "input-file": "[[PREFIX]]/tu2.m"
124+
// CHECK-NEXT: }
125+
// CHECK: ]
126+
// CHECK: }
127+
// CHECK-NEXT: {
128+
// CHECK-NEXT: "commands": [
129+
// CHECK: {
130+
// CHECK: "clang-module-deps": [
131+
// CHECK: {
132+
// CHECK: "module-name": "B"
133+
// CHECK: }
134+
// CHECK: ]
135+
// CHECK: "command-line": [
136+
// CHECK: "-fmodule-map-file=[[PREFIX]]/frameworks/A.framework/Modules/module.modulemap"
137+
// CHECK: "-fmodule-map-file=[[PREFIX]]/frameworks/B.framework/Modules/module.modulemap"
138+
// CHECK: "-fmodule-name=A"
139+
// CHECK: ],
140+
// CHECK: "input-file": "[[PREFIX]]/tu3.m"
141+
// CHECK-NEXT: }
142+
// CHECK: ]
143+
// CHECK: }
144+
145+
// RUN: %deps-to-rsp %t/result.json --tu-index=0 > %t/tu1.rsp
146+
// RUN: %clang @%t/tu1.rsp
147+
148+
// RUN: %deps-to-rsp %t/result.json --tu-index=1 > %t/tu2.rsp
149+
// RUN: %clang @%t/tu2.rsp
150+
151+
// RUN: %deps-to-rsp %t/result.json --module-name A > %t/A.rsp
152+
// RUN: %deps-to-rsp %t/result.json --module-name B > %t/B.rsp
153+
// RUN: %deps-to-rsp %t/result.json --tu-index=2 > %t/tu3.rsp
154+
// RUN: %clang @%t/A.rsp
155+
// RUN: %clang @%t/B.rsp
156+
// RUN: %clang @%t/tu3.rsp -verify

0 commit comments

Comments
 (0)