18
18
#include " swift/AST/ASTContext.h"
19
19
#include " swift/AST/ASTMangler.h"
20
20
#include " swift/AST/ASTPrinter.h"
21
+ #include " swift/AST/DiagnosticsFrontend.h"
21
22
#include " swift/AST/SourceFile.h"
22
- #include " swift/Demangling/Demangler.h"
23
23
#include " swift/Basic/OptionSet.h"
24
+ #include " swift/Demangling/Demangler.h"
24
25
#include " swift/Frontend/DiagnosticVerifier.h"
25
26
#include " swift/Parse/Lexer.h"
26
27
@@ -261,7 +262,6 @@ struct Obligation {
261
262
class DependencyVerifier {
262
263
SourceManager &SM;
263
264
const DependencyTracker &DT;
264
- std::vector<llvm::SMDiagnostic> Errors = {};
265
265
266
266
public:
267
267
explicit DependencyVerifier (SourceManager &SM, const DependencyTracker &DT)
@@ -286,7 +286,7 @@ class DependencyVerifier {
286
286
ObligationMap &Obs,
287
287
NegativeExpectationMap &NegativeExpectations);
288
288
289
- bool verifyNegativeExpectations (ObligationMap &Obs,
289
+ bool verifyNegativeExpectations (const SourceFile *SF, ObligationMap &Obs,
290
290
NegativeExpectationMap &Negs);
291
291
292
292
bool diagnoseUnfulfilledObligations (const SourceFile *SF, ObligationMap &OM);
@@ -328,29 +328,13 @@ class DependencyVerifier {
328
328
}
329
329
330
330
private:
331
- template <typename ... Ts>
332
- inline auto addFormattedDiagnostic (const Expectation &dep, const char *Fmt,
333
- Ts &&... Vals) {
334
- return addFormattedDiagnostic (dep.MessageRange .begin (), Fmt,
335
- std::forward<Ts>(Vals)...);
336
- }
337
-
338
- template <typename ... Ts>
339
- inline auto addFormattedDiagnostic (const char *Loc, const char *Fmt,
340
- Ts &&... Vals) {
341
- auto loc = SourceLoc (llvm::SMLoc::getFromPointer (Loc));
342
- auto diag =
343
- SM.GetMessage (loc, llvm::SourceMgr::DK_Error,
344
- llvm::formatv (Fmt, std::forward<Ts>(Vals)...), {}, {});
345
- Errors.push_back (diag);
331
+ template <typename ... ArgTypes>
332
+ InFlightDiagnostic
333
+ diagnose (DiagnosticEngine &Diags, const char *LocPtr, Diag<ArgTypes...> ID,
334
+ typename detail::PassArgument<ArgTypes>::type... Args) const {
335
+ auto Loc = SourceLoc (llvm::SMLoc::getFromPointer (LocPtr));
336
+ return Diags.diagnose (Loc, ID, std::move (Args)...);
346
337
}
347
-
348
- void addError (const char *Loc, const Twine &Msg,
349
- ArrayRef<llvm::SMFixIt> FixIts = {}) {
350
- auto loc = SourceLoc (llvm::SMLoc::getFromPointer (Loc));
351
- auto diag = SM.GetMessage (loc, llvm::SourceMgr::DK_Error, Msg, {}, FixIts);
352
- Errors.push_back (diag);
353
- };
354
338
};
355
339
} // end anonymous namespace
356
340
@@ -391,17 +375,19 @@ bool DependencyVerifier::parseExpectations(
391
375
392
376
// Skip any whitespace before the {{.
393
377
MatchStart = MatchStart.substr (MatchStart.find_first_not_of (" \t " ));
378
+ auto &diags = SF->getASTContext ().Diags ;
394
379
395
380
const size_t TextStartIdx = MatchStart.find (" {{" );
396
381
if (TextStartIdx == StringRef::npos) {
397
- addError (MatchStart.data (), " expected {{ in expectation" );
382
+ diagnose (diags, MatchStart.data (),
383
+ diag::expectation_missing_opening_braces);
398
384
continue ;
399
385
}
400
386
401
387
const size_t End = MatchStart.find (" }}" );
402
388
if (End == StringRef::npos) {
403
- addError ( MatchStart.data (),
404
- " didn't find '}}' to match '{{' in expectation " );
389
+ diagnose (diags, MatchStart.data (),
390
+ diag::expectation_missing_closing_braces );
405
391
continue ;
406
392
}
407
393
@@ -483,7 +469,7 @@ bool DependencyVerifier::verifyObligations(
483
469
ObligationMap &OM, llvm::StringMap<Expectation> &NegativeExpectations) {
484
470
auto *tracker = SF->getReferencedNameTracker ();
485
471
assert (tracker && " Constructed source file without referenced name tracker!" );
486
-
472
+ auto &diags = SF-> getASTContext (). Diags ;
487
473
for (auto &expectation : ExpectedDependencies) {
488
474
const bool wantsCascade = expectation.isCascading ();
489
475
switch (expectation.Info .Kind ) {
@@ -497,20 +483,18 @@ bool DependencyVerifier::verifyObligations(
497
483
[&](Obligation &p) {
498
484
const auto haveCascade = p.getCascades ();
499
485
if (haveCascade != wantsCascade) {
500
- addFormattedDiagnostic (
501
- expectation,
502
- " expected {0} dependency; found {1} dependency instead" ,
503
- wantsCascade ? " cascading" : " non-cascading" ,
504
- haveCascade ? " cascading" : " non-cascading" );
486
+ diagnose (diags, expectation.MessageRange .begin (),
487
+ diag::dependency_cascading_mismatch, wantsCascade,
488
+ haveCascade);
505
489
return p.fail ();
506
490
}
507
491
508
492
return p.fullfill ();
509
493
},
510
- [this ](const Expectation &e) {
511
- addFormattedDiagnostic (
512
- e, " expected member dependency does not exist: {0} " ,
513
- e.MessageRange );
494
+ [& ](const Expectation &e) {
495
+ diagnose (
496
+ diags, e. MessageRange . begin (), diag::missing_member_dependency ,
497
+ static_cast < uint8_t >(expectation. Info . Kind ), e.MessageRange );
514
498
});
515
499
break ;
516
500
case Expectation::Kind::PotentialMember:
@@ -520,39 +504,36 @@ bool DependencyVerifier::verifyObligations(
520
504
assert (p.getName ().empty ());
521
505
const auto haveCascade = p.getCascades ();
522
506
if (haveCascade != wantsCascade) {
523
- addFormattedDiagnostic (
524
- expectation,
525
- " expected {0} potential member dependency; found {1} "
526
- " potential member dependency instead" ,
527
- wantsCascade ? " cascading" : " non-cascading" ,
528
- haveCascade ? " cascading" : " non-cascading" );
507
+ diagnose (diags, expectation.MessageRange .begin (),
508
+ diag::potential_dependency_cascading_mismatch,
509
+ wantsCascade, haveCascade);
529
510
return p.fail ();
530
511
}
531
512
532
513
return p.fullfill ();
533
514
},
534
- [this ](const Expectation &e) {
535
- addFormattedDiagnostic (
536
- e, " expected potential member dependency does not exist: {0} " ,
537
- e.MessageRange );
515
+ [& ](const Expectation &e) {
516
+ diagnose (
517
+ diags, e. MessageRange . begin (), diag::missing_member_dependency ,
518
+ static_cast < uint8_t >(expectation. Info . Kind ), e.MessageRange );
538
519
});
539
520
break ;
540
521
case Expectation::Kind::Provides:
541
522
matchExpectationOrFail (
542
523
OM, expectation, [](Obligation &O) { return O.fullfill (); },
543
- [this ](const Expectation &e) {
544
- addFormattedDiagnostic (
545
- e, " expected provided dependency does not exist: {0} " ,
546
- e.MessageRange );
524
+ [& ](const Expectation &e) {
525
+ diagnose (
526
+ diags, e. MessageRange . begin (), diag::missing_member_dependency ,
527
+ static_cast < uint8_t >(expectation. Info . Kind ), e.MessageRange );
547
528
});
548
529
break ;
549
530
case Expectation::Kind::DynamicMember:
550
531
matchExpectationOrFail (
551
532
OM, expectation, [](Obligation &O) { return O.fullfill (); },
552
- [this ](const Expectation &e) {
553
- addFormattedDiagnostic (
554
- e, " expected dynamic member dependency does not exist: {0} " ,
555
- e.MessageRange );
533
+ [& ](const Expectation &e) {
534
+ diagnose (
535
+ diags, e. MessageRange . begin (), diag::missing_member_dependency ,
536
+ static_cast < uint8_t >(expectation. Info . Kind ), e.MessageRange );
556
537
});
557
538
break ;
558
539
}
@@ -562,16 +543,17 @@ bool DependencyVerifier::verifyObligations(
562
543
}
563
544
564
545
bool DependencyVerifier::verifyNegativeExpectations (
565
- ObligationMap &Obligations, NegativeExpectationMap &NegativeExpectations) {
546
+ const SourceFile *SF, ObligationMap &Obligations,
547
+ NegativeExpectationMap &NegativeExpectations) {
566
548
forEachOwedObligation (Obligations, [&](StringRef key, Obligation &p) {
567
549
auto entry = NegativeExpectations.find (key);
568
550
if (entry == NegativeExpectations.end ()) {
569
551
return ;
570
552
}
571
553
572
554
auto &expectation = entry->second ;
573
- addFormattedDiagnostic (expectation, " unexpected dependency exists: {0} " ,
574
- expectation.MessageRange );
555
+ diagnose (SF-> getASTContext (). Diags , expectation. MessageRange . begin () ,
556
+ diag::negative_expectation_violated, expectation.MessageRange );
575
557
p.fail ();
576
558
});
577
559
return false ;
@@ -581,31 +563,23 @@ bool DependencyVerifier::diagnoseUnfulfilledObligations(
581
563
const SourceFile *SF, ObligationMap &Obligations) {
582
564
CharSourceRange EntireRange = SM.getRangeForBuffer (*SF->getBufferID ());
583
565
StringRef InputFile = SM.extractText (EntireRange);
566
+ auto &diags = SF->getASTContext ().Diags ;
584
567
forEachOwedObligation (Obligations, [&](StringRef key, Obligation &p) {
585
568
// HACK: Diagnosing the end of the buffer will print a carat pointing
586
569
// at the file path, but not print any of the buffer's contents, which
587
570
// might be misleading.
588
- const char * Loc = InputFile.end ();
571
+ auto Loc = SourceLoc ( llvm::SMLoc::getFromPointer ( InputFile.end ()) );
589
572
switch (p.getKind ()) {
590
573
case Expectation::Kind::Negative:
591
574
llvm_unreachable (" Obligations may not be negative; only Expectations!" );
592
575
case Expectation::Kind::Member:
593
- addFormattedDiagnostic (Loc, " unexpected {0} dependency: {1}" ,
594
- p.describeCascade (), key);
595
- break ;
596
576
case Expectation::Kind::DynamicMember:
597
- addFormattedDiagnostic (Loc,
598
- " unexpected {0} dynamic member dependency: {1}" ,
599
- p.describeCascade (), p.getName ());
600
- break ;
601
577
case Expectation::Kind::PotentialMember:
602
- addFormattedDiagnostic (Loc,
603
- " unexpected {0} potential member dependency: {1}" ,
604
- p.describeCascade (), key);
578
+ diags.diagnose (Loc, diag::unexpected_dependency, p.describeCascade (),
579
+ static_cast <uint8_t >(p.getKind ()), key);
605
580
break ;
606
581
case Expectation::Kind::Provides:
607
- addFormattedDiagnostic (Loc, " unexpected provided entity: {0}" ,
608
- p.getName ());
582
+ diags.diagnose (Loc, diag::unexpected_provided_entity, p.getName ());
609
583
break ;
610
584
}
611
585
});
@@ -629,25 +603,15 @@ bool DependencyVerifier::verifyFile(const SourceFile *SF) {
629
603
return true ;
630
604
}
631
605
632
- if (verifyNegativeExpectations (Obligations, Negatives)) {
606
+ if (verifyNegativeExpectations (SF, Obligations, Negatives)) {
633
607
return true ;
634
608
}
635
609
636
610
if (diagnoseUnfulfilledObligations (SF, Obligations)) {
637
611
return true ;
638
612
}
639
613
640
- // Sort the diagnostics by location so we get a stable ordering.
641
- std::sort (Errors.begin (), Errors.end (),
642
- [&](const llvm::SMDiagnostic &lhs,
643
- const llvm::SMDiagnostic &rhs) -> bool {
644
- return lhs.getLoc ().getPointer () < rhs.getLoc ().getPointer ();
645
- });
646
-
647
- for (auto Err : Errors)
648
- SM.getLLVMSourceMgr ().PrintMessage (llvm::errs (), Err);
649
-
650
- return !Errors.empty ();
614
+ return SF->getASTContext ().Diags .hadAnyError ();
651
615
}
652
616
653
617
// ===----------------------------------------------------------------------===//
0 commit comments