Skip to content

Commit 8f11e8c

Browse files
committed
[clang][cas] Enable "full" dependencies output with include-tree
This allows getting full dependencies output with include-tree enabled for caching, similar to what we already do for cas-fs. Conflicts: clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp clang/tools/clang-scan-deps/ClangScanDeps.cpp (cherry picked from commit 6effe8d)
1 parent e6cffd1 commit 8f11e8c

File tree

13 files changed

+206
-25
lines changed

13 files changed

+206
-25
lines changed

clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ enum class ScanningOutputFormat {
5151

5252
/// This emits the CAS ID of the include tree.
5353
IncludeTree,
54+
55+
/// This emits the full dependency graph but with include tree.
56+
FullIncludeTree,
5457
};
5558

5659
/// The dependency scanning service contains shared configuration and state that
@@ -59,6 +62,7 @@ class DependencyScanningService {
5962
public:
6063
DependencyScanningService(
6164
ScanningMode Mode, ScanningOutputFormat Format, CASOptions CASOpts,
65+
std::shared_ptr<llvm::cas::ObjectStore> CAS,
6266
std::shared_ptr<llvm::cas::ActionCache> Cache,
6367
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> SharedFS,
6468
bool OptimizeArgs = false, bool EagerLoadModules = false);
@@ -78,19 +82,19 @@ class DependencyScanningService {
7882
}
7983

8084
const CASOptions &getCASOpts() const { return CASOpts; }
81-
llvm::cas::ActionCache &getCache() const {
82-
assert(Cache && "Cache is not initialized");
83-
return *Cache;
84-
}
85+
86+
std::shared_ptr<llvm::cas::ObjectStore> getCAS() const { return CAS; }
87+
std::shared_ptr<llvm::cas::ActionCache> getCache() const { return Cache; }
8588

8689
llvm::cas::CachingOnDiskFileSystem &getSharedFS() { return *SharedFS; }
8790

88-
bool useCASScanning() const { return (bool)SharedFS; }
91+
bool useCASFS() const { return (bool)SharedFS; }
8992

9093
private:
9194
const ScanningMode Mode;
9295
const ScanningOutputFormat Format;
9396
CASOptions CASOpts;
97+
std::shared_ptr<llvm::cas::ObjectStore> CAS;
9498
std::shared_ptr<llvm::cas::ActionCache> Cache;
9599
/// Whether to optimize the modules' command-line arguments.
96100
const bool OptimizeArgs;

clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ class DependencyScanningWorker {
156156
ScanningOutputFormat getScanningFormat() const { return Format; }
157157

158158
CachingOnDiskFileSystemPtr getCASFS() { return CacheFS; }
159-
bool useCAS() const { return UseCAS; }
160159
const CASOptions &getCASOpts() const { return CASOpts; }
160+
std::shared_ptr<cas::ObjectStore> getCAS() const { return CAS; }
161161

162162
/// If \p DependencyScanningService enabled sharing of \p FileManager this
163163
/// will return the same instance, otherwise it will create a new one for
@@ -187,7 +187,7 @@ class DependencyScanningWorker {
187187
/// The CAS Dependency Filesytem. This is not set at the sametime as DepFS;
188188
llvm::IntrusiveRefCntPtr<DependencyScanningCASFilesystem> DepCASFS;
189189
CASOptions CASOpts;
190-
bool UseCAS;
190+
std::shared_ptr<cas::ObjectStore> CAS;
191191
};
192192

193193
} // end namespace dependencies

clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ using namespace dependencies;
1818

1919
DependencyScanningService::DependencyScanningService(
2020
ScanningMode Mode, ScanningOutputFormat Format, CASOptions CASOpts,
21+
std::shared_ptr<llvm::cas::ObjectStore> CAS,
2122
std::shared_ptr<llvm::cas::ActionCache> Cache,
2223
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> SharedFS,
2324
bool OptimizeArgs, bool EagerLoadModules)
24-
: Mode(Mode), Format(Format), CASOpts(std::move(CASOpts)), Cache(Cache),
25-
OptimizeArgs(OptimizeArgs), SharedFS(std::move(SharedFS)),
26-
EagerLoadModules(EagerLoadModules) {
25+
: Mode(Mode), Format(Format), CASOpts(std::move(CASOpts)), CAS(std::move(CAS)), Cache(std::move(Cache)),
26+
OptimizeArgs(OptimizeArgs), SharedFS(std::move(SharedFS)), EagerLoadModules(EagerLoadModules) {
2727
if (!this->SharedFS)
2828
SharedCache.emplace();
2929

clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ DependencyScanningTool::createActionController(
292292
DependencyScanningWorker &Worker,
293293
LookupModuleOutputCallback LookupModuleOutput,
294294
DepscanPrefixMapping PrefixMapping) {
295+
if (Worker.getScanningFormat() == ScanningOutputFormat::FullIncludeTree)
296+
return createIncludeTreeActionController(*Worker.getCAS(), std::move(PrefixMapping));
295297
if (auto CacheFS = Worker.getCASFS())
296298
return createCASFSActionController(LookupModuleOutput, *CacheFS,
297299
std::move(PrefixMapping));

clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ class DependencyScanningAction : public tooling::ToolAction {
417417
case ScanningOutputFormat::IncludeTree:
418418
case ScanningOutputFormat::Full:
419419
case ScanningOutputFormat::FullTree:
420+
case ScanningOutputFormat::FullIncludeTree:
420421
if (EmitDependencyFile) {
421422
auto DFG =
422423
std::make_shared<ReversePrefixMappingDependencyFileGenerator>(
@@ -534,7 +535,7 @@ DependencyScanningWorker::DependencyScanningWorker(
534535
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS)
535536
: Format(Service.getFormat()), OptimizeArgs(Service.canOptimizeArgs()),
536537
EagerLoadModules(Service.shouldEagerLoadModules()),
537-
CASOpts(Service.getCASOpts()), UseCAS(Service.useCASScanning()) {
538+
CASOpts(Service.getCASOpts()), CAS(Service.getCAS()) {
538539
PCHContainerOps = std::make_shared<PCHContainerOperations>();
539540
PCHContainerOps->registerReader(
540541
std::make_unique<ObjectFilePCHContainerReader>());
@@ -543,9 +544,9 @@ DependencyScanningWorker::DependencyScanningWorker(
543544
PCHContainerOps->registerWriter(
544545
std::make_unique<ObjectFilePCHContainerWriter>());
545546

546-
if (Service.useCASScanning()) {
547+
if (Service.useCASFS()) {
547548
CacheFS = Service.getSharedFS().createProxyFS();
548-
DepCASFS = new DependencyScanningCASFilesystem(CacheFS, Service.getCache());
549+
DepCASFS = new DependencyScanningCASFilesystem(CacheFS, *Service.getCache());
549550
BaseFS = DepCASFS;
550551
return;
551552
}

clang/lib/Tooling/DependencyScanning/IncludeTreeActionController.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class IncludeTreeActionController : public CallbackActionController {
7676
}
7777

7878
cas::ObjectStore &DB;
79+
CASOptions CASOpts;
7980
DepscanPrefixMapping PrefixMapping;
8081
llvm::PrefixMapper PrefixMapper;
8182
Optional<cas::ObjectRef> PCHRef;
@@ -181,6 +182,8 @@ Error IncludeTreeActionController::initialize(
181182
});
182183
ScanInstance.addDependencyCollector(std::move(DC));
183184

185+
CASOpts = ScanInstance.getCASOpts();
186+
184187
return Error::success();
185188
}
186189

@@ -322,9 +325,12 @@ Error IncludeTreeActionController::finalize(CompilerInstance &ScanInstance,
322325
if (!IncludeTreeRoot)
323326
return IncludeTreeRoot.takeError();
324327

325-
// FIXME: use configureInvocationForCaching
326-
NewInvocation.getFrontendOpts().CASIncludeTreeID =
327-
IncludeTreeRoot->getID().toString();
328+
configureInvocationForCaching(NewInvocation, CASOpts,
329+
IncludeTreeRoot->getID().toString(),
330+
/*CASFSWorkingDir=*/"",
331+
/*ProduceIncludeTree=*/true);
332+
333+
DepscanPrefixMapping::remapInvocationPaths(NewInvocation, PrefixMapper);
328334

329335
return Error::success();
330336
}

clang/test/ClangScanDeps/include-tree-prefix-mapping.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// RUN: split-file %s %t
33
// RUN: sed -e "s|DIR|%t|g" -e "s|CLANG|%clang|g" -e "s|SDK|%S/Inputs/SDK|g" %t/cdb.json.template > %t/cdb.json
44

5-
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-include-tree -in-memory-cas \
5+
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-include-tree -cas-path %t/cas \
66
// RUN: -prefix-map=%t=/^src -prefix-map-sdk=/^sdk -prefix-map-toolchain=/^tc > %t/result.txt
77
// RUN: FileCheck %s -input-file %t/result.txt -DPREFIX=%t -DSDK_PREFIX=%S/Inputs/SDK
88

@@ -14,6 +14,59 @@
1414
// CHECK: /^tc{{[/\\]}}lib{{[/\\]}}clang{{[/\\]}}{{.*}}{{[/\\]}}include{{[/\\]}}stdarg.h
1515
// CHECK: /^sdk{{[/\\]}}usr{{[/\\]}}include{{[/\\]}}stdlib.h
1616

17+
// RUN: clang-scan-deps -compilation-database %t/cdb.json \
18+
// RUN: -format experimental-include-tree-full -cas-path %t/cas \
19+
// RUN: -prefix-map=%t=/^src -prefix-map-sdk=/^sdk -prefix-map-toolchain=/^tc > %t/deps.json
20+
21+
// RUN: cat %t/result.txt > %t/full.txt
22+
// RUN: echo "FULL DEPS START" >> %t/full.txt
23+
// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' >> %t/full.txt
24+
25+
// RUN: FileCheck %s -DPREFIX=%/t -DSDK_PREFIX=%S/Inputs/SDK -check-prefix=FULL -input-file %t/full.txt
26+
27+
// Capture the tree id from experimental-include-tree ; ensure that it matches
28+
// the result from experimental-full.
29+
// FULL: [[TREE_ID:llvmcas://[[:xdigit:]]+]] - [[PREFIX]]/t.c
30+
// FULL: FULL DEPS START
31+
32+
// FULL-NEXT: {
33+
// FULL-NEXT: "modules": []
34+
// FULL-NEXT: "translation-units": [
35+
// FULL-NEXT: {
36+
// FULL-NEXT: "commands": [
37+
// FULL-NEXT: {
38+
// FULL: "clang-module-deps": []
39+
// FULL: "command-line": [
40+
// FULL-NEXT: "-cc1"
41+
// FULL: "-fcas-path"
42+
// FULL-NEXT: "[[PREFIX]]/cas"
43+
// FULL: "-disable-free"
44+
// FULL: "-fcas-include-tree"
45+
// FULL-NEXT: "[[TREE_ID]]"
46+
// FULL: "-fcache-compile-job"
47+
// FULL: "-fsyntax-only"
48+
// FULL: "-x"
49+
// FULL-NEXT: "c"
50+
// FULL: "-isysroot"
51+
// FULL-NEXT: "/^sdk"
52+
// FULL: ]
53+
// FULL: "file-deps": [
54+
// FULL-DAG: "[[PREFIX]]/t.c"
55+
// FULL-DAG: "[[PREFIX]]/top.h"
56+
// FULL-DAG: "{{.*}}/stdarg.h"
57+
// FULL-DAG: "[[SDK_PREFIX]]/usr/include/stdlib.h"
58+
// FULL: ]
59+
// FULL: "input-file": "[[PREFIX]]/t.c"
60+
// FULL: }
61+
// FULL: ]
62+
// FULL: }
63+
// FULL: ]
64+
// FULL: }
65+
66+
// Build the include-tree command
67+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp
68+
// RUN: %clang @%t/tu.rsp
69+
1770
//--- cdb.json.template
1871
[
1972
{

clang/test/ClangScanDeps/include-tree-with-pch.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,59 @@
2020
// CHECK-NEXT: [[PREFIX]]/n3.h
2121
// CHECK-NOT: [[PREFIX]]
2222

23+
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-include-tree-full -cas-path %t/cas > %t/deps.json
24+
25+
// RUN: cat %t/result.txt > %t/full.txt
26+
// RUN: echo "FULL DEPS START" >> %t/full.txt
27+
// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' >> %t/full.txt
28+
29+
// RUN: FileCheck %s -DPREFIX=%/t -check-prefix=FULL -input-file %t/full.txt
30+
31+
// Capture the tree id from experimental-include-tree ; ensure that it matches
32+
// the result from experimental-full.
33+
// FULL: [[TREE_ID:llvmcas://[[:xdigit:]]+]] - [[PREFIX]]/t.c
34+
// FULL: FULL DEPS START
35+
36+
// FULL-NEXT: {
37+
// FULL-NEXT: "modules": []
38+
// FULL-NEXT: "translation-units": [
39+
// FULL-NEXT: {
40+
// FULL-NEXT: "commands": [
41+
// FULL-NEXT: {
42+
// FULL: "clang-module-deps": []
43+
// FULL: "command-line": [
44+
// FULL-NEXT: "-cc1"
45+
// FULL: "-fcas-path"
46+
// FULL-NEXT: "[[PREFIX]]/cas"
47+
// FULL: "-disable-free"
48+
// FULL: "-fcas-include-tree"
49+
// FULL-NEXT: "[[TREE_ID]]"
50+
// FULL: "-fcache-compile-job"
51+
// FULL: "-fsyntax-only"
52+
// FULL: "-x"
53+
// FULL-NEXT: "c"
54+
// FULL-NOT: "t.c"
55+
// FULL: "-main-file-name"
56+
// FULL-NEXT: "t.c"
57+
// FULL-NOT: "t.c"
58+
// FULL: ]
59+
// FULL: "executable": "clang"
60+
// FULL: "file-deps": [
61+
// FULL-NEXT: "[[PREFIX]]/t.c"
62+
// FULL-NEXT: "[[PREFIX]]/t.h"
63+
// FULL-NEXT: "[[PREFIX]]/prefix.pch"
64+
// FULL-NEXT: ]
65+
// FULL: "input-file": "[[PREFIX]]/t.c"
66+
// FULL: }
67+
// FULL: ]
68+
// FULL: }
69+
// FULL: ]
70+
// FULL: }
71+
72+
// Build the include-tree command
73+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp
74+
// RUN: %clang @%t/tu.rsp
75+
2376
//--- prefix.h
2477
#include "n1.h"
2578
#import "n2.h"

clang/test/ClangScanDeps/include-tree.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,63 @@
2828
// ORDER-NEXT: [[PREFIX]]/n3.h
2929
// ORDER-NOT: [[PREFIX]]
3030

31+
// Full dependency output
32+
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-include-tree-full -cas-path %t/cas > %t/deps.json
33+
34+
// RUN: cat %t/result1.txt > %t/full.txt
35+
// RUN: echo "FULL DEPS START" >> %t/full.txt
36+
// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' >> %t/full.txt
37+
38+
// RUN: FileCheck %s -DPREFIX=%/t -check-prefix=FULL -input-file %t/full.txt
39+
40+
// Capture the tree id from experimental-include-tree ; ensure that it matches
41+
// the result from experimental-full.
42+
// FULL: [[TREE_ID:llvmcas://[[:xdigit:]]+]] - [[PREFIX]]/t.c
43+
// FULL: FULL DEPS START
44+
45+
// FULL-NEXT: {
46+
// FULL-NEXT: "modules": []
47+
// FULL-NEXT: "translation-units": [
48+
// FULL-NEXT: {
49+
// FULL-NEXT: "commands": [
50+
// FULL-NEXT: {
51+
// FULL: "clang-module-deps": []
52+
// FULL: "command-line": [
53+
// FULL-NEXT: "-cc1"
54+
// FULL: "-fcas-path"
55+
// FULL-NEXT: "[[PREFIX]]/cas"
56+
// FULL: "-disable-free"
57+
// FULL: "-fcas-include-tree"
58+
// FULL-NEXT: "[[TREE_ID]]"
59+
// FULL: "-fcache-compile-job"
60+
// FULL: "-fsyntax-only"
61+
// FULL: "-x"
62+
// FULL-NEXT: "c"
63+
// FULL-NOT: "t.c"
64+
// FULL: "-main-file-name"
65+
// FULL-NEXT: "t.c"
66+
// FULL-NOT: "t.c"
67+
// FULL: ]
68+
// FULL: "executable": "clang"
69+
// FULL: "file-deps": [
70+
// FULL-NEXT: "[[PREFIX]]/t.c"
71+
// FULL-NEXT: "[[PREFIX]]/top.h"
72+
// FULL-NEXT: "[[PREFIX]]/n1.h"
73+
// FULL-NEXT: "[[PREFIX]]/n2.h"
74+
// FULL-NEXT: "[[PREFIX]]/n3.h"
75+
// FULL-NEXT: "[[PREFIX]]/n3.h"
76+
// FULL-NEXT: "[[PREFIX]]/n2.h"
77+
// FULL-NEXT: ]
78+
// FULL: "input-file": "[[PREFIX]]/t.c"
79+
// FULL: }
80+
// FULL: ]
81+
// FULL: }
82+
// FULL: ]
83+
// FULL: }
84+
85+
// Build the include-tree command
86+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp
87+
// RUN: %clang @%t/tu.rsp
3188

3289
//--- cdb.json.template
3390
[

clang/tools/clang-scan-deps/ClangScanDeps.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ static llvm::cl::opt<ScanningOutputFormat> Format(
149149
clEnumValN(ScanningOutputFormat::IncludeTree,
150150
"experimental-include-tree",
151151
"Write out a CAS include tree."),
152+
clEnumValN(ScanningOutputFormat::FullIncludeTree,
153+
"experimental-include-tree-full",
154+
"Full dependency graph with include tree."),
152155
clEnumValN(ScanningOutputFormat::Full, "experimental-full",
153156
"Full dependency graph suitable"
154157
" for explicitly building modules. This format "
@@ -496,6 +499,7 @@ static bool outputFormatRequiresCAS() {
496499
case ScanningOutputFormat::Tree:
497500
case ScanningOutputFormat::FullTree:
498501
case ScanningOutputFormat::IncludeTree:
502+
case ScanningOutputFormat::FullIncludeTree:
499503
return true;
500504
default:
501505
return false;
@@ -882,7 +886,7 @@ int main(int argc, const char **argv) {
882886
std::tie(CAS, Cache) = CASOpts.getOrCreateDatabases(Diags);
883887
if (!CAS)
884888
return 1;
885-
if (Format != ScanningOutputFormat::IncludeTree)
889+
if (Format != ScanningOutputFormat::IncludeTree && Format != ScanningOutputFormat::FullIncludeTree)
886890
FS = llvm::cantFail(llvm::cas::createCachingOnDiskFileSystem(*CAS));
887891
}
888892

@@ -893,7 +897,7 @@ int main(int argc, const char **argv) {
893897
PrefixMapping.NewSDKPath = PrefixMapSDK;
894898
PrefixMapping.PrefixMap.append(PrefixMaps.begin(), PrefixMaps.end());
895899

896-
DependencyScanningService Service(ScanMode, Format, CASOpts, Cache, FS,
900+
DependencyScanningService Service(ScanMode, Format, CASOpts, CAS, Cache, FS,
897901
OptimizeArgs, EagerLoadModules);
898902
llvm::ThreadPool Pool(llvm::hardware_concurrency(NumThreads));
899903

@@ -1038,7 +1042,8 @@ int main(int argc, const char **argv) {
10381042
HadErrors = true;
10391043
}
10401044
} else if (Format == ScanningOutputFormat::Full ||
1041-
Format == ScanningOutputFormat::FullTree) {
1045+
Format == ScanningOutputFormat::FullTree ||
1046+
Format == ScanningOutputFormat::FullIncludeTree) {
10421047
FD.printFullOutput(llvm::outs());
10431048
}
10441049

0 commit comments

Comments
 (0)