Skip to content

Commit 9ca875d

Browse files
committed
[cas/libclang] Enhance the CAS-related libclang APIs for CAS configuration
The main changes are: * Added `CXCASOptions` which is a wrapper for `clang::CASOptions` * Added `CXCASDatabases` which encapsulates `ObjectStore` and `ActionCache` instances created from a particular `CXCASOptions` configuration. * Added `clang_experimental_DependencyScannerServiceOptions_setCASDatabases` for configuring a `CXDependencyScannerServiceOptions` object for caching functionality. * Simplified the setup by only needing the client to call `clang_experimental_cas_Options_setOnDiskPath` for configuring the path for on-disk databases. This scheme deprecates: * `clang_experimental_cas_OnDiskActionCache_create` * `clang_experimental_cas_OnDiskObjectStore_create` * `clang_experimental_DependencyScannerServiceOptions_setObjectStore` * `clang_experimental_DependencyScannerServiceOptions_setActionCache` The benefits of this scheme are: * It makes it explicit that the libclang client gets instances of `ObjectStore` and `ActionCache` the same way as how the `cc1` invocation will create them (both using the `clang::CASOptions` mechanism). * Improved flexibility; adding CAS configurations only needs adding new `clang_experimental_cas_Options_*` functions. (cherry picked from commit e80aa81)
1 parent 6d7998b commit 9ca875d

File tree

8 files changed

+165
-46
lines changed

8 files changed

+165
-46
lines changed

