[cfe-commits] r101882 - in /cfe/trunk: docs/UsersManual.html include/clang/Basic/Diagnostic.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Driver/CC1Options.td include/clang/Driver/Options.td include/clang/Frontend/DiagnosticOptions.h lib/Basic/Diagnostic.cpp lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp lib/Frontend/Warnings.cpp lib/Sema/SemaTemplateInstantiate.cpp test/SemaTemplate/instantiation-depth.cpp

Douglas Gregor dgregor at apple.com
Tue Apr 20 00:18:24 PDT 2010


Author: dgregor
Date: Tue Apr 20 02:18:24 2010
New Revision: 101882

URL: http://llvm.org/viewvc/llvm-project?rev=101882&view=rev
Log:
Introduce a limit on the depth of the template instantiation backtrace
we will print with each error that occurs during template
instantiation. When the backtrace is longer than that, we will print
N/2 of the innermost backtrace entries and N/2 of the outermost
backtrace entries, then skip the middle entries with a note such as:

  note: suppressed 2 template instantiation contexts; use
  -ftemplate-backtrace-limit=N to change the number of template
  instantiation entries shown

This should eliminate some excessively long backtraces that aren't
providing any value.

Modified:
    cfe/trunk/docs/UsersManual.html
    cfe/trunk/include/clang/Basic/Diagnostic.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/include/clang/Frontend/DiagnosticOptions.h
    cfe/trunk/lib/Basic/Diagnostic.cpp
    cfe/trunk/lib/Driver/Tools.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Frontend/Warnings.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/test/SemaTemplate/instantiation-depth.cpp

Modified: cfe/trunk/docs/UsersManual.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.html?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/docs/UsersManual.html (original)
+++ cfe/trunk/docs/UsersManual.html Tue Apr 20 02:18:24 2010
@@ -193,6 +193,8 @@
    been produced.  The default is 20, and the error limit can be disabled with
    -ferror-limit=0.</p>
 
+<p><b>-ftemplate-backtrace-limit=123</b>: Only emit up to 123 template instantiation notes within the template instantiation backtrace for a single warning or error. The default is 10, and the limit can be disabled with -ftemplate-backtrace-limit=0.</p>
+
 <!-- ================================================= -->
 <h4 id="cl_diag_formatting">Formatting of Diagnostics</h4>
 <!-- ================================================= -->

Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Tue Apr 20 02:18:24 2010
@@ -189,6 +189,8 @@
   bool SuppressSystemWarnings;   // Suppress warnings in system headers.
   bool SuppressAllDiagnostics;   // Suppress all diagnostics.
   unsigned ErrorLimit;           // Cap of # errors emitted, 0 -> no limit.
+  unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
+                                   // 0 -> no limit.
   ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
   DiagnosticClient *Client;
 
@@ -276,6 +278,18 @@
   /// emit before giving up.  Zero disables the limit.
   void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
   
+  /// \brief Specify the maximum number of template instantiation
+  /// notes to emit along with a given diagnostic.
+  void setTemplateBacktraceLimit(unsigned Limit) {
+    TemplateBacktraceLimit = Limit;
+  }
+
+  /// \brief Retrieve the maximum number of template instantiation
+  /// nodes to emit along with a given diagnostic.
+  unsigned getTemplateBacktraceLimit() const {
+    return TemplateBacktraceLimit;
+  }
+
   /// setIgnoreAllWarnings - When set to true, any unmapped warnings are
   /// ignored.  If this and WarningsAsErrors are both set, then this one wins.
   void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Apr 20 02:18:24 2010
@@ -1434,7 +1434,10 @@
   " template parameter%1 %2">;
 def note_template_default_arg_checking : Note<
   "while checking a default template argument used here">;
-  
+def note_instantiation_contexts_suppressed : Note<
+  "suppressed %0 template instantiation context%s0; use -ftemplate-backtrace-"
+  "limit=N to change the number of template instantiation entries shown">;
+
 def err_field_instantiates_to_function : Error<
   "data member instantiated with function type %0">;
 def err_nested_name_spec_non_tag : Error<

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Tue Apr 20 02:18:24 2010
@@ -200,6 +200,8 @@
   HelpText<"Set the tab stop distance.">;
 def ferror_limit : Separate<"-ferror-limit">, MetaVarName<"<N>">,
   HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">;
+def ftemplate_backtrace_limit : Separate<"-ftemplate-backtrace-limit">, MetaVarName<"<N>">,
+  HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">;
 def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"<N>">,
   HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">;
 def fcolor_diagnostics : Flag<"-fcolor-diagnostics">,

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Tue Apr 20 02:18:24 2010
@@ -366,6 +366,8 @@
 def ftabstop_EQ : Joined<"-ftabstop=">, Group<f_Group>;
 def ferror_limit_EQ : Joined<"-ferror-limit=">, Group<f_Group>;
 def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>;
+def ftemplate_backtrace_limit_EQ : Joined<"-ftemplate-backtrace-limit=">, 
+                                   Group<f_Group>;
 def fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>;
 def fthreadsafe_statics : Flag<"-fthreadsafe-statics">, Group<f_Group>;
 def ftime_report : Flag<"-ftime-report">, Group<f_Group>;

Modified: cfe/trunk/include/clang/Frontend/DiagnosticOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/DiagnosticOptions.h?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/DiagnosticOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/DiagnosticOptions.h Tue Apr 20 02:18:24 2010
@@ -39,7 +39,8 @@
                                  /// deserialized by, e.g., the CIndex library.
 
   unsigned ErrorLimit;           /// Limit # errors emitted.
-  
+  unsigned TemplateBacktraceLimit; /// Limit depth of instantiation backtrace.
+
   /// The distance between tab stops.
   unsigned TabStop;
   enum { DefaultTabStop = 8, MaxTabStop = 100 };
