diff options
-rw-r--r-- | include/clang/Basic/Diagnostic.h | 24 | ||||
-rw-r--r-- | lib/Basic/Diagnostic.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 24 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 14 |
4 files changed, 62 insertions, 18 deletions
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 13e22a0d5d..bce43c2c0a 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -389,6 +389,28 @@ public: /// the diagnostic, this returns null. static const char *getWarningOptionForDiag(unsigned DiagID); + /// \brief Enumeration describing how the the emission of a diagnostic should + /// be treated when it occurs during C++ template argument deduction. + enum SFINAEResponse { + /// \brief The diagnostic should not be reported, but it should cause + /// template argument deduction to fail. + /// + /// The vast majority of errors that occur during template argument + /// deduction fall into this category. + SFINAE_SubstitutionFailure, + + /// \brief The diagnostic should be suppressed entirely. + /// + /// Warnings generally fall into this category. + SFINAE_Suppress, + + /// \brief The diagnostic should be reported. + /// + /// The diagnostic should be reported. Various fatal errors (e.g., + /// template instantiation depth exceeded) fall into this category. + SFINAE_Report + }; + /// \brief Determines whether the given built-in diagnostic ID is /// for an error that is suppressed if it occurs during C++ template /// argument deduction. @@ -397,7 +419,7 @@ public: /// deduction fails but no diagnostic is emitted. Certain classes of /// errors, such as those errors that involve C++ access control, /// are not SFINAE errors. - static bool isBuiltinSFINAEDiag(unsigned DiagID); + static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); /// getDiagnosticLevel - Based on the way the client configured the Diagnostic /// object, classify the specified diagnostic ID into a Level, consumable by diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index 31d3b34c81..21a8aeae42 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -124,10 +124,20 @@ const char *Diagnostic::getWarningOptionForDiag(unsigned DiagID) { return 0; } -bool Diagnostic::isBuiltinSFINAEDiag(unsigned DiagID) { - if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return Info->SFINAE && Info->Class == CLASS_ERROR; - return false; +Diagnostic::SFINAEResponse +Diagnostic::getDiagnosticSFINAEResponse(unsigned DiagID) { + if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) { + if (!Info->SFINAE) + return SFINAE_Report; + + if (Info->Class == CLASS_ERROR) + return SFINAE_SubstitutionFailure; + + // Suppress notes, warnings, and extensions; + return SFINAE_Suppress; + } + + return SFINAE_Report; } /// getDiagClass - Return the class field of the diagnostic. diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 7190cf0f1f..ccfbe1e00a 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -348,6 +348,30 @@ Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() { } } +Sema::SemaDiagnosticBuilder Sema::Diag(SourceLocation Loc, unsigned DiagID) { + if (isSFINAEContext()) { + switch (Diagnostic::getDiagnosticSFINAEResponse(DiagID)) { + case Diagnostic::SFINAE_Report: + // Fall through; we'll report the diagnostic below. + break; + + case Diagnostic::SFINAE_SubstitutionFailure: + // Count this failure so that we know that template argument deduction + // has failed. + ++NumSFINAEErrors; + // Fall through + + case Diagnostic::SFINAE_Suppress: + // Suppress this diagnostic. + Diags.setLastDiagnosticIgnored(); + return SemaDiagnosticBuilder(*this); + } + } + + DiagnosticBuilder DB = Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID); + return SemaDiagnosticBuilder(DB, *this, DiagID); +} + Sema::SemaDiagnosticBuilder Sema::Diag(SourceLocation Loc, const PartialDiagnostic& PD) { SemaDiagnosticBuilder Builder(Diag(Loc, PD.getDiagID())); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 7e2e614396..5986b479cd 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -610,19 +610,7 @@ public: }; /// \brief Emit a diagnostic. - SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) { - if (isSFINAEContext() && Diagnostic::isBuiltinSFINAEDiag(DiagID)) { - // If we encountered an error during template argument - // deduction, and that error is one of the SFINAE errors, - // suppress the diagnostic. - ++NumSFINAEErrors; - Diags.setLastDiagnosticIgnored(); - return SemaDiagnosticBuilder(*this); - } - - DiagnosticBuilder DB = Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID); - return SemaDiagnosticBuilder(DB, *this, DiagID); - } + SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID); /// \brief Emit a partial diagnostic. SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD); |