clang/include/clang-c/CAS.h

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ extern "C" {
3232
* @{
3333
*/
3434

35+
/**
36+
* Configuration options for ObjectStore and ActionCache.
37+
*/
38+
typedef struct CXOpaqueCASOptions *CXCASOptions;
39+
40+
/**
41+
* Encapsulates instances of ObjectStore and ActionCache, created from a
42+
* particular configuration of \p CXCASOptions.
43+
*/
44+
typedef struct CXOpaqueCASDatabases *CXCASDatabases;
45+
3546
/**
3647
* Content-addressable storage for objects.
3748
*/
@@ -42,6 +53,39 @@ typedef struct CXOpaqueCASObjectStore *CXCASObjectStore;
4253
*/
4354
typedef struct CXOpaqueCASActionCache *CXCASActionCache;
4455

56+
/**
57+
* Create a \c CXCASOptions object.
58+
*/
59+
CINDEX_LINKAGE CXCASOptions clang_experimental_cas_Options_create(void);
60+
61+
/**
62+
* Dispose of a \c CXCASOptions object.
63+
*/
64+
CINDEX_LINKAGE void clang_experimental_cas_Options_dispose(CXCASOptions);
65+
66+
/**
67+
* Configure the file path to use for on-disk CAS/cache instances.
68+
*/
69+
CINDEX_LINKAGE void
70+
clang_experimental_cas_Options_setOnDiskPath(CXCASOptions, const char *Path);
71+
72+
/**
73+
* Creates instances for a CAS object store and action cache based on the
74+
* configuration of a \p CXCASOptions.
75+
*
76+
* \param Opts configuration options.
77+
* \param[out] Error The error string to pass back to client (if any).
78+
*
79+
* \returns The resulting instances object, or null if there was an error.
80+
*/
81+
CINDEX_LINKAGE CXCASDatabases
82+
clang_experimental_cas_Databases_create(CXCASOptions Opts, CXString *Error);
83+
84+
/**
85+
* Dispose of a \c CXCASDatabases object.
86+
*/
87+
CINDEX_LINKAGE void clang_experimental_cas_Databases_dispose(CXCASDatabases);
88+
4589
/**
4690
* Dispose of a \c CXCASObjectStore object.
4791
*/
@@ -56,27 +100,29 @@ clang_experimental_cas_ActionCache_dispose(CXCASActionCache Cache);
56100

57101
/**
58102
* Gets or creates a persistent on-disk CAS object store at \p Path.
103+
* Deprecated, use \p clang_experimental_cas_Databases_create() instead.
59104
*
60105
* \param Path The path to locate the object store.
61106
* \param[out] Error The error string to pass back to client (if any).
62107
*
63108
* \returns The resulting object store, or null if there was an error.
64109
*/
65-
CINDEX_LINKAGE CXCASObjectStore
66-
clang_experimental_cas_OnDiskObjectStore_create(
67-
const char *Path, CXString *Error);
110+
CINDEX_DEPRECATED CINDEX_LINKAGE CXCASObjectStore
111+
clang_experimental_cas_OnDiskObjectStore_create(const char *Path,
112+
CXString *Error);
68113

69114
/**
70115
* Gets or creates a persistent on-disk action cache at \p Path.
116+
* Deprecated, use \p clang_experimental_cas_Databases_create() instead.
71117
*
72118
* \param Path The path to locate the object store.
73119
* \param[out] Error The error string to pass back to client (if any).
74120
*
75121
* \returns The resulting object store, or null if there was an error.
76122
*/
77-
CINDEX_LINKAGE CXCASActionCache
78-
clang_experimental_cas_OnDiskActionCache_create(
79-
const char *Path, CXString *Error);
123+
CINDEX_DEPRECATED CINDEX_LINKAGE CXCASActionCache
124+
clang_experimental_cas_OnDiskActionCache_create(const char *Path,
125+
CXString *Error);
80126

81127
/**
82128
* @}

clang/include/clang-c/Dependencies.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,19 +197,33 @@ CINDEX_LINKAGE void
197197
clang_experimental_DependencyScannerServiceOptions_setDependencyMode(
198198
CXDependencyScannerServiceOptions Opts, CXDependencyMode Mode);
199199

200+
/**
201+
* Specify the object store and action cache databases in the given options.
202+
* With this set, the scanner will produce cached commands.
203+
*/
204+
CINDEX_LINKAGE void
205+
clang_experimental_DependencyScannerServiceOptions_setCASDatabases(
206+
CXDependencyScannerServiceOptions Opts, CXCASDatabases);
207+
200208
/**
201209
* Specify a \c CXCASObjectStore in the given options. If an object store and
202210
* action cache are available, the scanner will produce cached commands.
211+
* Deprecated, use
212+
* \p clang_experimental_DependencyScannerServiceOptions_setCASDatabases()
213+
* instead.
203214
*/
204-
CINDEX_LINKAGE void
215+
CINDEX_DEPRECATED CINDEX_LINKAGE void
205216
clang_experimental_DependencyScannerServiceOptions_setObjectStore(
206217
CXDependencyScannerServiceOptions Opts, CXCASObjectStore CAS);
207218

208219
/**
209220
* Specify a \c CXCASActionCache in the given options. If an object store and
210221
* action cache are available, the scanner will produce cached commands.
222+
* Deprecated, use
223+
* \p clang_experimental_DependencyScannerServiceOptions_setCASDatabases()
224+
* instead.
211225
*/
212-
CINDEX_LINKAGE void
226+
CINDEX_DEPRECATED CINDEX_LINKAGE void
213227
clang_experimental_DependencyScannerServiceOptions_setActionCache(
214228
CXDependencyScannerServiceOptions Opts, CXCASActionCache Cache);
215229

clang/test/Index/Core/scan-deps-cas.m

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// RUN: rm -rf %t.mcp %t
22
// RUN: echo %S > %t.result
33
//
4-
// RUN: c-index-test core --scan-deps %S -output-dir=%t \
5-
// RUN: -cas-path %t/cas -action-cache-path %t/cache \
4+
// RUN: c-index-test core --scan-deps %S -output-dir=%t -cas-path %t/cas \
65
// RUN: -- %clang -c -I %S/Inputs/module \
76
// RUN: -fmodules -fmodules-cache-path=%t.mcp \
87
// RUN: -o FoE.o -x objective-c %s >> %t.result

clang/tools/c-index-test/core_main.cpp

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,7 @@ static cl::list<std::string> DependencyTargets(
138138
"dependency-target",
139139
cl::desc("module builds should use the given dependency target(s)"));
140140
static llvm::cl::opt<std::string>
141-
CASPath("cas-path", llvm::cl::desc("Path for on-disk CAS."));
142-
static llvm::cl::opt<std::string>
143-
CachePath("action-cache-path",
144-
llvm::cl::desc("Path for on-disk action cache."));
141+
CASPath("cas-path", llvm::cl::desc("Path for on-disk CAS/cache."));
145142
}
146143
} // anonymous namespace
147144

