Skip to content

Commit 3782f0c

Browse files
authored
Merge pull request #7304 from akyrtzi/akyrtzi/pr/major-libclang-cas-queries
[stable/20230725][CAS/libclang] Add libclang APIs for handling and replaying cached compilations
2 parents 50ea21c + c2aa9e6 commit 3782f0c

27 files changed

+1124
-64
lines changed

clang/include/clang-c/CAS.h

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#ifndef LLVM_CLANG_C_CAS_H
2121
#define LLVM_CLANG_C_CAS_H
2222

23+
#include "clang-c/CXErrorCode.h"
2324
#include "clang-c/CXString.h"
2425
#include "clang-c/Platform.h"
2526

@@ -53,6 +54,23 @@ typedef struct CXOpaqueCASObjectStore *CXCASObjectStore;
5354
*/
5455
typedef struct CXOpaqueCASActionCache *CXCASActionCache;
5556

57+
typedef struct CXOpaqueCASObject *CXCASObject;
58+
59+
/**
60+
* Result of \c clang_experimental_cas_getCachedCompilation.
61+
*/
62+
typedef struct CXOpaqueCASCachedCompilation *CXCASCachedCompilation;
63+
64+
/**
65+
* Result of \c clang_experimental_cas_replayCompilation.
66+
*/
67+
typedef struct CXOpaqueCASReplayResult *CXCASReplayResult;
68+
69+
/**
70+
* Used for cancelling asynchronous actions.
71+
*/
72+
typedef struct CXOpaqueCASCancellationToken *CXCASCancellationToken;
73+
5674
/**
5775
* Create a \c CXCASOptions object.
5876
*/
@@ -99,6 +117,181 @@ clang_experimental_cas_Databases_create(CXCASOptions Opts, CXString *Error);
99117
*/
100118
CINDEX_LINKAGE void clang_experimental_cas_Databases_dispose(CXCASDatabases);
101119

