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&