@@ -684,8 +681,7 @@ static int scanDeps(ArrayRef<const char *> Args, std::string WorkingDirectory,
684681
bool SerializeDiags, bool DependencyFile,
685682
ArrayRef<std::string> DepTargets, std::string OutputPath,
686683
Optional<std::string> CASPath,
687-
Optional<std::string> CachePath,
688-
Optional<std::string> ModuleName = None) {
684+
Optional<std::string> ModuleName = std::nullopt) {
689685
CXDependencyScannerServiceOptions Opts =
690686
clang_experimental_DependencyScannerServiceOptions_create();
691687
auto CleanupOpts = llvm::make_scope_exit([&] {
@@ -696,32 +692,22 @@ static int scanDeps(ArrayRef<const char *> Args, std::string WorkingDirectory,
696692

697693
CXString Error;
698694
if (CASPath) {
699-
CXCASObjectStore CAS = clang_experimental_cas_OnDiskObjectStore_create(
700-
CASPath->c_str(), &Error);
701-
auto CleanupCache = llvm::make_scope_exit(
702-
[&] { clang_experimental_cas_ObjectStore_dispose(CAS); });
703-
if (!CAS) {
704-
llvm::errs() << "error: failed to create ObjectStore\n";
695+
CXCASOptions CASOpts = clang_experimental_cas_Options_create();
696+
auto CleanupCASOpts = llvm::make_scope_exit(
697+
[&] { clang_experimental_cas_Options_dispose(CASOpts); });
698+
clang_experimental_cas_Options_setOnDiskPath(CASOpts, CASPath->c_str());
699+
CXCASDatabases DBs =
700+
clang_experimental_cas_Databases_create(CASOpts, &Error);
701+
auto CleanupCaches = llvm::make_scope_exit(
702+
[&] { clang_experimental_cas_Databases_dispose(DBs); });
703+
if (!DBs) {
704+
llvm::errs() << "error: failed to create cache instances\n";
705705
llvm::errs() << clang_getCString(Error) << "\n";
706706
clang_disposeString(Error);
707707
return 1;
708708
}
709-
clang_experimental_DependencyScannerServiceOptions_setObjectStore(Opts,
710-
CAS);
711-
if (CachePath) {
712-
CXCASActionCache Cache = clang_experimental_cas_OnDiskActionCache_create(
713-
CachePath->c_str(), &Error);
714-
auto CleanupCache = llvm::make_scope_exit(
715-
[&] { clang_experimental_cas_ActionCache_dispose(Cache); });
716-
if (!Cache) {
717-
llvm::errs() << "error: failed to create ActionCache\n";
718-
llvm::errs() << clang_getCString(Error) << "\n";
719-
clang_disposeString(Error);
720-
return 1;
721-
}
722-
clang_experimental_DependencyScannerServiceOptions_setActionCache(Opts,
723-
Cache);
724-
}
709+
clang_experimental_DependencyScannerServiceOptions_setCASDatabases(Opts,
710+
DBs);
725711
}
726712

727713
CXDependencyScannerService Service =
@@ -1146,11 +1132,9 @@ int indextest_core_main(int argc, const char **argv) {
11461132
return aggregateDataAsJSON(storePath, PathRemapper, OS);
11471133
}
11481134

1149-
Optional<std::string> CASPath =
1150-
options::CASPath.empty() ? None : Optional<std::string>(options::CASPath);
1151-
Optional<std::string> CachePath =
1152-
options::CachePath.empty() ? None
1153-
: Optional<std::string>(options::CachePath);
1135+
Optional<std::string> CASPath = options::CASPath.empty()
1136+
? std::nullopt
1137+
: Optional<std::string>(options::CASPath);
11541138

11551139
if (options::Action == ActionType::ScanDeps) {
11561140
if (options::InputFiles.empty()) {
@@ -1159,7 +1143,7 @@ int indextest_core_main(int argc, const char **argv) {
11591143
}
11601144
return scanDeps(CompArgs, options::InputFiles[0], options::SerializeDiags,
11611145
options::DependencyFile, options::DependencyTargets,
1162-
options::OutputDir, CASPath, CachePath);
1146+
options::OutputDir, CASPath);
11631147
}
11641148

11651149
if (options::Action == ActionType::ScanDepsByModuleName) {
@@ -1174,8 +1158,7 @@ int indextest_core_main(int argc, const char **argv) {
11741158
}
11751159
return scanDeps(CompArgs, options::InputFiles[0], options::SerializeDiags,
11761160
options::DependencyFile, options::DependencyTargets,
1177-
options::OutputDir, CASPath, CachePath,
1178-
options::ModuleName);
1161+
options::OutputDir, CASPath, options::ModuleName);
11791162
}
11801163

11811164
if (options::Action == ActionType::WatchDir) {

clang/tools/libclang/CASUtils.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "clang-c/CAS.h"
1313
#include "clang/Basic/LLVM.h"
14+
#include "clang/CAS/CASOptions.h"
1415
#include "llvm/CAS/ActionCache.h"
1516
#include "llvm/CAS/ObjectStore.h"
1617
#include "llvm/Support/CBindingWrapping.h"
@@ -19,6 +20,12 @@
1920
namespace clang {
2021
namespace cas {
2122

23+
struct WrappedCASDatabases {
24+
CASOptions CASOpts;
25+
std::shared_ptr<cas::ObjectStore> CAS;
26+
std::shared_ptr<cas::ActionCache> Cache;
27+
};
28+
2229
struct WrappedObjectStore {
2330
std::shared_ptr<ObjectStore> CAS;
2431
std::string CASPath;
@@ -29,6 +36,8 @@ struct WrappedActionCache {
2936
std::string CachePath;
3037
};
3138

39+
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(CASOptions, CXCASOptions)
40+
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(WrappedCASDatabases, CXCASDatabases)
3241
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(WrappedObjectStore, CXCASObjectStore)
3342
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(WrappedActionCache, CXCASActionCache)
3443

clang/tools/libclang/CCAS.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,66 @@
1313

1414
#include "clang/Basic/LLVM.h"
1515
#include "clang/CAS/CASOptions.h"
16+
#include "clang/Frontend/TextDiagnosticPrinter.h"
1617
#include "llvm/CAS/ActionCache.h"
1718
#include "llvm/CAS/ObjectStore.h"
19+
#include "llvm/Support/Path.h"
1820

1921
using namespace clang;
2022
using namespace clang::cas;
2123

24+
CXCASOptions clang_experimental_cas_Options_create(void) {
25+
return wrap(new CASOptions());
26+
}
27+
28+
void clang_experimental_cas_Options_dispose(CXCASOptions Opts) {
29+
delete unwrap(Opts);
30+
}
31+
32+
void clang_experimental_cas_Options_setOnDiskPath(CXCASOptions COpts,
33+
const char *Path) {
34+
CASOptions &Opts = *unwrap(COpts);
35+
SmallString<256> PathBuf;
36+
PathBuf = Path;
37+
llvm::sys::path::append(PathBuf, "cas");
38+
Opts.CASPath = std::string(PathBuf);
39+
llvm::sys::path::remove_filename(PathBuf);
40+
llvm::sys::path::append(PathBuf, "cache");
41+
Opts.CachePath = std::string(PathBuf);
42+
}
43+
44+
CXCASDatabases clang_experimental_cas_Databases_create(CXCASOptions COpts,
45+
CXString *Error) {
46+
CASOptions &Opts = *unwrap(COpts);
47+
48+
SmallString<128> DiagBuf;
49+
llvm::raw_svector_ostream OS(DiagBuf);
50+
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
51+
TextDiagnosticPrinter DiagPrinter(OS, DiagOpts.get());
52+
DiagnosticsEngine Diags(
53+
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts.get(),
54+
&DiagPrinter, /*ShouldOwnClient=*/false);
55+
56+
auto CAS = Opts.getOrCreateObjectStore(Diags);
57+
if (!CAS) {
58+
if (Error)
59+
*Error = cxstring::createDup(OS.str());
60+
return nullptr;
61+
}
62+
auto Cache = Opts.getOrCreateActionCache(Diags);
63+
if (!Cache) {
64+
if (Error)
65+
*Error = cxstring::createDup(OS.str());
66+
return nullptr;
67+
}
68+
69+
return wrap(new WrappedCASDatabases{Opts, std::move(CAS), std::move(Cache)});
70+
}
71+
72+
void clang_experimental_cas_Databases_dispose(CXCASDatabases CDBs) {
73+
delete unwrap(CDBs);
74+
}
75+
2276
void clang_experimental_cas_ObjectStore_dispose(CXCASObjectStore CAS) {
2377
delete unwrap(CAS);
2478
}

clang/tools/libclang/CDependencies.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ void clang_experimental_DependencyScannerServiceOptions_setDependencyMode(
9696
unwrap(Opts)->Format = unwrap(Mode);
9797
}
9898

99+
void clang_experimental_DependencyScannerServiceOptions_setCASDatabases(
100+
CXDependencyScannerServiceOptions Opts, CXCASDatabases CDBs) {
101+
cas::WrappedCASDatabases &DBs = *cas::unwrap(CDBs);
102+
unwrap(Opts)->CASOpts = DBs.CASOpts;
103+
unwrap(Opts)->CAS = DBs.CAS;
104+
unwrap(Opts)->Cache = DBs.Cache;
105+
}
106+
99107
void clang_experimental_DependencyScannerServiceOptions_setObjectStore(
100108
CXDependencyScannerServiceOptions Opts, CXCASObjectStore CAS) {
101109
unwrap(Opts)->CAS = cas::unwrap(CAS)->CAS;

clang/tools/libclang/libclang.map

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,13 +472,19 @@ LLVM_13 {
472472
LLVM_16 {
473473
global:
474474
clang_experimental_cas_ActionCache_dispose;
475+
clang_experimental_cas_Databases_create;
476+
clang_experimental_cas_Databases_dispose;
475477
clang_experimental_cas_ObjectStore_dispose;
476478
clang_experimental_cas_OnDiskActionCache_create;
477479
clang_experimental_cas_OnDiskObjectStore_create;
480+
clang_experimental_cas_Options_create;
481+
clang_experimental_cas_Options_dispose;
482+
clang_experimental_cas_Options_setOnDiskPath;
478483
clang_experimental_DependencyScannerService_create_v1;
479484
clang_experimental_DependencyScannerServiceOptions_create;
480485
clang_experimental_DependencyScannerServiceOptions_dispose;
481486
clang_experimental_DependencyScannerServiceOptions_setActionCache;
487+
clang_experimental_DependencyScannerServiceOptions_setCASDatabases;
482488
clang_experimental_DependencyScannerServiceOptions_setDependencyMode;
483489
clang_experimental_DependencyScannerServiceOptions_setObjectStore;
484490
clang_experimental_DependencyScannerWorker_getFileDependencies_v5;

0 commit comments

Comments
 (0)