22
22
#include " swift/AST/TypeLoc.h"
23
23
#include " swift/AST/DeclNameLoc.h"
24
24
#include " swift/AST/DiagnosticConsumer.h"
25
+ #include " llvm/ADT/StringMap.h"
26
+ #include " llvm/Support/Allocator.h"
25
27
26
28
namespace swift {
27
29
class Decl ;
@@ -323,6 +325,8 @@ namespace swift {
323
325
SourceLoc Loc;
324
326
const Decl *Decl = nullptr ;
325
327
328
+ friend DiagnosticEngine;
329
+
326
330
public:
327
331
// All constructors are intentionally implicit.
328
332
template <typename ...ArgTypes>
@@ -564,6 +568,12 @@ namespace swift {
564
568
// / results that we can point to on the command line.
565
569
llvm::DenseMap<const Decl *, SourceLoc> PrettyPrintedDeclarations;
566
570
571
+ llvm::BumpPtrAllocator TransactionAllocator;
572
+ // / A set of all strings involved in current transactional chain.
573
+ // / This is required because diagnostics are not directly emitted
574
+ // / but rather stored until all transactions complete.
575
+ llvm::StringMap<char , llvm::BumpPtrAllocator &> TransactionStrings;
576
+
567
577
// / The number of open diagnostic transactions. Diagnostics are only
568
578
// / emitted once all transactions have closed.
569
579
unsigned TransactionCount = 0 ;
@@ -579,8 +589,8 @@ namespace swift {
579
589
580
590
public:
581
591
explicit DiagnosticEngine (SourceManager &SourceMgr)
582
- : SourceMgr(SourceMgr), ActiveDiagnostic() {
583
- }
592
+ : SourceMgr(SourceMgr), ActiveDiagnostic(),
593
+ TransactionStrings(TransactionAllocator) { }
584
594
585
595
// / hadAnyError - return true if any *error* diagnostics have been emitted.
586
596
bool hadAnyError () const { return state.hadAnyError (); }
@@ -797,6 +807,11 @@ namespace swift {
797
807
DiagnosticFormatOptions FormatOpts = DiagnosticFormatOptions());
798
808
799
809
private:
810
+ // / Called when tentative diagnostic is about to be flushed,
811
+ // / to apply any required transformations e.g. copy string arguments
812
+ // / to extend their lifetime.
813
+ void onTentativeDiagnosticFlush (Diagnostic &diagnostic);
814
+
800
815
// / Flush the active diagnostic.
801
816
void flushActiveDiagnostic ();
802
817
@@ -856,6 +871,9 @@ namespace swift {
856
871
bool IsOpen = true ;
857
872
858
873
public:
874
+ DiagnosticTransaction (const DiagnosticTransaction &) = delete ;
875
+ DiagnosticTransaction &operator =(const DiagnosticTransaction &) = delete ;
876
+
859
877
explicit DiagnosticTransaction (DiagnosticEngine &engine)
860
878
: Engine(engine),
861
879
PrevDiagnostics(Engine.TentativeDiagnostics.size()),
@@ -870,6 +888,11 @@ namespace swift {
870
888
if (IsOpen) {
871
889
commit ();
872
890
}
891
+
892
+ if (Depth == 0 ) {
893
+ Engine.TransactionStrings .clear ();
894
+ Engine.TransactionAllocator .Reset ();
895
+ }
873
896
}
874
897
875
898
// / Abort and close this transaction and erase all diagnostics
0 commit comments