120+
/**
121+
* Loads an object using its printed \p CASID.
122+
*
123+
* \param CASID The printed CASID string for the object.
124+
* \param[out] OutError The error object to pass back to client (if any).
125+
* If non-null the object must be disposed using \c clang_Error_dispose.
126+
*
127+
* \returns The resulting object, or null if the object was not found or an
128+
* error occurred. The object should be disposed using
129+
* \c clang_experimental_cas_CASObject_dispose.
130+
*/
131+
CINDEX_LINKAGE CXCASObject clang_experimental_cas_loadObjectByString(
132+
CXCASDatabases, const char *CASID, CXError *OutError);
133+
134+
/**
135+
* Asynchronous version of \c clang_experimental_cas_loadObjectByString.
136+
*
137+
* \param CASID The printed CASID string for the object.
138+
* \param Ctx opaque value to pass to the callback.
139+
* \param Callback receives a \c CXCASObject, or \c CXError if an error occurred
140+
* or both NULL if the object was not found or the call was cancelled.
141+
* The objects should be disposed with
142+
* \c clang_experimental_cas_CASObject_dispose or \c clang_Error_dispose.
143+
* \param[out] OutToken if non-null receives a \c CXCASCancellationToken that
144+
* can be used to cancel the call using
145+
* \c clang_experimental_cas_CancellationToken_cancel. The object should be
146+
* disposed using \c clang_experimental_cas_CancellationToken_dispose.
147+
*/
148+
CINDEX_LINKAGE void clang_experimental_cas_loadObjectByString_async(
149+
CXCASDatabases, const char *CASID, void *Ctx,
150+
void (*Callback)(void *Ctx, CXCASObject, CXError),
151+
CXCASCancellationToken *OutToken);
152+
153+
/**
154+
* Dispose of a \c CXCASObject object.
155+
*/
156+
CINDEX_LINKAGE void clang_experimental_cas_CASObject_dispose(CXCASObject);
157+
158+
/**
159+
* Looks up a cache key and returns the associated set of compilation output IDs
160+
*
161+
* \param CacheKey The printed compilation cache key string.
162+
* \param Globally if true it is a hint to the underlying CAS implementation
163+
* that the lookup is profitable to be done on a distributed caching level, not
164+
* just locally.
165+
* \param[out] OutError The error object to pass back to client (if any).
166+
* If non-null the object must be disposed using \c clang_Error_dispose.
167+
*
168+
* \returns The resulting object, or null if the cache key was not found or an
169+
* error occurred. The object should be disposed using
170+
* \c clang_experimental_cas_CachedCompilation_dispose.
171+
*/
172+
CINDEX_LINKAGE CXCASCachedCompilation
173+
clang_experimental_cas_getCachedCompilation(CXCASDatabases,
174+
const char *CacheKey, bool Globally,
175+
CXError *OutError);
176+
177+
/**
178+
* Asynchronous version of \c clang_experimental_cas_getCachedCompilation.
179+
*
180+
* \param CacheKey The printed compilation cache key string.
181+
* \param Globally if true it is a hint to the underlying CAS implementation
182+
* that the lookup is profitable to be done on a distributed caching level, not
183+
* just locally.
184+
* \param Ctx opaque value to pass to the callback.
185+
* \param Callback receives a \c CXCASCachedCompilation, or \c CXError if an
186+
* error occurred or both NULL if the object was not found or the call was
187+
* cancelled. The objects should be disposed with
188+
* \c clang_experimental_cas_CachedCompilation_dispose or \c clang_Error_dispose
189+
* \param[out] OutToken if non-null receives a \c CXCASCancellationToken that
190+
* can be used to cancel the call using
191+
* \c clang_experimental_cas_CancellationToken_cancel. The object should be
192+
* disposed using \c clang_experimental_cas_CancellationToken_dispose.
193+
*/
194+
CINDEX_LINKAGE void clang_experimental_cas_getCachedCompilation_async(
195+
CXCASDatabases, const char *CacheKey, bool Globally, void *Ctx,
196+
void (*Callback)(void *Ctx, CXCASCachedCompilation, CXError),
197+
CXCASCancellationToken *OutToken);
198+
199+
/**
200+
* Dispose of a \c CXCASCachedCompilation object.
201+
*/
202+
CINDEX_LINKAGE void
203+
clang_experimental_cas_CachedCompilation_dispose(CXCASCachedCompilation);
204+
205+
/**
206+
* \returns number of compilation outputs.
207+
*/
208+
CINDEX_LINKAGE size_t clang_experimental_cas_CachedCompilation_getNumOutputs(
209+
CXCASCachedCompilation);
210+
211+
/**
212+
* \returns the compilation output name given the index via \p OutputIdx.
213+
*/
214+
CINDEX_LINKAGE CXString clang_experimental_cas_CachedCompilation_getOutputName(
215+
CXCASCachedCompilation, size_t OutputIdx);
216+
217+
/**
218+
* \returns the compilation output printed CASID given the index via
219+
* \p OutputIdx.
220+
*/
221+
CINDEX_LINKAGE CXString
222+
clang_experimental_cas_CachedCompilation_getOutputCASIDString(
223+
CXCASCachedCompilation, size_t OutputIdx);
224+
225+
/**
226+
* \returns whether the compilation output data exist in the local CAS given the
227+
* index via \p OutputIdx.
228+
*/
229+
CINDEX_LINKAGE bool
230+
clang_experimental_cas_CachedCompilation_isOutputMaterialized(
231+
CXCASCachedCompilation, size_t OutputIdx);
232+
233+
/**
234+
* If distributed caching is available it uploads the compilation outputs and
235+
* the association of key <-> outputs to the distributed cache.
236+
* This allows separating the task of computing the compilation outputs and
237+
* storing them in the local cache, from the task of "uploading" them.
238+
*
239+
* \param Ctx opaque value to pass to the callback.
240+
* \param Callback receives a \c CXError if an error occurred. The error will be
241+
* NULL if the call was successful or cancelled. The error should be disposed
242+
* via \c clang_Error_dispose.
243+
* \param[out] OutToken if non-null receives a \c CXCASCancellationToken that
244+
* can be used to cancel the call using
245+
* \c clang_experimental_cas_CancellationToken_cancel. The object should be
246+
* disposed using \c clang_experimental_cas_CancellationToken_dispose.
247+
*/
248+
CINDEX_LINKAGE void clang_experimental_cas_CachedCompilation_makeGlobal(
249+
CXCASCachedCompilation, void *Ctx, void (*Callback)(void *Ctx, CXError),
250+
CXCASCancellationToken *OutToken);
251+
252+
/**
253+
* Replays a cached compilation by writing the cached outputs to the filesystem
254+
* and/or stderr based on the given compilation arguments.
255+
*
256+
* \param argc number of compilation arguments.
257+
* \param argv array of compilation arguments.
258+
* \param WorkingDirectory working directory to use, can be NULL.
259+
* \param reserved for future use, caller must pass NULL.
260+
* \param[out] OutError The error object to pass back to client (if any).
261+
* If non-null the object must be disposed using \c clang_Error_dispose.
262+
*
263+
* \returns a \c CXCASReplayResult object or NULL if an error occurred or a
264+
* compilation output was not found in the CAS. The object should be disposed
265+
* via \c clang_experimental_cas_ReplayResult_dispose.
266+
*/
267+
CINDEX_LINKAGE CXCASReplayResult clang_experimental_cas_replayCompilation(
268+
CXCASCachedCompilation, int argc, const char *const *argv,
269+
const char *WorkingDirectory, void *reserved, CXError *OutError);
270+
271+
/**
272+
* Dispose of a \c CXCASReplayResult object.
273+
*/
274+
CINDEX_LINKAGE void
275+
clang_experimental_cas_ReplayResult_dispose(CXCASReplayResult);
276+
277+
/**
278+
* Get the diagnostic text of a replayed cached compilation.
279+
*/
280+
CINDEX_LINKAGE
281+
CXString clang_experimental_cas_ReplayResult_getStderr(CXCASReplayResult);
282+
283+
/**
284+
* Cancel an asynchronous CAS-related action.
285+
*/
286+
CINDEX_LINKAGE void
287+
clang_experimental_cas_CancellationToken_cancel(CXCASCancellationToken);
288+
289+
/**
290+
* Dispose of a \c CXCASCancellationToken object.
291+
*/
292+
CINDEX_LINKAGE void
293+
clang_experimental_cas_CancellationToken_dispose(CXCASCancellationToken);
294+
102295
/**
103296
* Dispose of a \c CXCASObjectStore object.
104297
*/

