@@ -42,7 +42,8 @@ enum class SwiftCacheToolAction {
42
42
Invalid,
43
43
PrintBaseKey,
44
44
PrintOutputKeys,
45
- ValidateOutputs
45
+ ValidateOutputs,
46
+ RenderDiags
46
47
};
47
48
48
49
struct OutputEntry {
@@ -134,11 +135,13 @@ class SwiftCacheToolInvocation {
134
135
.Case (" print-base-key" , SwiftCacheToolAction::PrintBaseKey)
135
136
.Case (" print-output-keys" , SwiftCacheToolAction::PrintOutputKeys)
136
137
.Case (" validate-outputs" , SwiftCacheToolAction::ValidateOutputs)
138
+ .Case (" render-diags" , SwiftCacheToolAction::RenderDiags)
137
139
.Default (SwiftCacheToolAction::Invalid);
138
140
139
141
if (ActionKind == SwiftCacheToolAction::Invalid) {
140
- llvm::errs () << " Invalid option specified for -cache-tool-action: "
141
- << " use print-base-key|print-output-keys|validate-outputs\n " ;
142
+ llvm::errs ()
143
+ << " Invalid option specified for -cache-tool-action: "
144
+ << " print-base-key|print-output-keys|validate-outputs|render-diags\n " ;
142
145
return 1 ;
143
146
}
144
147
@@ -153,6 +156,8 @@ class SwiftCacheToolInvocation {
153
156
return printOutputKeys ();
154
157
case SwiftCacheToolAction::ValidateOutputs:
155
158
return validateOutputs ();
159
+ case SwiftCacheToolAction::RenderDiags:
160
+ return renderDiags ();
156
161
case SwiftCacheToolAction::Invalid:
157
162
return 0 ; // No action. Probably just print help. Return.
158
163
}
@@ -202,6 +207,12 @@ class SwiftCacheToolInvocation {
202
207
return true ;
203
208
}
204
209
210
+ // Disable diagnostic caching from this fake instance.
211
+ if (auto *CDP = Instance.getCachingDiagnosticsProcessor ()) {
212
+ CDP->endCaptureDiagnostics ();
213
+ CDP->setDisableCapture ();
214
+ }
215
+
205
216
return false ;
206
217
}
207
218
@@ -233,6 +244,7 @@ class SwiftCacheToolInvocation {
233
244
234
245
int printOutputKeys ();
235
246
int validateOutputs ();
247
+ int renderDiags ();
236
248
};
237
249
238
250
} // end anonymous namespace
@@ -283,6 +295,10 @@ int SwiftCacheToolInvocation::printOutputKeys() {
283
295
Invocation.getFrontendOptions ().InputsAndOutputs .getAllInputs (),
284
296
addFromInputFile);
285
297
298
+ // Add diagnostics file.
299
+ addOutputKey (" <cached-diagnostics>" , file_types::ID::TY_CachedDiagnostics,
300
+ " <cached-diagnostics>" );
301
+
286
302
if (hasError)
287
303
return 1 ;
288
304
@@ -301,6 +317,26 @@ int SwiftCacheToolInvocation::printOutputKeys() {
301
317
return 0 ;
302
318
}
303
319
320
+ static llvm::Expected<llvm::json::Array>
321
+ readOutputEntriesFromFile (StringRef Path) {
322
+ auto JSONContent = llvm::MemoryBuffer::getFile (Path);
323
+ if (!JSONContent)
324
+ return llvm::createStringError (JSONContent.getError (),
325
+ " failed to read input file" );
326
+
327
+ auto JSONValue = llvm::json::parse ((*JSONContent)->getBuffer ());
328
+ if (!JSONValue)
329
+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
330
+ " failed to parse input file as JSON" );
331
+
332
+ auto Keys = JSONValue->getAsArray ();
333
+ if (!Keys)
334
+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
335
+ " invalid JSON format for input file" );
336
+
337
+ return *Keys;
338
+ }
339
+
304
340
int SwiftCacheToolInvocation::validateOutputs () {
305
341
auto DB = llvm::cas::createOnDiskUnifiedCASDatabases (CASPath);
306
342
if (!DB)
@@ -310,22 +346,10 @@ int SwiftCacheToolInvocation::validateOutputs() {
310
346
Instance.getDiags ().addConsumer (PDC);
311
347
312
348
auto validateCacheKeysFromFile = [&](const std::string &Path) {
313
- auto JSONContent = llvm::MemoryBuffer::getFile (Path);
314
- if (!JSONContent) {
315
- llvm::errs () << " failed to read " << Path << " : "
316
- << JSONContent.getError ().message () << " \n " ;
317
- return true ;
318
- }
319
- auto JSONValue = llvm::json::parse ((*JSONContent)->getBuffer ());
320
- if (!JSONValue) {
321
- llvm::errs () << " failed to parse " << Path << " : "
322
- << toString (JSONValue.takeError ()) << " \n " ;
323
- return true ;
324
- }
325
-
326
- auto Keys = JSONValue->getAsArray ();
349
+ auto Keys = readOutputEntriesFromFile (Path);
327
350
if (!Keys) {
328
- llvm::errs () << " invalid keys format in " << Path << " \n " ;
351
+ llvm::errs () << " cannot read file " << Path << " : "
352
+ << toString (Keys.takeError ()) << " \n " ;
329
353
return true ;
330
354
}
331
355
@@ -350,6 +374,51 @@ int SwiftCacheToolInvocation::validateOutputs() {
350
374
return llvm::any_of (Inputs, validateCacheKeysFromFile);
351
375
}
352
376
377
+ int SwiftCacheToolInvocation::renderDiags () {
378
+ if (setupCompiler ())
379
+ return 1 ;
380
+
381
+ auto *CDP = Instance.getCachingDiagnosticsProcessor ();
382
+ if (!CDP) {
383
+ llvm::errs () << " provided commandline doesn't support cached diagnostics\n " ;
384
+ return 1 ;
385
+ }
386
+
387
+ auto renderDiagsFromFile = [&](const std::string &Path) {
388
+ auto Keys = readOutputEntriesFromFile (Path);
389
+ if (!Keys) {
390
+ llvm::errs () << " cannot read file " << Path << " : "
391
+ << toString (Keys.takeError ()) << " \n " ;
392
+ return true ;
393
+ }
394
+
395
+ for (const auto & Entry : *Keys) {
396
+ if (auto *Obj = Entry.getAsObject ()) {
397
+ if (auto Kind = Obj->getString (" OutputKind" )) {
398
+ if (*Kind != " cached-diagnostics" )
399
+ continue ;
400
+ }
401
+ if (auto Key = Obj->getString (" CacheKey" )) {
402
+ if (auto Buffer = loadCachedCompileResultFromCacheKey (
403
+ Instance.getObjectStore (), Instance.getActionCache (),
404
+ Instance.getDiags (), *Key)) {
405
+ if (auto E = CDP->replayCachedDiagnostics (Buffer->getBuffer ())) {
406
+ llvm::errs () << " failed to replay cache: "
407
+ << toString (std::move (E)) << " \n " ;
408
+ return true ;
409
+ }
410
+ return false ;
411
+ }
412
+ }
413
+ }
414
+ }
415
+ llvm::errs () << " cannot locate cached diagnostics in file\n " ;
416
+ return true ;
417
+ };
418
+
419
+ return llvm::any_of (Inputs, renderDiagsFromFile);
420
+ }
421
+
353
422
int swift_cache_tool_main (ArrayRef<const char *> Args, const char *Argv0,
354
423
void *MainAddr) {
355
424
INITIALIZE_LLVM ();
0 commit comments