99#include " clang/CAS/CASOptions.h"
1010#include " clang/Basic/Diagnostic.h"
1111#include " clang/Basic/DiagnosticCAS.h"
12+ #include " llvm/CAS/ActionCache.h"
1213#include " llvm/CAS/CASDB.h"
14+ #include " llvm/Support/Error.h"
1315
1416using namespace clang ;
1517using namespace llvm ::cas;
1618
1719static std::shared_ptr<llvm::cas::CASDB>
18- createCAS (const CASConfiguration &Config, DiagnosticsEngine &Diags,
19- bool CreateEmptyCASOnFailure) {
20+ createCAS (const CASConfiguration &Config, DiagnosticsEngine &Diags) {
2021 if (Config.CASPath .empty ())
2122 return llvm::cas::createInMemoryCAS ();
2223
@@ -33,7 +34,7 @@ createCAS(const CASConfiguration &Config, DiagnosticsEngine &Diags,
3334 llvm::expectedToOptional (llvm::cas::createOnDiskCAS (Path)))
3435 return std::move (*MaybeCAS);
3536 Diags.Report (diag::err_builtin_cas_cannot_be_initialized) << Path;
36- return CreateEmptyCASOnFailure ? llvm::cas::createInMemoryCAS () : nullptr ;
37+ return nullptr ;
3738}
3839
3940std::shared_ptr<llvm::cas::CASDB>
@@ -42,22 +43,21 @@ CASOptions::getOrCreateCAS(DiagnosticsEngine &Diags,
4243 if (Cache.Config .IsFrozen )
4344 return Cache.CAS ;
4445
45- auto &CurrentConfig = static_cast < const CASConfiguration &>(* this );
46- if (! Cache.CAS || CurrentConfig != Cache. Config ) {
47- Cache.Config = CurrentConfig ;
48- Cache. CAS = createCAS (Cache. Config , Diags, CreateEmptyCASOnFailure);
49- }
50-
46+ initCache (Diags );
47+ if (Cache.CAS )
48+ return Cache.CAS ;
49+ if (! CreateEmptyCASOnFailure)
50+ return nullptr ;
51+ Cache. CAS = llvm::cas::createInMemoryCAS ();
5152 return Cache.CAS ;
5253}
5354
54- std::shared_ptr<llvm::cas::CASDB>
55- CASOptions::getOrCreateCASAndHideConfig (DiagnosticsEngine &Diags) {
55+ void CASOptions::freezeConfig (DiagnosticsEngine &Diags) {
5656 if (Cache.Config .IsFrozen )
57- return Cache. CAS ;
57+ return ;
5858
59- std::shared_ptr<llvm::cas::CASDB> CAS = getOrCreateCAS (Diags);
60- assert (CAS == Cache. CAS && " Expected CAS to be cached " );
59+ // Make sure the cache is initialized.
60+ initCache (Diags );
6161
6262 // Freeze the CAS and wipe out the visible config to hide it from future
6363 // accesses. For example, future diagnostics cannot see this. Something that
@@ -67,13 +67,48 @@ CASOptions::getOrCreateCASAndHideConfig(DiagnosticsEngine &Diags) {
6767 CurrentConfig = CASConfiguration ();
6868 CurrentConfig.IsFrozen = Cache.Config .IsFrozen = true ;
6969
70- if (CAS) {
70+ if (Cache. CAS ) {
7171 // Set the CASPath to the hash schema, since that leaks through CASContext's
7272 // API and is observable.
73- CurrentConfig.CASPath = CAS->getHashSchemaIdentifier ().str ();
73+ CurrentConfig.CASPath = Cache. CAS ->getHashSchemaIdentifier ().str ();
7474 }
75+ if (Cache.AC )
76+ CurrentConfig.CachePath = " " ;
77+ }
78+
79+ static std::shared_ptr<llvm::cas::ActionCache>
80+ createCache (CASDB &CAS, const CASConfiguration &Config,
81+ DiagnosticsEngine &Diags) {
82+ if (Config.CachePath .empty ())
83+ return llvm::cas::createInMemoryActionCache (CAS);
84+
85+ // Compute the path.
86+ std::string Path = Config.CASPath ;
87+ if (Path == " auto" )
88+ Path = getDefaultOnDiskActionCachePath ();
7589
76- return CAS;
90+ // FIXME: Pass on the actual error from the CAS.
91+ if (auto MaybeCache = llvm::expectedToOptional (
92+ llvm::cas::createOnDiskActionCache (CAS, Path)))
93+ return std::move (*MaybeCache);
94+ Diags.Report (diag::err_builtin_actioncache_cannot_be_initialized) << Path;
95+ return nullptr ;
96+ }
97+
98+ std::shared_ptr<llvm::cas::ActionCache>
99+ CASOptions::getOrCreateActionCache (DiagnosticsEngine &Diags,
100+ bool CreateEmptyOnFailure) const {
101+ if (Cache.Config .IsFrozen )
102+ return Cache.AC ;
103+
104+ initCache (Diags);
105+ if (Cache.AC )
106+ return Cache.AC ;
107+ if (!CreateEmptyOnFailure)
108+ return nullptr ;
109+
110+ Cache.CAS = Cache.CAS ? Cache.CAS : llvm::cas::createInMemoryCAS ();
111+ return llvm::cas::createInMemoryActionCache (*Cache.CAS );
77112}
78113
79114void CASOptions::ensurePersistentCAS () {
@@ -83,8 +118,19 @@ void CASOptions::ensurePersistentCAS() {
83118 llvm_unreachable (" Cannot ensure persistent CAS if it's unknown / frozen" );
84119 case InMemoryCAS:
85120 CASPath = " auto" ;
121+ CachePath = " auto" ;
86122 break ;
87123 case OnDiskCAS:
88124 break ;
89125 }
90126}
127+
128+ void CASOptions::initCache (DiagnosticsEngine &Diags) const {
129+ auto &CurrentConfig = static_cast <const CASConfiguration &>(*this );
130+ if (CurrentConfig == Cache.Config && Cache.CAS && Cache.AC )
131+ return ;
132+
133+ Cache.Config = CurrentConfig;
134+ Cache.CAS = createCAS (Cache.Config , Diags);
135+ Cache.AC = createCache (*Cache.CAS , Cache.Config , Diags);
136+ }
0 commit comments