clang/include/clang-c/CXErrorCode.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,26 @@ enum CXErrorCode {
7474
CXError_RefactoringNameInvalid = 7
7575
};
7676

77+
/**
78+
* Represents an error with error code and description string.
79+
*/
80+
typedef struct CXOpaqueError *CXError;
81+
82+
/**
83+
* \returns the error code.
84+
*/
85+
CINDEX_LINKAGE enum CXErrorCode clang_Error_getCode(CXError);
86+
87+
/**
88+
* \returns the error description string.
89+
*/
90+
CINDEX_LINKAGE const char *clang_Error_getDescription(CXError);
91+
92+
/**
93+
* Dispose of a \c CXError object.
94+
*/
95+
CINDEX_LINKAGE void clang_Error_dispose(CXError);
96+
7797
LLVM_CLANG_C_EXTERN_C_END
7898

7999
#endif

clang/include/clang-c/Dependencies.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,14 @@ CINDEX_LINKAGE void
210210
clang_experimental_DependencyScannerServiceOptions_setCASDatabases(
211211
CXDependencyScannerServiceOptions Opts, CXCASDatabases);
212212

213+
/**
214+
* Specify the specific CAS options for the scanner to use for the produced
215+
* compiler arguments.
216+
*/
217+
CINDEX_LINKAGE void
218+
clang_experimental_DependencyScannerServiceOptions_setCASOptions(
219+
CXDependencyScannerServiceOptions Opts, CXCASOptions);
220+
213221
/**
214222
* Specify a \c CXCASObjectStore in the given options. If an object store and
215223
* action cache are available, the scanner will produce cached commands.

clang/include/clang/Frontend/CompileJobCache.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace clang {
1515

1616
class CompilerInstance;
17+
class CompilerInvocation;
1718
class DiagnosticsEngine;
1819

1920
// Manage caching and replay of compile jobs.
@@ -80,6 +81,13 @@ class CompileJobCache {
8081
/// \returns true if finished successfully.
8182
bool finishComputedResult(CompilerInstance &Clang, bool Success);
8283

84+
static llvm::Expected<std::optional<int>> replayCachedResult(
85+
std::shared_ptr<CompilerInvocation> Invok,
86+
const llvm::cas::CASID &CacheKey,
87+
cas::CompileJobCacheResult &CachedResult, SmallVectorImpl<char> &DiagText,
88+
bool WriteOutputAsCASID = false, bool UseCASBackend = false,
89+
std::optional<llvm::cas::CASID> *MCOutputID = nullptr);
90+
8391
class CachingOutputs;
8492

8593
private:

clang/include/clang/Frontend/CompileJobCacheResult.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class CompileJobCacheResult : public ObjectProxy {
5555

5656
size_t getNumOutputs() const;
5757

58+
Output getOutput(size_t I) const;
59+
5860
/// Retrieves a specific output specified by \p Kind, if it exists.
5961
std::optional<Output> getOutput(OutputKind Kind) const;
6062

0 commit comments

Comments
 (0)