Skip to content

Commit c9b7511

Browse files
committed
[clang][cas] Add tests for include-tree module map
* Private modules with fmodule-name * Inferred framework modules * Framework autolink * VFS (cherry picked from commit 9565950) (cherry picked from commit 871b0e7)
1 parent 1fa976b commit c9b7511

File tree

5 files changed

+341
-1
lines changed

5 files changed

+341
-1
lines changed

clang/lib/Tooling/DependencyScanning/IncludeTreeActionController.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ IncludeTreeBuilder::finishIncludeTree(CompilerInstance &ScanInstance,
586586
Module *PM =
587587
MMap.findModule(ScanInstance.getLangOpts().ModuleName + "_Private");
588588
if (PM)
589-
if (Error E = AddModule(M))
589+
if (Error E = AddModule(PM))
590590
return std::move(E);
591591
}
592592

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// REQUIRES: ondisk_cas
2+
3+
// RUN: rm -rf %t
4+
// RUN: split-file %s %t
5+
// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
6+
7+
// RUN: clang-scan-deps -compilation-database %t/cdb.json -j 1 \
8+
// RUN: -cas-path %t/cas -module-files-dir %t/outputs \
9+
// RUN: -format experimental-include-tree-full -mode preprocess-dependency-directives \
10+
// RUN: > %t/deps.json
11+
12+
// Extract the include-tree commands
13+
// RUN: %deps-to-rsp %t/deps.json --module-name TwoSubs > %t/TwoSubs.rsp
14+
// RUN: %deps-to-rsp %t/deps.json --module-name ExportExplicit > %t/ExportExplicit.rsp
15+
// RUN: %deps-to-rsp %t/deps.json --module-name ExportWildcard > %t/ExportWildcard.rsp
16+
// RUN: %deps-to-rsp %t/deps.json --module-name ExportGlobalWildcard > %t/ExportGlobalWildcard.rsp
17+
// RUN: %deps-to-rsp %t/deps.json --module-name NoExports > %t/NoExports.rsp
18+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu_export_explicit.rsp
19+
// RUN: %deps-to-rsp %t/deps.json --tu-index 1 > %t/tu_export_wildcard.rsp
20+
// RUN: %deps-to-rsp %t/deps.json --tu-index 2 > %t/tu_export_global_wildcard.rsp
21+
// RUN: %deps-to-rsp %t/deps.json --tu-index 3 > %t/tu_export_none.rsp
22+
23+
// Build
24+
// RUN: %clang @%t/TwoSubs.rsp
25+
// RUN: %clang @%t/ExportExplicit.rsp
26+
// RUN: %clang @%t/ExportWildcard.rsp
27+
// RUN: %clang @%t/ExportGlobalWildcard.rsp
28+
// RUN: %clang @%t/NoExports.rsp
29+
// RUN: not %clang @%t/tu_export_explicit.rsp 2>&1 | FileCheck %s -check-prefix=tu_export_explicit
30+
// RUN: %clang @%t/tu_export_wildcard.rsp 2>&1 | FileCheck %s -check-prefix=tu_export_wildcard -allow-empty
31+
// RUN: %clang @%t/tu_export_global_wildcard.rsp 2>&1 | FileCheck %s -check-prefix=tu_export_global_wildcard -allow-empty
32+
// RUN: not %clang @%t/tu_export_none.rsp 2>&1 | FileCheck %s -check-prefix=tu_export_none
33+
34+
//--- cdb.json.template
35+
[
36+
{
37+
"file": "DIR/tu_export_explicit.c",
38+
"directory": "DIR",
39+
"command": "clang -fsyntax-only DIR/tu_export_explicit.c -I DIR -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache"
40+
},
41+
{
42+
"file": "DIR/tu_export_wildcard.c",
43+
"directory": "DIR",
44+
"command": "clang -fsyntax-only DIR/tu_export_wildcard.c -I DIR -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache"
45+
},
46+
{
47+
"file": "DIR/tu_export_global_wildcard.c",
48+
"directory": "DIR",
49+
"command": "clang -fsyntax-only DIR/tu_export_global_wildcard.c -I DIR -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache"
50+
},
51+
{
52+
"file": "DIR/tu_export_none.c",
53+
"directory": "DIR",
54+
"command": "clang -fsyntax-only DIR/tu_export_none.c -I DIR -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache"
55+
},
56+
]
57+
58+
//--- module.modulemap
59+
module TwoSubs {
60+
module Sub1 { header "Sub1.h" }
61+
module Sub2 { header "Sub2.h" }
62+
}
63+
64+
module ExportExplicit {
65+
header "Import.h"
66+
export TwoSubs.Sub2
67+
}
68+
69+
module ExportWildcard {
70+
header "Import.h"
71+
export TwoSubs.*
72+
}
73+
74+
module ExportGlobalWildcard {
75+
header "Import.h"
76+
export *
77+
}
78+
79+
module NoExports {
80+
header "Import.h"
81+
}
82+
83+
//--- Sub1.h
84+
void sub1(void);
85+
86+
//--- Sub2.h
87+
void sub2(void);
88+
89+
//--- Import.h
90+
#include "Sub1.h"
91+
#include "Sub2.h"
92+
93+
//--- tu_export_explicit.c
94+
#pragma clang module import ExportExplicit
95+
void tu1(void) {
96+
sub2();
97+
// tu_export_explicit-NOT: error
98+
sub1();
99+
// tu_export_explicit: error: call to undeclared function 'sub1'
100+
// tu_export_explicit: error: missing '#include "Sub1.h"'
101+
}
102+
103+
//--- tu_export_wildcard.c
104+
#pragma clang module import ExportWildcard
105+
void tu1(void) {
106+
sub1();
107+
sub2();
108+
// tu_export_wildcard-NOT: error
109+
}
110+
111+
//--- tu_export_global_wildcard.c
112+
#pragma clang module import ExportGlobalWildcard
113+
void tu1(void) {
114+
sub1();
115+
sub2();
116+
// tu_export_global_wildcard-NOT: error
117+
}
118+
119+
//--- tu_export_none.c
120+
#pragma clang module import NoExports
121+
void tu1(void) {
122+
sub1();
123+
// tu_export_none: error: call to undeclared function 'sub1'
124+
// tu_export_none: error: missing '#include "Sub1.h"'
125+
sub2();
126+
// tu_export_none: error: call to undeclared function 'sub2'
127+
// tu_export_none: error: missing '#include "Sub2.h"'
128+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// REQUIRES: ondisk_cas
2+
3+
// RUN: rm -rf %t
4+
// RUN: split-file %s %t
5+
// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
6+
7+
// RUN: clang-scan-deps -compilation-database %t/cdb.json \
8+
// RUN: -cas-path %t/cas -module-files-dir %t/outputs \
9+
// RUN: -format experimental-include-tree-full -mode preprocess-dependency-directives \
10+
// RUN: > %t/deps.json
11+
12+
// RUN: FileCheck %s -input-file %t/deps.json -check-prefix=NO_MODULES
13+
// NO_MODULES: "modules": []
14+
15+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp
16+
// RUN: cat %t/tu.rsp | sed -E 's|.*"-fcas-include-tree" "(llvmcas://[[:xdigit:]]+)".*|\1|' > %t/tu.casid
17+
// RUN: clang-cas-test -cas %t/cas -print-include-tree @%t/tu.casid | FileCheck %s -DPREFIX=%/t
18+
// RUN: %clang @%t/tu.rsp
19+
20+
// CHECK: [[PREFIX]]/tu.m llvmcas://
21+
// CHECK: 1:1 <built-in> llvmcas://
22+
// CHECK: 2:1 [[PREFIX]]/Mod.framework/Headers/Mod.h llvmcas://
23+
// CHECK: Submodule: Mod
24+
// CHECK: 3:1 [[PREFIX]]/Mod.framework/PrivateHeaders/Priv.h llvmcas://
25+
// CHECK: Submodule: Mod_Private
26+
// CHECK: Module Map:
27+
// CHECK: Mod (framework)
28+
// CHECK: link Mod (framework)
29+
// CHECK: Mod_Private (framework)
30+
// CHECK: link Mod_Private (framework)
31+
32+
// CHECK: Files:
33+
// CHECK: [[PREFIX]]/tu.m llvmcas://
34+
// CHECK-NOT: [[PREFIX]]/module.modulemap
35+
// CHECK: [[PREFIX]]/Mod.framework/Headers/Mod.h llvmcas://
36+
// CHECK-NOT: [[PREFIX]]/module.modulemap
37+
// CHECK: [[PREFIX]]/Mod.framework/PrivateHeaders/Priv.h llvmcas://
38+
// CHECK-NOT: [[PREFIX]]/module.modulemap
39+
40+
//--- cdb.json.template
41+
[{
42+
"file": "DIR/tu.m",
43+
"directory": "DIR",
44+
"command": "clang -fsyntax-only DIR/tu.m -F DIR -fmodule-name=Mod -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache"
45+
}]
46+
47+
//--- Mod.framework/Modules/module.modulemap
48+
framework module Mod { header "Mod.h" }
49+
50+
//--- Mod.framework/Modules/module.private.modulemap
51+
framework module Mod_Private { header "Priv.h" }
52+
53+
//--- Mod.framework/Headers/Mod.h
54+
void pub(void);
55+
56+
//--- Mod.framework/PrivateHeaders/Priv.h
57+
void priv(void);
58+
59+
//--- tu.m
60+
#import <Mod/Mod.h>
61+
#import <Mod/Priv.h>
62+
void tu(void) {
63+
pub();
64+
priv();
65+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// REQUIRES: ondisk_cas
2+
3+
// RUN: rm -rf %t
4+
// RUN: split-file %s %t
5+
// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
6+
7+
// RUN: clang-scan-deps -compilation-database %t/cdb.json \
8+
// RUN: -cas-path %t/cas -module-files-dir %t/outputs \
9+
// RUN: -format experimental-include-tree-full -mode preprocess-dependency-directives \
10+
// RUN: > %t/deps.json
11+
12+
// RUN: %deps-to-rsp %t/deps.json --module-name Mod > %t/Mod.rsp
13+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp
14+
// RUN: cat %t/Mod.rsp | sed -E 's|.*"-fcas-include-tree" "(llvmcas://[[:xdigit:]]+)".*|\1|' > %t/Mod.casid
15+
// RUN: clang-cas-test -cas %t/cas -print-include-tree @%t/Mod.casid | FileCheck %s -DPREFIX=%/t
16+
// RUN: %clang @%t/Mod.rsp
17+
// RUN: %clang @%t/tu.rsp
18+
19+
// CHECK: <module-includes> llvmcas://
20+
// CHECK: 1:1 <built-in> llvmcas://
21+
// CHECK: 2:1 [[PREFIX]]/Mod.framework/Headers/Mod.h llvmcas://
22+
// CHECK: Submodule: Mod
23+
// CHECK: Module Map:
24+
// CHECK: Mod (framework)
25+
// CHECK: link Mod (framework)
26+
// CHECK: Files:
27+
// CHECK-NOT: [[PREFIX]]/module.modulemap
28+
// CHECK: [[PREFIX]]/Mod.framework/Headers/Mod.h llvmcas://
29+
// CHECK-NOT: [[PREFIX]]/module.modulemap
30+
31+
//--- cdb.json.template
32+
[{
33+
"file": "DIR/tu.m",
34+
"directory": "DIR",
35+
"command": "clang -fsyntax-only DIR/tu.m -F DIR -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache"
36+
}]
37+
38+
//--- module.modulemap
39+
framework module * {}
40+
41+
//--- Mod.framework/Headers/Mod.h
42+
void pub(void);
43+
44+
//--- tu.m
45+
#import <Mod/Mod.h>
46+
void tu(void) {
47+
pub();
48+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Check include-tree-based caching works with vfsoverlay files.
2+
3+
// RUN: rm -rf %t
4+
// RUN: split-file %s %t
5+
// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
6+
// RUN: sed -e "s|DIR|%/t|g" %t/vfs.yaml.template > %t/vfs.yaml
7+
8+
// RUN: clang-scan-deps -compilation-database %t/cdb.json -j 1 \
9+
// RUN: -format experimental-include-tree-full -mode preprocess-dependency-directives \
10+
// RUN: -cas-path %t/cas > %t/deps.json
11+
12+
// RUN: %deps-to-rsp %t/deps.json --module-name=A > %t/A.rsp
13+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp
14+
// RUN: %clang @%t/A.rsp
15+
// RUN: %clang @%t/tu.rsp
16+
17+
// Extract include-tree casids
18+
// RUN: cat %t/A.rsp | sed -E 's|.*"-fcas-include-tree" "(llvmcas://[[:xdigit:]]+)".*|\1|' > %t/A.casid
19+
// RUN: cat %t/tu.rsp | sed -E 's|.*"-fcas-include-tree" "(llvmcas://[[:xdigit:]]+)".*|\1|' > %t/tu.casid
20+
21+
// RUN: echo "MODULE A" > %t/result.txt
22+
// RUN: clang-cas-test -cas %t/cas -print-include-tree @%t/A.casid >> %t/result.txt
23+
// RUN: echo "TRANSLATION UNIT" >> %t/result.txt
24+
// RUN: clang-cas-test -cas %t/cas -print-include-tree @%t/tu.casid >> %t/result.txt
25+
26+
// RUN: FileCheck %s -input-file %t/result.txt -DPREFIX=%/t
27+
28+
// CHECK-LABEL: MODULE A
29+
// CHECK: <module-includes> llvmcas://
30+
// CHECK: 2:1 [[PREFIX]]/elsewhere2/A.h llvmcas://
31+
// CHECK: Submodule: A
32+
// CHECK: Module Map:
33+
// CHECK: A (framework)
34+
// CHECK: link A (framework)
35+
// CHECK: Files:
36+
// CHECK-NOT: modulemap
37+
// CHECK: [[PREFIX]]/elsewhere2/A.h llvmcas://
38+
// CHECK-NOT: modulemap
39+
40+
// CHECK-LABEL: TRANSLATION UNIT
41+
// CHECK: Files:
42+
// CHECK-NOT: .modulemap
43+
// CHECK-NOT: .yaml
44+
// CHECK: [[PREFIX]]/elsewhere2/A.h llvmcas://
45+
// CHECK-NOT: .modulemap
46+
// CHECK-NOT: .yaml
47+
48+
//--- cdb.json.template
49+
[{
50+
"directory": "DIR",
51+
"command": "clang -fsyntax-only DIR/tu.c -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -ivfsoverlay DIR/vfs.yaml -F DIR",
52+
"file": "DIR/tu.c"
53+
}]
54+
55+
//--- vfs.yaml.template
56+
{
57+
"version": 0,
58+
"case-sensitive": "false",
59+
"roots": [
60+
{
61+
"name": "DIR/A.framework",
62+
"type": "directory"
63+
"contents": [
64+
{
65+
"name": "Modules",
66+
"type": "directory"
67+
"contents": [
68+
{
69+
"external-contents": "DIR/elsewhere1/A.modulemap",
70+
"name": "module.modulemap",
71+
"type": "file"
72+
}
73+
]
74+
},
75+
{
76+
"name": "Headers",
77+
"type": "directory"
78+
"contents": [
79+
{
80+
"external-contents": "DIR/elsewhere2/A.h",
81+
"name": "A.h",
82+
"type": "file"
83+
}
84+
]
85+
}
86+
]
87+
}
88+
]
89+
}
90+
91+
//--- elsewhere1/A.modulemap
92+
framework module A { header "A.h" }
93+
94+
//--- elsewhere2/A.h
95+
typedef int A_t;
96+
97+
//--- tu.c
98+
#include "A/A.h"
99+
A_t a = 0;

0 commit comments

Comments
 (0)