Eliminate post-diagnostic hooks. Instead, implement a Sema-specific
variant of DiagnosticBuilder that emits the template instantiation
backtrace when needed.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67413 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 2e019c9..76c3b05 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -241,15 +241,30 @@
   Diagnostic &getDiagnostics() const { return Diags; }
   SourceManager &getSourceManager() const { return SourceMgr; }
 
-  /// The primitive diagnostic helpers.
-  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
+  /// \brief Helper class that creates diagnostics with optional
+  /// template instantiation stacks.
+  ///
+  /// This class provides a wrapper around the basic DiagnosticBuilder
+  /// class that emits diagnostics. SemaDiagnosticBuilder is
+  /// responsible for emitting the diagnostic (as DiagnosticBuilder
+  /// does) and, if the diagnostic comes from inside a template
+  /// instantiation, printing the template instantiation stack as
+  /// well.
+  class SemaDiagnosticBuilder : public DiagnosticBuilder {
+    Sema &SemaRef;
+    unsigned DiagID;
+
+  public:
+    SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
+      : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { }
+
+    ~SemaDiagnosticBuilder();
+  };
+
+  /// \brief Emit a diagnostic.
+  SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
     DiagnosticBuilder DB = Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
-    if (!Diags.isBuiltinNote(DiagID) && 
-        !ActiveTemplateInstantiations.empty() &&
-        ActiveTemplateInstantiations.back() 
-          != LastTemplateInstantiationErrorContext)
-      DB << PostDiagnosticHook(PrintInstantiationStackHook, this);
-    return DB;
+    return SemaDiagnosticBuilder(DB, *this, DiagID);
   }
 
   virtual void DeleteExpr(ExprTy *E);
@@ -1858,7 +1873,6 @@
     operator=(const InstantiatingTemplate&); // not implemented
   };
 
-  static void PrintInstantiationStackHook(unsigned DiagID, void *Cookie);
   void PrintInstantiationStack();
 
   QualType InstantiateType(QualType T, const TemplateArgument *TemplateArgs,