@@ -73,6 +74,7 @@
     VerifyDiagnostics = 0;
     BinaryOutput = 0;
     ErrorLimit = 0;
+    TemplateBacktraceLimit = 0;
   }
 };
 

Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Tue Apr 20 02:18:24 2010
@@ -224,7 +224,8 @@
   ErrorOccurred = false;
   FatalErrorOccurred = false;
   ErrorLimit = 0;
-  
+  TemplateBacktraceLimit = 0;
+
   NumWarnings = 0;
   NumErrors = 0;
   NumErrorsSuppressed = 0;

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Tue Apr 20 02:18:24 2010
@@ -1079,6 +1079,12 @@
     CmdArgs.push_back(A->getValue(Args));
   else
     CmdArgs.push_back("19");
+
+  CmdArgs.push_back("-ftemplate-backtrace-limit");
+  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ))
+    CmdArgs.push_back(A->getValue(Args));
+  else
+    CmdArgs.push_back("10");
   
   // Pass -fmessage-length=.
   CmdArgs.push_back("-fmessage-length");

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Tue Apr 20 02:18:24 2010
@@ -240,6 +240,11 @@
     Res.push_back("-ferror-limit");
     Res.push_back(llvm::utostr(Opts.ErrorLimit));
   }
+  if (Opts.TemplateBacktraceLimit != 10) {
+    Res.push_back("-ftemplate-backtrace-limit");
+    Res.push_back(llvm::utostr(Opts.TemplateBacktraceLimit));
+  }
+
   if (Opts.TabStop != DiagnosticOptions::DefaultTabStop) {
     Res.push_back("-ftabstop");
     Res.push_back(llvm::utostr(Opts.TabStop));
@@ -857,6 +862,8 @@
   Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);
   Opts.BinaryOutput = Args.hasArg(OPT_fdiagnostics_binary);
   Opts.ErrorLimit = getLastArgIntValue(Args, OPT_ferror_limit, 0, Diags);
+  Opts.TemplateBacktraceLimit
+    = getLastArgIntValue(Args, OPT_ftemplate_backtrace_limit, 0, Diags);
   Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop,
                                     DiagnosticOptions::DefaultTabStop, Diags);
   if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {

Modified: cfe/trunk/lib/Frontend/Warnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Warnings.cpp?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/Warnings.cpp (original)
+++ cfe/trunk/lib/Frontend/Warnings.cpp Tue Apr 20 02:18:24 2010
@@ -39,6 +39,8 @@
   // Handle -ferror-limit
   if (Opts.ErrorLimit)
     Diags.setErrorLimit(Opts.ErrorLimit);
+  if (Opts.TemplateBacktraceLimit)
+    Diags.setTemplateBacktraceLimit(Opts.TemplateBacktraceLimit);
 
   // If -pedantic or -pedantic-errors was specified, then we want to map all
   // extension diagnostics onto WARNING or ERROR unless the user has futz'd

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Tue Apr 20 02:18:24 2010
@@ -339,12 +339,32 @@
 /// \brief Prints the current instantiation stack through a series of
 /// notes.
 void Sema::PrintInstantiationStack() {
+  // Determine which template instantiations to skip, if any.
+  unsigned SkipStart = ActiveTemplateInstantiations.size(), SkipEnd = SkipStart;
+  unsigned Limit = Diags.getTemplateBacktraceLimit();
+  if (Limit && Limit < ActiveTemplateInstantiations.size()) {
+    SkipStart = Limit / 2 + Limit % 2;
+    SkipEnd = ActiveTemplateInstantiations.size() - Limit / 2;
+  }
+
   // FIXME: In all of these cases, we need to show the template arguments
+  unsigned InstantiationIdx = 0;
   for (llvm::SmallVector<ActiveTemplateInstantiation, 16>::reverse_iterator
          Active = ActiveTemplateInstantiations.rbegin(),
          ActiveEnd = ActiveTemplateInstantiations.rend();
        Active != ActiveEnd;
-       ++Active) {
+       ++Active, ++InstantiationIdx) {
+    // Skip this instantiation?
+    if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) {
+      if (InstantiationIdx == SkipStart) {
+        // Note that we're skipping instantiations.
+        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+                     diag::note_instantiation_contexts_suppressed)
+          << unsigned(ActiveTemplateInstantiations.size() - Limit);
+      }
+      continue;
+    }
+
     switch (Active->Kind) {
     case ActiveTemplateInstantiation::TemplateInstantiation: {
       Decl *D = reinterpret_cast<Decl *>(Active->Entity);

Modified: cfe/trunk/test/SemaTemplate/instantiation-depth.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiation-depth.cpp?rev=101882&r1=101881&r2=101882&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiation-depth.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiation-depth.cpp Tue Apr 20 02:18:24 2010
@@ -1,8 +1,10 @@
-// RUN: %clang_cc1 -fsyntax-only -ftemplate-depth 5 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 %s
 
-template<typename T> struct X : X<T*> { }; // expected-error{{recursive template instantiation exceeded maximum depth of 5}} \
-// expected-note{{use -ftemplate-depth-N to increase recursive template instantiation depth}} \
-// expected-note 5 {{instantiation of template class}}
+template<typename T> struct X : X<T*> { }; \
+// expected-error{{recursive template instantiation exceeded maximum depth of 5}} \
+// expected-note 3 {{instantiation of template class}} \
+// expected-note {{suppressed 2 template instantiation contexts}} \
+// expected-note {{use -ftemplate-depth-N to increase recursive template instantiation depth}}
 
 void test() { 
   (void)sizeof(X<int>); // expected-note {{instantiation of template class}}





More information about the cfe-commits mailing list