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
@@ -870,6 +885,11 @@ namespace swift {
870
885
if (IsOpen) {
871
886
commit ();
872
887
}
888
+
889
+ if (Depth == 0 ) {
890
+ Engine.TransactionStrings .clear ();
891
+ Engine.TransactionAllocator .Reset ();
892
+ }
873
893
}
874
894
875
895
// / Abort and close this transaction and erase all diagnostics
0 commit comments