Add a notion of "post-diagnostic hooks", which are callbacks attached
to a diagnostic that will be invoked after the diagnostic (if it is
not suppressed). The hooks are allowed to produce additional
diagnostics (typically notes) that provide more information. We should
be able to use this to help diagnostic clients link notes back to the
diagnostic they clarify. Comments welcome; I'll write up documentation
and convert other clients (e.g., overload resolution failures) if
there are no screams of protest.

As the first client of post-diagnostic hooks, we now produce a
template instantiation backtrace when a failure occurs during template
instantiation. There's still more work to do to make this output
pretty, if that's even possible.




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66557 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 0990057..4a12b07 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -21,6 +21,10 @@
 
 using namespace clang;
 
+//===----------------------------------------------------------------------===/
+// Template Instantiation Support
+//===----------------------------------------------------------------------===/
+
 Sema::InstantiatingTemplate::
 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                       ClassTemplateSpecializationDecl *Entity,
@@ -50,6 +54,26 @@
     SemaRef.ActiveTemplateInstantiations.pop_back();
 }
 
+/// \brief Post-diagnostic hook for printing the instantiation stack.
+void Sema::PrintInstantiationStackHook(unsigned, void *Cookie) {
+  static_cast<Sema*>(Cookie)->PrintInstantiationStack();
+}
+
+/// \brief Prints the current instantiation stack through a series of
+/// notes.
+void Sema::PrintInstantiationStack() {
+  for (llvm::SmallVector<ActiveTemplateInstantiation, 16>::reverse_iterator
+         Active = ActiveTemplateInstantiations.rbegin(),
+         ActiveEnd = ActiveTemplateInstantiations.rend();
+       Active != ActiveEnd;
+       ++Active) {
+    Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr), 
+                 diag::note_template_class_instantiation_here)
+      << Context.getTypeDeclType(Active->Entity)
+      << Active->InstantiationRange;
+  }
+}
+
 //===----------------------------------------------------------------------===/
 // Template Instantiation for Types
 //===----------------------------------------------------------------------===/