[cfe-commits] r67413 - in /cfe/trunk: include/clang/Basic/Diagnostic.h lib/Basic/Diagnostic.cpp lib/Sema/Sema.cpp lib/Sema/Sema.h lib/Sema/SemaTemplateInstantiate.cpp
Douglas Gregor
dgregor at apple.com
Fri Mar 20 15:48:49 PDT 2009
Author: dgregor
Date: Fri Mar 20 17:48:49 2009
New Revision: 67413
URL: http://llvm.org/viewvc/llvm-project?rev=67413&view=rev
Log:
Eliminate post-diagnostic hooks. Instead, implement a Sema-specific
variant of DiagnosticBuilder that emits the template instantiation
backtrace when needed.
Modified:
cfe/trunk/include/clang/Basic/Diagnostic.h
cfe/trunk/lib/Basic/Diagnostic.cpp
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=67413&r1=67412&r2=67413&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Fri Mar 20 17:48:49 2009
@@ -125,33 +125,6 @@
}
};
-/// \brief A hook function that will be invoked after we have
-/// completed processing of the current diagnostic.
-///
-/// Hook functions are typically used to emit further diagnostics
-/// (typically notes) that give more information about this
-/// diagnostic.
-struct PostDiagnosticHook {
- /// \brief The type of the hook function itself.
- ///
- /// DiagID is the ID of the diagnostic to which the hook was
- /// attached, and Cookie is a user-specified value that can be used
- /// to store extra data for the hook.
- typedef void (*HookTy)(unsigned DiagID, void *Cookie);
-
- PostDiagnosticHook() {}
-
- PostDiagnosticHook(HookTy Hook, void *Cookie) : Hook(Hook), Cookie(Cookie) {
- assert(Hook && "No hook provided!");
- }
-
- /// \brief The hook function.
- HookTy Hook;
-
- /// \brief The cookie that will be passed along to the hook function.
- void *Cookie;
-};
-
/// Diagnostic - This concrete class is used by the front-end to report
/// problems and issues. It massages the diagnostics (e.g. handling things like
/// "report warnings as errors" and passes them off to the DiagnosticClient for
@@ -363,9 +336,6 @@
/// \brief The number of code modifications hints in the
/// CodeModificationHints array.
unsigned char NumCodeModificationHints;
- /// \brief The number of post-diagnostic hooks in the
- /// PostDiagnosticHooks array.
- unsigned char NumPostDiagnosticHooks;
/// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
/// values, with one for each argument. This specifies whether the argument
@@ -393,15 +363,6 @@
/// to insert, remove, or modify at a particular position.
CodeModificationHint CodeModificationHints[MaxCodeModificationHints];
- enum { MaxPostDiagnosticHooks = 10 };
-
- /// \brief Functions that will be invoked after the diagnostic has
- /// been emitted.
- PostDiagnosticHook PostDiagnosticHooks[MaxPostDiagnosticHooks];
-
- /// \brief Whether we're already within a post-diagnostic hook.
- bool InPostDiagnosticHook;
-
/// ProcessDiag - This is the method used to report a diagnostic that is
/// finally fully formed.
void ProcessDiag();
@@ -424,14 +385,13 @@
/// for example.
class DiagnosticBuilder {
mutable Diagnostic *DiagObj;
- mutable unsigned NumArgs, NumRanges, NumCodeModificationHints,
- NumPostDiagnosticHooks;
+ mutable unsigned NumArgs, NumRanges, NumCodeModificationHints;
void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
friend class Diagnostic;
explicit DiagnosticBuilder(Diagnostic *diagObj)
: DiagObj(diagObj), NumArgs(0), NumRanges(0),
- NumCodeModificationHints(0), NumPostDiagnosticHooks(0) {}
+ NumCodeModificationHints(0) {}
public:
/// Copy constructor. When copied, this "takes" the diagnostic info from the
@@ -439,19 +399,25 @@
DiagnosticBuilder(const DiagnosticBuilder &D) {
DiagObj = D.DiagObj;
D.DiagObj = 0;
+ NumArgs = D.NumArgs;
+ NumRanges = D.NumRanges;
+ NumCodeModificationHints = D.NumCodeModificationHints;
}
-
- /// Destructor - The dtor emits the diagnostic.
- ~DiagnosticBuilder() {
- // If DiagObj is null, then its soul was stolen by the copy ctor.
+
+ /// \brief Force the diagnostic builder to emit the diagnostic now.
+ ///
+ /// Once this function has been called, the DiagnosticBuilder object
+ /// should not be used again before it is destroyed.
+ void Emit() {
+ // If DiagObj is null, then its soul was stolen by the copy ctor
+ // or the user called Emit().
if (DiagObj == 0) return;
- // When destroyed, the ~DiagnosticBuilder sets the final argument count into
+ // When emitting diagnostics, we set the final argument count into
// the Diagnostic object.
DiagObj->NumDiagArgs = NumArgs;
DiagObj->NumDiagRanges = NumRanges;
DiagObj->NumCodeModificationHints = NumCodeModificationHints;
- DiagObj->NumPostDiagnosticHooks = NumPostDiagnosticHooks;
// Process the diagnostic, sending the accumulated information to the
// DiagnosticClient.
@@ -459,7 +425,14 @@
// This diagnostic is no longer in flight.
DiagObj->CurDiagID = ~0U;
+
+ // This diagnostic is dead.
+ DiagObj = 0;
}
+
+ /// Destructor - The dtor emits the diagnostic if it hasn't already
+ /// been emitted.
+ ~DiagnosticBuilder() { Emit(); }
/// Operator bool: conversion of DiagnosticBuilder to bool always returns
/// true. This allows is to be used in boolean error contexts like:
@@ -492,15 +465,6 @@
"Too many code modification hints!");
DiagObj->CodeModificationHints[NumCodeModificationHints++] = Hint;
}
-
- void AddPostDiagnosticHook(const PostDiagnosticHook &Hook) const {
- assert(!DiagObj->InPostDiagnosticHook &&
- "Can't add a post-diagnostic hook to a diagnostic inside "
- "a post-diagnostic hook");
- assert(NumPostDiagnosticHooks < Diagnostic::MaxPostDiagnosticHooks &&
- "Too many post-diagnostic hooks");
- DiagObj->PostDiagnosticHooks[NumPostDiagnosticHooks++] = Hook;
- }
};
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
@@ -551,13 +515,6 @@
return DB;
}
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const PostDiagnosticHook &Hook) {
- DB.AddPostDiagnosticHook(Hook);
- return DB;
-}
-
-
/// Report - Issue the message to the client. DiagID is a member of the
/// diag::kind enum. This actually returns a new instance of DiagnosticBuilder
/// which emits the diagnostics (through ProcessDiag) when it is destroyed.
Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=67413&r1=67412&r2=67413&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Fri Mar 20 17:48:49 2009
@@ -221,8 +221,6 @@
ArgToStringFn = DummyArgToStringFn;
ArgToStringCookie = 0;
-
- InPostDiagnosticHook = false;
}
Diagnostic::~Diagnostic() {
@@ -411,15 +409,7 @@
Client->HandleDiagnostic(DiagLevel, Info);
if (Client->IncludeInDiagnosticCounts()) ++NumDiagnostics;
- // Invoke any post-diagnostic hooks.
- unsigned LastDiag = CurDiagID;
CurDiagID = ~0U;
-
- InPostDiagnosticHook = true;
- for (unsigned Hook = 0; Hook < NumPostDiagnosticHooks; ++Hook)
- PostDiagnosticHooks[Hook].Hook(LastDiag,
- PostDiagnosticHooks[Hook].Cookie);
- InPostDiagnosticHook = false;
}
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=67413&r1=67412&r2=67413&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Fri Mar 20 17:48:49 2009
@@ -295,3 +295,19 @@
return 0;
}
+Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
+ this->Emit();
+
+ // If this is not a note, and we're in a template instantiation
+ // that is different from the last template instantiation where
+ // we emitted an error, print a template instantiation
+ // backtrace.
+ if (!SemaRef.Diags.isBuiltinNote(DiagID) &&
+ !SemaRef.ActiveTemplateInstantiations.empty() &&
+ SemaRef.ActiveTemplateInstantiations.back()
+ != SemaRef.LastTemplateInstantiationErrorContext) {
+ SemaRef.PrintInstantiationStack();
+ SemaRef.LastTemplateInstantiationErrorContext
+ = SemaRef.ActiveTemplateInstantiations.back();
+ }
+}
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=67413&r1=67412&r2=67413&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Mar 20 17:48:49 2009
@@ -241,15 +241,30 @@
Diagnostic &getDiagnostics() const { return Diags; }
SourceManager &getSourceManager() const { return SourceMgr; }
- /// The primitive diagnostic helpers.
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
+ /// \brief Helper class that creates diagnostics with optional
+ /// template instantiation stacks.
+ ///
+ /// This class provides a wrapper around the basic DiagnosticBuilder
+ /// class that emits diagnostics. SemaDiagnosticBuilder is
+ /// responsible for emitting the diagnostic (as DiagnosticBuilder
+ /// does) and, if the diagnostic comes from inside a template
+ /// instantiation, printing the template instantiation stack as
+ /// well.
+ class SemaDiagnosticBuilder : public DiagnosticBuilder {
+ Sema &SemaRef;
+ unsigned DiagID;
+
+ public:
+ SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
+ : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { }
+
+ ~SemaDiagnosticBuilder();
+ };
+
+ /// \brief Emit a diagnostic.
+ SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
DiagnosticBuilder DB = Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
- if (!Diags.isBuiltinNote(DiagID) &&
- !ActiveTemplateInstantiations.empty() &&
- ActiveTemplateInstantiations.back()
- != LastTemplateInstantiationErrorContext)
- DB << PostDiagnosticHook(PrintInstantiationStackHook, this);
- return DB;
+ return SemaDiagnosticBuilder(DB, *this, DiagID);
}
virtual void DeleteExpr(ExprTy *E);
@@ -1858,7 +1873,6 @@
operator=(const InstantiatingTemplate&); // not implemented
};
- static void PrintInstantiationStackHook(unsigned DiagID, void *Cookie);
void PrintInstantiationStack();
QualType InstantiateType(QualType T, const TemplateArgument *TemplateArgs,
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=67413&r1=67412&r2=67413&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Fri Mar 20 17:48:49 2009
@@ -93,14 +93,6 @@
return true;
}
-/// \brief Post-diagnostic hook for printing the instantiation stack.
-void Sema::PrintInstantiationStackHook(unsigned, void *Cookie) {
- Sema &SemaRef = *static_cast<Sema*>(Cookie);
- SemaRef.PrintInstantiationStack();
- SemaRef.LastTemplateInstantiationErrorContext
- = SemaRef.ActiveTemplateInstantiations.back();
-}
-
/// \brief Prints the current instantiation stack through a series of
/// notes.
void Sema::PrintInstantiationStack() {
More information about the cfe-commits
mailing list