summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/Diagnostic.cpp3
-rw-r--r--clang/lib/Driver/Tools.cpp6
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp7
-rw-r--r--clang/lib/Frontend/Warnings.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp22
5 files changed, 38 insertions, 2 deletions
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
index 755fbed66f3..1870195ded0 100644
--- a/clang/lib/Basic/Diagnostic.cpp
+++ b/clang/lib/Basic/Diagnostic.cpp
@@ -224,7 +224,8 @@ Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) {
ErrorOccurred = false;
FatalErrorOccurred = false;
ErrorLimit = 0;
-
+ TemplateBacktraceLimit = 0;
+
NumWarnings = 0;
NumErrors = 0;
NumErrorsSuppressed = 0;
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index d9df471714a..4653551a469 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -1079,6 +1079,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
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");
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 932481f87f6..f9cfd73c7e6 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -240,6 +240,11 @@ static void DiagnosticOptsToArgs(const DiagnosticOptions &Opts,
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 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
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) {
diff --git a/clang/lib/Frontend/Warnings.cpp b/clang/lib/Frontend/Warnings.cpp
index 39cda8783b4..84c4f5d40fa 100644
--- a/clang/lib/Frontend/Warnings.cpp
+++ b/clang/lib/Frontend/Warnings.cpp
@@ -39,6 +39,8 @@ void clang::ProcessWarningOptions(Diagnostic &Diags,
// 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
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index e35d988dc81..abc8e5fb560 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -339,12 +339,32 @@ bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
/// \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);
OpenPOWER on IntegriCloud