diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index 1f3b2cd5f47c..b38df5f9c4f7 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -29,6 +29,7 @@ namespace clang { class DeclContext; class LangOptions; class Preprocessor; + class DiagnosticErrorTrap; /// \brief Annotates a diagnostic with some code that should be /// inserted, removed, or replaced to fix the problem. @@ -486,6 +487,7 @@ private: friend class DiagnosticBuilder; friend class DiagnosticInfo; friend class PartialDiagnostic; + friend class DiagnosticErrorTrap; /// CurDiagLoc - This is the location of the current diagnostic that is in /// flight. @@ -549,6 +551,27 @@ private: friend class ASTWriter; }; +/// \brief RAII class that determines when any errors have occurred +/// between the time the instance was created and the time it was +/// queried. +class DiagnosticErrorTrap { + Diagnostic &Diag; + unsigned PrevErrors; + +public: + explicit DiagnosticErrorTrap(Diagnostic &Diag) + : Diag(Diag), PrevErrors(Diag.NumErrors) {} + + /// \brief Determine whether any errors have occurred since this + /// object instance was created. + bool hasErrorOccurred() const { + return Diag.NumErrors > PrevErrors; + } + + // Set to initial state of "no errors occurred". + void reset() { PrevErrors = Diag.NumErrors; } +}; + //===----------------------------------------------------------------------===// // DiagnosticBuilder //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h index 4229c6c62748..ad3ad4df136f 100644 --- a/clang/include/clang/Sema/Scope.h +++ b/clang/include/clang/Sema/Scope.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SEMA_SCOPE_H #define LLVM_CLANG_SEMA_SCOPE_H +#include "clang/Basic/Diagnostic.h" #include "llvm/ADT/SmallPtrSet.h" namespace clang { @@ -131,11 +132,12 @@ private: typedef llvm::SmallVector UsingDirectivesTy; UsingDirectivesTy UsingDirectives; - /// \brief The number of errors at the start of the given scope. - unsigned NumErrorsAtStart; + /// \brief Used to determine if errors occurred in this scope. + DiagnosticErrorTrap ErrorTrap; public: - Scope(Scope *Parent, unsigned ScopeFlags) { + Scope(Scope *Parent, unsigned ScopeFlags, Diagnostic &Diag) + : ErrorTrap(Diag) { Init(Parent, ScopeFlags); } @@ -214,13 +216,7 @@ public: void* getEntity() const { return Entity; } void setEntity(void *E) { Entity = E; } - /// \brief Retrieve the number of errors that had been emitted when we - /// entered this scope. - unsigned getNumErrorsAtStart() const { return NumErrorsAtStart; } - - void setNumErrorsAtStart(unsigned NumErrors) { - NumErrorsAtStart = NumErrors; - } + bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); } /// isClassScope - Return true if this scope is a class/struct/union scope. bool isClassScope() const { @@ -318,7 +314,7 @@ public: DeclsInScope.clear(); UsingDirectives.clear(); Entity = 0; - NumErrorsAtStart = 0; + ErrorTrap.reset(); } }; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 1790351f6326..e6cbc329bf5e 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3521,24 +3521,6 @@ public: } }; - /// \brief RAII class that determines when any errors have occurred - /// between the time the instance was created and the time it was - /// queried. - class ErrorTrap { - Sema &SemaRef; - unsigned PrevErrors; - - public: - explicit ErrorTrap(Sema &SemaRef) - : SemaRef(SemaRef), PrevErrors(SemaRef.getDiagnostics().getNumErrors()) {} - - /// \brief Determine whether any errors have occurred since this - /// object instance was created. - bool hasErrorOccurred() const { - return SemaRef.getDiagnostics().getNumErrors() > PrevErrors; - } - }; - /// \brief The current instantiation scope used to store local /// variables. LocalInstantiationScope *CurrentInstantiationScope; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 918c6718fcb3..fefe7871df00 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -305,9 +305,8 @@ void Parser::EnterScope(unsigned ScopeFlags) { N->Init(getCurScope(), ScopeFlags); Actions.CurScope = N; } else { - Actions.CurScope = new Scope(getCurScope(), ScopeFlags); + Actions.CurScope = new Scope(getCurScope(), ScopeFlags, Diags); } - getCurScope()->setNumErrorsAtStart(Diags.getNumErrors()); } /// ExitScope - Pop a scope off the scope stack. diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ceec0016e9ad..7c2a8fb105ef 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -696,7 +696,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (!D->getDeclName()) continue; // Diagnose unused variables in this scope. - if (S->getNumErrorsAtStart() == getDiagnostics().getNumErrors()) + if (!S->hasErrorOccurred()) DiagnoseUnusedDecl(D); // Remove this name from our lexical scope. diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7217b25652bd..38c1c3928d91 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4365,7 +4365,7 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, assert(ClassDecl && "DefineImplicitDefaultConstructor - invalid constructor"); ImplicitlyDefinedFunctionScope Scope(*this, Constructor); - ErrorTrap Trap(*this); + DiagnosticErrorTrap Trap(Diags); if (SetBaseOrMemberInitializers(Constructor, 0, 0, /*AnyErrors=*/false) || Trap.hasErrorOccurred()) { Diag(CurrentLocation, diag::note_member_synthesized_at) @@ -4473,7 +4473,7 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, ImplicitlyDefinedFunctionScope Scope(*this, Destructor); - ErrorTrap Trap(*this); + DiagnosticErrorTrap Trap(Diags); MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(), Destructor->getParent()); @@ -4878,7 +4878,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, CopyAssignOperator->setUsed(); ImplicitlyDefinedFunctionScope Scope(*this, CopyAssignOperator); - ErrorTrap Trap(*this); + DiagnosticErrorTrap Trap(Diags); // C++0x [class.copy]p30: // The implicitly-defined or explicitly-defaulted copy assignment operator @@ -5340,7 +5340,7 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, assert(ClassDecl && "DefineImplicitCopyConstructor - invalid constructor"); ImplicitlyDefinedFunctionScope Scope(*this, CopyConstructor); - ErrorTrap Trap(*this); + DiagnosticErrorTrap Trap(Diags); if (SetBaseOrMemberInitializers(CopyConstructor, 0, 0, /*AnyErrors=*/false) || Trap.hasErrorOccurred()) {