21
21
#include " llvm/ADT/ArrayRef.h"
22
22
#include " llvm/ADT/SmallVector.h"
23
23
#include " llvm/ADT/STLExtras.h"
24
+ #include " llvm/Support/raw_ostream.h"
24
25
25
26
using namespace llvm ;
26
27
using namespace swift ;
@@ -112,10 +113,8 @@ void SplitterStep::computeFollowupSteps(
112
113
CS, i, /* single=*/ false , &Components[i], PartialSolutions[i]));
113
114
}
114
115
115
- if (numComponents > 1 && CS.getASTContext ().LangOpts .DebugConstraintSolver ) {
116
- auto &log = CS.getASTContext ().TypeCheckerDebug ->getStream ().indent (
117
- CS.solverState ->depth * 2 );
118
-
116
+ if (numComponents > 1 && isDebugMode ()) {
117
+ auto &log = getDebugLogger ();
119
118
// Verify that the constraint graph is valid.
120
119
CG.verify ();
121
120
@@ -212,11 +211,8 @@ bool SplitterStep::mergePartialSolutions() const {
212
211
if (!CS.worseThanBestSolution ()) {
213
212
// Finalize this solution.
214
213
auto solution = CS.finalize ();
215
- if (CS.TC .getLangOpts ().DebugConstraintSolver ) {
216
- auto &log = CS.getASTContext ().TypeCheckerDebug ->getStream ();
217
- log.indent (CS.solverState ->depth * 2 )
218
- << " (composed solution " << CS.CurrentScore << " )\n " ;
219
- }
214
+ if (isDebugMode ())
215
+ getDebugLogger () << " (composed solution " << CS.CurrentScore << " )\n " ;
220
216
221
217
// Save this solution.
222
218
Solutions.push_back (std::move (solution));
@@ -252,12 +248,6 @@ StepResult ComponentStep::take(bool prevFailed) {
252
248
if (prevFailed || CS.getExpressionTooComplex (Solutions))
253
249
return done (/* isSuccess=*/ false );
254
250
255
- if (!IsSingle && CS.TC .getLangOpts ().DebugConstraintSolver ) {
256
- auto &log = CS.getASTContext ().TypeCheckerDebug ->getStream ();
257
- log.indent (CS.solverState ->depth * 2 )
258
- << " (solving component #" << Index << ' \n ' ;
259
- }
260
-
261
251
// / Try to figure out what this step is going to be,
262
252
// / after the scope has been established.
263
253
auto *disjunction = CS.selectDisjunction ();
@@ -296,11 +286,8 @@ StepResult ComponentStep::take(bool prevFailed) {
296
286
}
297
287
298
288
auto solution = CS.finalize ();
299
- if (CS.TC .getLangOpts ().DebugConstraintSolver ) {
300
- auto &log = CS.getASTContext ().TypeCheckerDebug ->getStream ();
301
- log.indent (CS.solverState ->depth * 2 )
302
- << " (found solution " << getCurrentScore () << " )\n " ;
303
- }
289
+ if (isDebugMode ())
290
+ getDebugLogger () << " (found solution " << getCurrentScore () << " )\n " ;
304
291
305
292
Solutions.push_back (std::move (solution));
306
293
return done (/* isSuccess=*/ true );
@@ -310,6 +297,12 @@ StepResult ComponentStep::resume(bool prevFailed) {
310
297
// Rewind all modifications done to constraint system.
311
298
ComponentScope.reset ();
312
299
300
+ if (!IsSingle && isDebugMode ()) {
301
+ auto &log = getDebugLogger ();
302
+ log << (prevFailed ? " failed" : " finished" ) << " component #" << Index
303
+ << " )\n " ;
304
+ }
305
+
313
306
// If we came either back to this step and previous
314
307
// (either disjunction or type var) failed, it means
315
308
// that component as a whole has failed.
@@ -341,11 +334,11 @@ StepResult ComponentStep::resume(bool prevFailed) {
341
334
}
342
335
343
336
void TypeVariableStep::setup () {
344
- auto &TC = CS.TC ;
345
337
++CS.solverState ->NumTypeVariablesBound ;
346
- if (TC.getLangOpts ().DebugConstraintSolver ) {
347
- auto &log = TC.Context .TypeCheckerDebug ->getStream ();
348
- log.indent (CS.solverState ->depth * 2 ) << " Initial bindings: " ;
338
+ if (isDebugMode ()) {
339
+ auto &log = getDebugLogger ();
340
+
341
+ log << " Initial bindings: " ;
349
342
interleave (InitialBindings.begin (), InitialBindings.end (),
350
343
[&](const Binding &binding) {
351
344
log << TypeVar->getString ()
@@ -358,7 +351,6 @@ void TypeVariableStep::setup() {
358
351
}
359
352
360
353
StepResult TypeVariableStep::take (bool prevFailed) {
361
- auto &TC = CS.TC ;
362
354
while (auto binding = Producer ()) {
363
355
// Try each of the bindings in turn.
364
356
++CS.solverState ->NumTypeVariableBindings ;
@@ -375,10 +367,10 @@ StepResult TypeVariableStep::take(bool prevFailed) {
375
367
break ;
376
368
}
377
369
378
- if (TC. getLangOpts (). DebugConstraintSolver ) {
379
- auto &log = TC. Context . TypeCheckerDebug -> getStream ();
380
- log. indent (CS. solverState -> depth * 2 ) << " (trying " ;
381
- binding->print (log, &TC. Context .SourceMgr );
370
+ if (isDebugMode () ) {
371
+ auto &log = getDebugLogger ();
372
+ log << " (trying " ;
373
+ binding->print (log, &CS. getASTContext () .SourceMgr );
382
374
log << ' \n ' ;
383
375
}
384
376
@@ -394,12 +386,15 @@ StepResult TypeVariableStep::take(bool prevFailed) {
394
386
// let's try to see if it leads to any solutions.
395
387
return suspend (SplitterStep::create (CS, Solutions));
396
388
}
397
-
398
- // If this binding didn't match, let's check
399
- // if we've checked enough bindings to stop.
400
- if (shouldStop ())
401
- break ;
402
389
}
390
+
391
+ if (isDebugMode ())
392
+ getDebugLogger () << " )\n " ;
393
+
394
+ // If this binding didn't match, let's check
395
+ // if we've checked enough bindings to stop.
396
+ if (shouldStop ())
397
+ break ;
403
398
}
404
399
405
400
// No more bindings to try, or producer has been short-circuited.
@@ -416,11 +411,8 @@ StepResult TypeVariableStep::resume(bool prevFailed) {
416
411
// that active binding has a solution.
417
412
AnySolved |= !prevFailed;
418
413
419
- auto &TC = CS.TC ;
420
- if (TC.getLangOpts ().DebugConstraintSolver ) {
421
- auto &log = TC.Context .TypeCheckerDebug ->getStream ();
422
- log.indent (CS.solverState ->depth * 2 ) << " )\n " ;
423
- }
414
+ if (isDebugMode ())
415
+ getDebugLogger () << " )\n " ;
424
416
425
417
// Let's check if we should stop right before
426
418
// attempting any new bindings.
@@ -441,11 +433,10 @@ StepResult DisjunctionStep::take(bool prevFailed) {
441
433
if (shouldShortCircuitAt (currentChoice))
442
434
break ;
443
435
444
- if (CS.TC .getLangOpts ().DebugConstraintSolver ) {
445
- auto &ctx = CS.getASTContext ();
446
- auto &log = ctx.TypeCheckerDebug ->getStream ();
447
- log.indent (CS.solverState ->depth ) << " (assuming " ;
448
- currentChoice.print (log, &ctx.SourceMgr );
436
+ if (isDebugMode ()) {
437
+ auto &log = getDebugLogger ();
438
+ log << " (assuming " ;
439
+ currentChoice.print (log, &CS.getASTContext ().SourceMgr );
449
440
log << ' \n ' ;
450
441
}
451
442
@@ -455,6 +446,9 @@ StepResult DisjunctionStep::take(bool prevFailed) {
455
446
// / have to return "split" step which is going to take care of the rest.
456
447
if (attemptChoice (currentChoice))
457
448
return suspend (SplitterStep::create (CS, Solutions));
449
+
450
+ if (isDebugMode ())
451
+ getDebugLogger () << " )\n " ;
458
452
}
459
453
460
454
return done (/* isSuccess=*/ bool (LastSolvedChoice));
@@ -465,11 +459,6 @@ StepResult DisjunctionStep::resume(bool prevFailed) {
465
459
// active choice, let's see if it has be solved or not.
466
460
assert (ActiveChoice);
467
461
468
- if (CS.TC .getLangOpts ().DebugConstraintSolver ) {
469
- auto &log = CS.getASTContext ().TypeCheckerDebug ->getStream ();
470
- log.indent (CS.solverState ->depth ) << " )\n " ;
471
- }
472
-
473
462
// If choice (sub-path) has failed, it's okay, other
474
463
// choices have to be attempted regardless, since final
475
464
// decision could be made only after attempting all
@@ -491,18 +480,21 @@ StepResult DisjunctionStep::resume(bool prevFailed) {
491
480
// Rewind back the constraint system information.
492
481
ActiveChoice.reset ();
493
482
483
+ if (isDebugMode ())
484
+ getDebugLogger () << " )\n " ;
485
+
494
486
// Attempt next disjunction choice (if any left).
495
487
return take (prevFailed);
496
488
}
497
489
498
490
bool DisjunctionStep::shouldSkipChoice (const TypeBinding &choice) const {
499
- auto &TC = CS.TC ;
491
+ auto &ctx = CS.getASTContext () ;
500
492
501
493
if (choice.isDisabled ()) {
502
- if (TC. getLangOpts (). DebugConstraintSolver ) {
503
- auto &log = CS. getASTContext (). TypeCheckerDebug -> getStream ();
504
- log. indent (CS. solverState -> depth ) << " (skipping " ;
505
- choice.print (log, &TC. Context .SourceMgr );
494
+ if (isDebugMode () ) {
495
+ auto &log = getDebugLogger ();
496
+ log << " (skipping " ;
497
+ choice.print (log, &ctx .SourceMgr );
506
498
log << ' \n ' ;
507
499
}
508
500
@@ -513,7 +505,7 @@ bool DisjunctionStep::shouldSkipChoice(const TypeBinding &choice) const {
513
505
if (!CS.shouldAttemptFixes () && choice.isUnavailable ())
514
506
return true ;
515
507
516
- if (TC. getLangOpts () .DisableConstraintSolverPerformanceHacks )
508
+ if (ctx. LangOpts .DisableConstraintSolverPerformanceHacks )
517
509
return false ;
518
510
519
511
// Don't attempt to solve for generic operators if we already have
0 commit comments