Skip to content

Commit cfb3eb8

Browse files
committed
[clang/CAS] Simplify clang::CASOptions
Replace `getOrCreateObjectStore` and `getOrCreateActionCache` with one function, `getOrCreateDatabases`. Also re-enable the `CASOptionsTest` unit tests, by using a new function `isOnDiskCASEnabled` to check for on-disk feature, instead of using the macro (which was not defined for that target).
1 parent cfd6add commit cfb3eb8

File tree

14 files changed

+142
-176
lines changed

14 files changed

+142
-176
lines changed

clang/include/clang/Basic/DiagnosticCASKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
let Component = "CAS" in {
1010

1111
def err_builtin_cas_cannot_be_initialized : Error<
12-
"CAS cannot be initialized from '%0' on disk (check -fcas-path)">,
12+
"CAS cannot be initialized from '%0' on disk (check -fcas-path): %1">,
1313
DefaultFatal;
1414
def err_builtin_actioncache_cannot_be_initialized : Error<
1515
"ActionCache cannot be initialized from '%0' on disk (check -fcas-path)">,

clang/include/clang/CAS/CASOptions.h

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@
1414
#ifndef LLVM_CLANG_CAS_CASOPTIONS_H
1515
#define LLVM_CLANG_CAS_CASOPTIONS_H
1616

17-
#include <memory>
17+
#include "llvm/ADT/SmallVector.h"
1818
#include <string>
19-
#include <vector>
2019

2120
namespace llvm {
22-
class Error;
2321
namespace cas {
2422
class ActionCache;
2523
class ObjectStore;
@@ -30,6 +28,9 @@ namespace clang {
3028

3129
class DiagnosticsEngine;
3230

31+
/// Set \p Path to a reasonable default on-disk cache path for the current user.
32+
void getClangDefaultCachePath(llvm::SmallVectorImpl<char> &Path);
33+
3334
/// Base class for options configuring which CAS to use. Separated for the
3435
/// fields where we don't need special move/copy logic.
3536
///
@@ -74,8 +75,8 @@ class CASConfiguration {
7475
/// Options configuring which CAS to use. User-accessible fields should be
7576
/// defined in CASConfiguration to enable caching a CAS instance.
7677
///
77-
/// CASOptions includes \a getOrCreateObjectStore() and \a
78-
/// getOrCreateActionCache() for creating CAS and ActionCache.
78+
/// CASOptions includes \a getOrCreateDatabases() for creating CAS and
79+
/// ActionCache.
7980
///
8081
/// FIXME: The the caching is done here, instead of as a field in \a
8182
/// CompilerInstance, in order to ensure that \a
@@ -84,32 +85,23 @@ class CASConfiguration {
8485
/// it would be better to update all callers and remove it from here.
8586
class CASOptions : public CASConfiguration {
8687
public:
87-
/// Get a CAS defined by the options above. Future calls will return the same
88-
/// CAS instance... unless the configuration has changed, in which case a new
89-
/// one will be created.
90-
///
91-
/// If \p CreateEmptyCASOnFailure, returns an empty in-memory CAS on failure.
92-
/// Else, returns \c nullptr on failure.
93-
std::shared_ptr<llvm::cas::ObjectStore>
94-
getOrCreateObjectStore(DiagnosticsEngine &Diags,
95-
bool CreateEmptyCASOnFailure = false) const;
96-
97-
/// Get a ActionCache defined by the options above. Future calls will return
98-
/// the same ActionCache instance... unless the configuration has changed, in
99-
/// which case a new one will be created.
88+
/// Get a CAS & ActionCache defined by the options above. Future calls will
89+
/// return the same instances... unless the configuration has changed, in
90+
/// which case new ones will be created.
10091
///
101-
/// If \p CreateEmptyCacheOnFailure, returns an empty in-memory ActionCache on
92+
/// If \p CreateEmptyDBsOnFailure, returns empty in-memory databases on
10293
/// failure. Else, returns \c nullptr on failure.
103-
std::shared_ptr<llvm::cas::ActionCache>
104-
getOrCreateActionCache(DiagnosticsEngine &Diags,
105-
bool CreateEmptyCacheOnFailures = false) const;
94+
std::pair<std::shared_ptr<llvm::cas::ObjectStore>,
95+
std::shared_ptr<llvm::cas::ActionCache>>
96+
getOrCreateDatabases(DiagnosticsEngine &Diags,
97+
bool CreateEmptyDBsOnFailure = false) const;
10698

10799
/// Freeze CAS Configuration. Future calls will return the same
108100
/// CAS instance, even if the configuration changes again later.
109101
///
110102
/// The configuration will be wiped out to prevent it being observable or
111103
/// affecting the output of something that takes \a CASOptions as an input.
112-
/// This also "locks in" the return value of \a getOrCreateObjectStore():
104+
/// This also "locks in" the return value of \a getOrCreateDatabases():
113105
/// future calls will not check if the configuration has changed.
114106
void freezeConfig(DiagnosticsEngine &Diags);
115107

clang/include/clang/Frontend/CompilerInstance.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ class CompilerInstance : public ModuleLoader {
186186
/// Force an output buffer.
187187
std::unique_ptr<llvm::raw_pwrite_stream> OutputStream;
188188

189+
void createCASDatabases();
190+
189191
CompilerInstance(const CompilerInstance &) = delete;
190192
void operator=(const CompilerInstance &) = delete;
191193
public:

clang/lib/CAS/CASOptions.cpp

Lines changed: 34 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -11,44 +11,31 @@
1111
#include "clang/Basic/DiagnosticCAS.h"
1212
#include "llvm/CAS/ActionCache.h"
1313
#include "llvm/CAS/ObjectStore.h"
14-
#include "llvm/Support/Error.h"
14+
#include "llvm/Support/Path.h"
1515

1616
using namespace clang;
1717
using namespace llvm::cas;
1818

19-
static std::shared_ptr<llvm::cas::ObjectStore>
20-
createObjectStoreWithoutPath(const CASConfiguration &Config,
21-
DiagnosticsEngine &Diags) {
22-
if (Config.CASPath.empty())
23-
return llvm::cas::createInMemoryCAS();
24-
25-
assert(Config.CASPath == "auto");
26-
// Compute the path.
27-
SmallString<128> Storage;
28-
llvm::cas::getDefaultOnDiskCASPath(Storage);
29-
StringRef Path = Storage;
30-
31-
// FIXME: Pass on the actual error from the CAS.
32-
if (auto MaybeCAS =
33-
llvm::expectedToOptional(llvm::cas::createOnDiskCAS(Path)))
34-
return std::move(*MaybeCAS);
35-
Diags.Report(diag::err_builtin_cas_cannot_be_initialized) << Path;
36-
return nullptr;
19+
void clang::getClangDefaultCachePath(SmallVectorImpl<char> &Path) {
20+
// FIXME: Should this return 'Error' instead of hard-failing?
21+
if (!llvm::sys::path::cache_directory(Path))
22+
llvm::report_fatal_error("cannot get default cache directory");
23+
llvm::sys::path::append(Path, "clang-cache");
3724
}
3825

39-
std::shared_ptr<llvm::cas::ObjectStore>
40-
CASOptions::getOrCreateObjectStore(DiagnosticsEngine &Diags,
41-
bool CreateEmptyCASOnFailure) const {
26+
std::pair<std::shared_ptr<llvm::cas::ObjectStore>,
27+
std::shared_ptr<llvm::cas::ActionCache>>
28+
CASOptions::getOrCreateDatabases(DiagnosticsEngine &Diags,
29+
bool CreateEmptyDBsOnFailure) const {
4230
if (Cache.Config.IsFrozen)
43-
return Cache.CAS;
31+
return {Cache.CAS, Cache.AC};
4432

4533
initCache(Diags);
46-
if (Cache.CAS)
47-
return Cache.CAS;
48-
if (!CreateEmptyCASOnFailure)
49-
return nullptr;
50-
Cache.CAS = llvm::cas::createInMemoryCAS();
51-
return Cache.CAS;
34+
if (!Cache.CAS && CreateEmptyDBsOnFailure)
35+
Cache.CAS = llvm::cas::createInMemoryCAS();
36+
if (!Cache.AC && CreateEmptyDBsOnFailure)
37+
Cache.AC = llvm::cas::createInMemoryActionCache();
38+
return {Cache.CAS, Cache.AC};
5239
}
5340

5441
void CASOptions::freezeConfig(DiagnosticsEngine &Diags) {
@@ -74,45 +61,11 @@ void CASOptions::freezeConfig(DiagnosticsEngine &Diags) {
7461
}
7562
}
7663

77-
static std::shared_ptr<llvm::cas::ActionCache>
78-
createCacheWithoutPath(const CASConfiguration &Config,
79-
DiagnosticsEngine &Diags) {
80-
if (Config.CASPath.empty())
81-
return llvm::cas::createInMemoryActionCache();
82-
83-
assert(Config.CASPath == "auto");
84-
// Compute the path.
85-
std::string Path = getDefaultOnDiskActionCachePath();
86-
87-
// FIXME: Pass on the actual error from the CAS.
88-
if (auto MaybeCache =
89-
llvm::expectedToOptional(llvm::cas::createOnDiskActionCache(Path)))
90-
return std::move(*MaybeCache);
91-
Diags.Report(diag::err_builtin_actioncache_cannot_be_initialized) << Path;
92-
return nullptr;
93-
}
94-
95-
std::shared_ptr<llvm::cas::ActionCache>
96-
CASOptions::getOrCreateActionCache(DiagnosticsEngine &Diags,
97-
bool CreateEmptyOnFailure) const {
98-
if (Cache.Config.IsFrozen)
99-
return Cache.AC;
100-
101-
initCache(Diags);
102-
if (Cache.AC)
103-
return Cache.AC;
104-
if (!CreateEmptyOnFailure)
105-
return nullptr;
106-
107-
Cache.CAS = Cache.CAS ? Cache.CAS : llvm::cas::createInMemoryCAS();
108-
return llvm::cas::createInMemoryActionCache();
109-
}
110-
11164
void CASOptions::ensurePersistentCAS() {
11265
assert(!IsFrozen && "Expected to check for a persistent CAS before freezing");
11366
switch (getKind()) {
11467
case UnknownCAS:
115-
llvm_unreachable("Cannot ensure persistent CAS if it's unknown / frozen");
68+
llvm_unreachable("Cannot ensure persistent CAS if it's unknown / frozen");
11669
case InMemoryCAS:
11770
CASPath = "auto";
11871
break;
@@ -128,16 +81,22 @@ void CASOptions::initCache(DiagnosticsEngine &Diags) const {
12881

12982
Cache.Config = CurrentConfig;
13083
StringRef CASPath = Cache.Config.CASPath;
131-
if (!CASPath.empty() && CASPath != "auto") {
132-
std::pair<std::unique_ptr<ObjectStore>, std::unique_ptr<ActionCache>> DBs;
133-
if (llvm::Error E =
134-
createOnDiskUnifiedCASDatabases(CASPath).moveInto(DBs)) {
135-
Diags.Report(diag::err_builtin_cas_cannot_be_initialized) << CASPath;
136-
return;
137-
}
138-
std::tie(Cache.CAS, Cache.AC) = std::move(DBs);
139-
} else {
140-
Cache.CAS = createObjectStoreWithoutPath(Cache.Config, Diags);
141-
Cache.AC = createCacheWithoutPath(Cache.Config, Diags);
84+
if (CASPath.empty()) {
85+
Cache.CAS = llvm::cas::createInMemoryCAS();
86+
Cache.AC = llvm::cas::createInMemoryActionCache();
87+
return;
88+
}
89+
90+
SmallString<256> PathBuf;
91+
if (CASPath == "auto") {
92+
getClangDefaultCachePath(PathBuf);
93+
CASPath = PathBuf;
94+
}
95+
std::pair<std::unique_ptr<ObjectStore>, std::unique_ptr<ActionCache>> DBs;
96+
if (llvm::Error E = createOnDiskUnifiedCASDatabases(CASPath).moveInto(DBs)) {
97+
Diags.Report(diag::err_builtin_cas_cannot_be_initialized)
98+
<< CASPath << toString(std::move(E));
99+
return;
142100
}
101+
std::tie(Cache.CAS, Cache.AC) = std::move(DBs);
143102
}

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -902,25 +902,24 @@ llvm::vfs::OutputBackend &CompilerInstance::getOrCreateOutputBackend() {
902902
return getOutputBackend();
903903
}
904904

905-
llvm::cas::ObjectStore &CompilerInstance::getOrCreateObjectStore() {
906-
if (CAS)
907-
return *CAS;
908-
909-
// Create a new CAS instance from the CompilerInvocation. Future calls to
905+
void CompilerInstance::createCASDatabases() {
906+
// Create a new CAS databases from the CompilerInvocation. Future calls to
910907
// createFileManager() will use the same CAS.
911-
CAS = getInvocation().getCASOpts().getOrCreateObjectStore(
912-
getDiagnostics(),
913-
/*CreateEmptyCASOnFailure=*/true);
908+
std::tie(CAS, ActionCache) =
909+
getInvocation().getCASOpts().getOrCreateDatabases(
910+
getDiagnostics(),
911+
/*CreateEmptyCASOnFailure=*/true);
912+
}
913+
914+
llvm::cas::ObjectStore &CompilerInstance::getOrCreateObjectStore() {
915+
if (!CAS)
916+
createCASDatabases();
914917
return *CAS;
915918
}
916919

917920
llvm::cas::ActionCache &CompilerInstance::getOrCreateActionCache() {
918-
if (ActionCache)
919-
return *ActionCache;
920-
921-
ActionCache = getInvocation().getCASOpts().getOrCreateActionCache(
922-
getDiagnostics(),
923-
/*CreateEmptyActionCacheOnFailure=*/true);
921+
if (!ActionCache)
922+
createCASDatabases();
924923
return *ActionCache;
925924
}
926925

@@ -2445,4 +2444,4 @@ bool CompileCacheASTReaderHelper::readCASFileSystemRootID(StringRef RootID,
24452444
return true;
24462445
}
24472446
return false;
2448-
}
2447+
}

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,7 +1347,7 @@ createBaseFS(const FileSystemOptions &FSOpts, const FrontendOptions &FEOpts,
13471347
// If no CAS was provided, create one with CASOptions.
13481348
std::shared_ptr<llvm::cas::ObjectStore> CAS = std::move(OverrideCAS);
13491349
if (!CAS)
1350-
CAS = CASOpts.getOrCreateObjectStore(Diags);
1350+
CAS = CASOpts.getOrCreateDatabases(Diags).first;
13511351

13521352
// Helper for creating a valid (but empty) CASFS if an error is encountered.
13531353
auto makeEmptyCASFS = [&CAS]() {
@@ -2988,7 +2988,7 @@ static void determineInputFromIncludeTree(
29882988
Diags.Report(diag::err_fe_unable_to_load_include_tree)
29892989
<< IncludeTreeID << llvm::toString(std::move(E));
29902990
};
2991-
auto CAS = CASOpts.getOrCreateObjectStore(Diags);
2991+
auto CAS = CASOpts.getOrCreateDatabases(Diags).first;
29922992
if (!CAS)
29932993
return;
29942994
auto ID = CAS->parseID(IncludeTreeID);

clang/tools/clang-cas-test/ClangCASTest.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ int main(int Argc, const char **Argv) {
7171
Opts.CASPath = CASPath.empty() ? std::string("auto") : CASPath;
7272

7373
auto CAS =
74-
Opts.getOrCreateObjectStore(*Diags, /*CreateEmptyCASOnFailure=*/false);
74+
Opts.getOrCreateDatabases(*Diags, /*CreateEmptyCASOnFailure=*/false)
75+
.first;
7576
if (!CAS)
7677
return 1;
7778

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,7 @@ llvm::cl::opt<std::string>
224224
llvm::cl::cat(DependencyScannerCategory));
225225

226226
llvm::cl::opt<bool> InMemoryCAS(
227-
"in-memory-cas",
228-
llvm::cl::desc("Use an in-memory CAS instead of on-disk."),
227+
"in-memory-cas", llvm::cl::desc("Use an in-memory CAS instead of on-disk."),
229228
llvm::cl::init(false), llvm::cl::cat(DependencyScannerCategory));
230229

231230
llvm::cl::opt<std::string>
@@ -881,8 +880,7 @@ int main(int argc, const char **argv) {
881880
CASOpts.ensurePersistentCAS();
882881
}
883882

884-
CAS = CASOpts.getOrCreateObjectStore(Diags);
885-
Cache = CASOpts.getOrCreateActionCache(Diags);
883+
std::tie(CAS, Cache) = CASOpts.getOrCreateDatabases(Diags);
886884
if (!CAS)
887885
return 1;
888886
if (Format != ScanningOutputFormat::IncludeTree)

clang/tools/driver/cc1_main.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -486,11 +486,8 @@ Optional<int> CompileJobCache::initialize(CompilerInstance &Clang) {
486486
if (!CacheCompileJob)
487487
return None;
488488

489-
CAS = Invocation.getCASOpts().getOrCreateObjectStore(Diags);
490-
if (!CAS)
491-
return 1; // Exit with error!
492-
Cache = Invocation.getCASOpts().getOrCreateActionCache(Diags);
493-
if (!Cache)
489+
std::tie(CAS, Cache) = Invocation.getCASOpts().getOrCreateDatabases(Diags);
490+
if (!CAS || !Cache)
494491
return 1; // Exit with error!
495492

496493
CompileJobCachingOptions CacheOpts;

clang/tools/driver/cc1depscan_main.cpp

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -612,14 +612,8 @@ int cc1depscan_main(ArrayRef<const char *> Argv, const char *Argv0,
612612
CompilerInvocation::ParseCASArgs(CASOpts, ParsedCC1Args, Diags);
613613
CASOpts.ensurePersistentCAS();
614614

615-
std::shared_ptr<llvm::cas::ObjectStore> CAS =
616-
CASOpts.getOrCreateObjectStore(Diags);
617-
if (!CAS)
618-
return 1;
619-
620-
std::shared_ptr<llvm::cas::ActionCache> Cache =
621-
CASOpts.getOrCreateActionCache(Diags);
622-
if (!Cache)
615+
auto [CAS, Cache] = CASOpts.getOrCreateDatabases(Diags);
616+
if (!CAS || !Cache)
623617
return 1;
624618

625619
if (int Ret = scanAndUpdateCC1(Argv0, CC1Args->getValues(), NewArgs, Diags,
@@ -866,13 +860,11 @@ int ScanServer::listen() {
866860
bool ProduceIncludeTree =
867861
ParsedCASArgs.hasArg(driver::options::OPT_fdepscan_include_tree);
868862

869-
std::shared_ptr<llvm::cas::ObjectStore> CAS =
870-
CASOpts.getOrCreateObjectStore(Diags);
863+
std::shared_ptr<llvm::cas::ObjectStore> CAS;
864+
std::shared_ptr<llvm::cas::ActionCache> Cache;
865+
std::tie(CAS, Cache) = CASOpts.getOrCreateDatabases(Diags);
871866
if (!CAS)
872867
reportError("cannot create CAS");
873-
874-
std::shared_ptr<llvm::cas::ActionCache> Cache =
875-
CASOpts.getOrCreateActionCache(Diags);
876868
if (!Cache)
877869
reportError("cannot create ActionCache");
878870

0 commit comments

Comments
 (0)