Extend the notion of active template instantiations to include the
context of a template-id for which we need to instantiate default
template arguments.

In the TextDiagnosticPrinter, don't suppress the caret diagnostic if
we are producing a non-note diagnostic that follows a note diagnostic
with the same location, because notes are (conceptually) a part of the
warning or error that comes before them.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66572 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index d68924c..c4964bf 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -245,7 +245,7 @@
     DiagnosticBuilder DB = Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
     if (!Diags.isBuiltinNote(DiagID) && 
         !ActiveTemplateInstantiations.empty() &&
-        ActiveTemplateInstantiations.back().Entity 
+        ActiveTemplateInstantiations.back() 
           != LastTemplateInstantiationErrorContext)
       DB << PostDiagnosticHook(PrintInstantiationStackHook, this);
     return DB;
@@ -1673,16 +1673,61 @@
 
   /// \brief A template instantiation that is currently in progress.
   struct ActiveTemplateInstantiation {
+    /// \brief The kind of template instantiation we are performing
+    enum {
+      /// We are instantiating a template declaration. The entity is
+      /// the declaration we're instantiation (e.g., a
+      /// ClassTemplateSpecializationDecl).
+      TemplateInstantiation,
+
+      /// We are instantiating a default argument for a template
+      /// parameter. The Entity is the template, and
+      /// TemplateArgs/NumTemplateArguments provides the template
+      /// arguments as specified.
+      DefaultTemplateArgumentInstantiation
+    } Kind;
+
     /// \brief The point of instantiation within the source code.
     SourceLocation PointOfInstantiation;
 
     /// \brief The entity that is being instantiated.
-    ClassTemplateSpecializationDecl *Entity;
+    uintptr_t Entity;
+
+    // \brief If this the instantiation of a default template
+    // argument, the list of tempalte arguments.
+    const TemplateArgument *TemplateArgs;
+
+    /// \brief The number of template arguments in TemplateArgs.
+    unsigned NumTemplateArgs;
 
     /// \brief The source range that covers the construct that cause
     /// the instantiation, e.g., the template-id that causes a class
     /// template instantiation.
     SourceRange InstantiationRange;
+
+    friend bool operator==(const ActiveTemplateInstantiation &X,
+                           const ActiveTemplateInstantiation &Y) {
+      if (X.Kind != Y.Kind)
+        return false;
+
+      if (X.Entity != Y.Entity)
+        return false;
+
+      switch (X.Kind) {
+      case TemplateInstantiation:
+        return true;
+
+      case DefaultTemplateArgumentInstantiation:
+        return X.TemplateArgs == Y.TemplateArgs;
+      }
+
+      return true;
+    }
+
+    friend bool operator!=(const ActiveTemplateInstantiation &X,
+                           const ActiveTemplateInstantiation &Y) {
+      return !(X == Y);
+    }
   };
 
   /// \brief List of active template instantiations.
@@ -1701,7 +1746,7 @@
   /// instantiation backtraces when there are multiple errors in the
   /// same instantiation. FIXME: Does this belong in Sema? It's tough
   /// to implement it anywhere else.
-  ClassTemplateSpecializationDecl *LastTemplateInstantiationErrorContext;
+  ActiveTemplateInstantiation LastTemplateInstantiationErrorContext;
 
   /// \brief A stack object to be created when performing template
   /// instantiation.
@@ -1715,9 +1760,19 @@
   /// Destruction of this object will pop the named instantiation off
   /// the stack.
   struct InstantiatingTemplate {
+    /// \brief Note that we are instantiating a class template.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           ClassTemplateSpecializationDecl *Entity,
                           SourceRange InstantiationRange = SourceRange());
+
+    /// \brief Note that we are instantiating a default argument in a
+    /// template-id.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          TemplateDecl *Template,
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs,
+                          SourceRange InstantiationRange = SourceRange());
+
     ~InstantiatingTemplate();
 
     /// \brief Determines whether we have exceeded the maximum
@@ -1728,6 +1783,9 @@
     Sema &SemaRef;
     bool Invalid;
 
+    bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
+                                 SourceRange InstantiationRange);
+
     InstantiatingTemplate(const InstantiatingTemplate&); // not implemented
 
     InstantiatingTemplate&