diff --git a/clang/Basic/Diagnostic.cpp b/clang/Basic/Diagnostic.cpp index bef3033af294..239211bcd46c 100644 --- a/clang/Basic/Diagnostic.cpp +++ b/clang/Basic/Diagnostic.cpp @@ -36,8 +36,9 @@ static unsigned char DiagnosticFlags[] = { /// getDiagClass - Return the class field of the diagnostic. /// -static unsigned getDiagClass(unsigned DiagID) { - assert(DiagID < diag::NUM_DIAGNOSTICS && "Diagnostic ID out of range!"); +static unsigned getBuiltinDiagClass(unsigned DiagID) { + assert(DiagID < diag::NUM_BUILTIN_DIAGNOSTICS && + "Diagnostic ID out of range!"); return DiagnosticFlags[DiagID] & class_mask; } @@ -61,25 +62,34 @@ Diagnostic::Diagnostic(DiagnosticClient &client) : Client(client) { NumErrors = 0; } -/// isNoteWarningOrExtension - Return true if the unmapped diagnostic level of -/// the specified diagnostic ID is a Note, Warning, or Extension. -bool Diagnostic::isNoteWarningOrExtension(unsigned DiagID) { - return getDiagClass(DiagID) < ERROR; +/// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic +/// level of the specified diagnostic ID is a Note, Warning, or Extension. +/// Note that this only works on builtin diagnostics, not custom ones. +bool Diagnostic::isBuiltinNoteWarningOrExtension(unsigned DiagID) { + return DiagID < diag::NUM_BUILTIN_DIAGNOSTICS && + getBuiltinDiagClass(DiagID) < ERROR; } /// getDescription - Given a diagnostic ID, return a description of the /// issue. const char *Diagnostic::getDescription(unsigned DiagID) { - assert(DiagID < diag::NUM_DIAGNOSTICS && "Diagnostic ID out of range!"); - return DiagnosticText[DiagID]; + if (DiagID < diag::NUM_BUILTIN_DIAGNOSTICS) + return DiagnosticText[DiagID]; + else + assert(0 && "FIXME: IMPLEMENT"); } /// getDiagnosticLevel - Based on the way the client configured the Diagnostic /// object, classify the specified diagnostic ID into a Level, consumable by /// the DiagnosticClient. Diagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const { - unsigned DiagClass = getDiagClass(DiagID); + if (DiagID >= diag::NUM_BUILTIN_DIAGNOSTICS) { + // FIXME: HAndle custom here. + assert(0 && "unimp"); + } + + unsigned DiagClass = getBuiltinDiagClass(DiagID); // Specific non-error diagnostics may be mapped to various levels from ignored // to error. @@ -137,8 +147,8 @@ void Diagnostic::Report(SourceLocation Pos, unsigned DiagID, return; // Finally, report it. - Client.HandleDiagnostic(DiagLevel, Pos, (diag::kind)DiagID, Strs, NumStrs, - Ranges, NumRanges); + Client.HandleDiagnostic(*this, DiagLevel, Pos, (diag::kind)DiagID, + Strs, NumStrs, Ranges, NumRanges); ++NumDiagnostics; } diff --git a/clang/Driver/DiagChecker.cpp b/clang/Driver/DiagChecker.cpp index 81d3e1b8f5af..53eed43c2cc7 100644 --- a/clang/Driver/DiagChecker.cpp +++ b/clang/Driver/DiagChecker.cpp @@ -96,8 +96,8 @@ static void FindExpectedDiags(Preprocessor &PP, unsigned MainFileID, // Turn off all warnings from relexing or preprocessing. PP.getDiagnostics().setWarnOnExtensions(false); PP.getDiagnostics().setErrorOnExtensions(false); - for (unsigned i = 0; i != diag::NUM_DIAGNOSTICS; ++i) - if (PP.getDiagnostics().isNoteWarningOrExtension((diag::kind)i)) + for (unsigned i = 0; i != diag::NUM_BUILTIN_DIAGNOSTICS; ++i) + if (PP.getDiagnostics().isBuiltinNoteWarningOrExtension((diag::kind)i)) PP.getDiagnostics().setDiagnosticMapping((diag::kind)i, diag::MAP_IGNORE); Token Tok; diff --git a/clang/Driver/RewriteTest.cpp b/clang/Driver/RewriteTest.cpp index 5d14f0355531..808fe9879825 100644 --- a/clang/Driver/RewriteTest.cpp +++ b/clang/Driver/RewriteTest.cpp @@ -17,6 +17,7 @@ #include "clang/AST/ASTConsumer.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/Diagnostic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "clang/Lex/Lexer.h" @@ -869,6 +870,7 @@ Stmt *RewriteTest::RewriteAtEncode(ObjCEncodeExpr *Exp) { return Exp; } + // Replace this subexpr in the parent. delete Exp; return Replacement; } diff --git a/clang/Driver/TextDiagnosticBuffer.cpp b/clang/Driver/TextDiagnosticBuffer.cpp index 1f6075ea921e..d0e2f900c554 100644 --- a/clang/Driver/TextDiagnosticBuffer.cpp +++ b/clang/Driver/TextDiagnosticBuffer.cpp @@ -17,7 +17,8 @@ using namespace clang; /// HandleDiagnostic - Store the errors & warnings that are reported. /// -void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic::Level Level, +void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic &Diags, + Diagnostic::Level Level, SourceLocation Pos, diag::kind ID, const std::string *Strs, @@ -27,12 +28,12 @@ void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic::Level Level, switch (Level) { default: assert(0 && "Diagnostic not handled during diagnostic buffering!"); case Diagnostic::Warning: - Warnings.push_back(std::make_pair(Pos, FormatDiagnostic(Level, ID, Strs, - NumStrs))); + Warnings.push_back(std::make_pair(Pos, FormatDiagnostic(Diags, Level, ID, + Strs, NumStrs))); break; case Diagnostic::Error: - Errors.push_back(std::make_pair(Pos, FormatDiagnostic(Level, ID, Strs, - NumStrs))); + Errors.push_back(std::make_pair(Pos, FormatDiagnostic(Diags, Level, ID, + Strs, NumStrs))); break; } } diff --git a/clang/Driver/TextDiagnosticBuffer.h b/clang/Driver/TextDiagnosticBuffer.h index 34fbc6e27a1c..d155874458f5 100644 --- a/clang/Driver/TextDiagnosticBuffer.h +++ b/clang/Driver/TextDiagnosticBuffer.h @@ -38,7 +38,7 @@ public: const_iterator warn_begin() const { return Warnings.begin(); } const_iterator warn_end() const { return Warnings.end(); } - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, + virtual void HandleDiagnostic(Diagnostic &Diags, Diagnostic::Level DiagLevel, SourceLocation Pos, diag::kind ID, const std::string *Strs, unsigned NumStrs, diff --git a/clang/Driver/TextDiagnosticPrinter.cpp b/clang/Driver/TextDiagnosticPrinter.cpp index 81c73fd533fd..463a3d7e8ed1 100644 --- a/clang/Driver/TextDiagnosticPrinter.cpp +++ b/clang/Driver/TextDiagnosticPrinter.cpp @@ -97,7 +97,8 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, CaratLine[i] = '~'; } -void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, +void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic &Diags, + Diagnostic::Level Level, SourceLocation Pos, diag::kind ID, const std::string *Strs, @@ -149,7 +150,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, break; } - std::cerr << FormatDiagnostic(Level, ID, Strs, NumStrs) << "\n"; + std::cerr << FormatDiagnostic(Diags, Level, ID, Strs, NumStrs) << "\n"; if (!NoCaretDiagnostics && Pos.isValid()) { // Get the line of the source file. diff --git a/clang/Driver/TextDiagnosticPrinter.h b/clang/Driver/TextDiagnosticPrinter.h index 3df38c9d42f0..beb9d808e992 100644 --- a/clang/Driver/TextDiagnosticPrinter.h +++ b/clang/Driver/TextDiagnosticPrinter.h @@ -32,7 +32,7 @@ public: std::string &CaratLine, const std::string &SourceLine); - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, + virtual void HandleDiagnostic(Diagnostic &Diags, Diagnostic::Level DiagLevel, SourceLocation Pos, diag::kind ID, const std::string *Strs, unsigned NumStrs, diff --git a/clang/Driver/TextDiagnostics.cpp b/clang/Driver/TextDiagnostics.cpp index 3c29cca696cf..5b14cdda8215 100644 --- a/clang/Driver/TextDiagnostics.cpp +++ b/clang/Driver/TextDiagnostics.cpp @@ -19,11 +19,12 @@ using namespace clang; TextDiagnostics:: ~TextDiagnostics() {} -std::string TextDiagnostics::FormatDiagnostic(Diagnostic::Level Level, +std::string TextDiagnostics::FormatDiagnostic(Diagnostic &Diags, + Diagnostic::Level Level, diag::kind ID, const std::string *Strs, unsigned NumStrs) { - std::string Msg = Diagnostic::getDescription(ID); + std::string Msg = Diags.getDescription(ID); // Replace all instances of %0 in Msg with 'Extra'. for (unsigned i = 0; i < Msg.size() - 1; ++i) { @@ -43,8 +44,7 @@ bool TextDiagnostics::IgnoreDiagnostic(Diagnostic::Level Level, if (Pos.isValid()) { // If this is a warning or note, and if it a system header, suppress the // diagnostic. - if (Level == Diagnostic::Warning || - Level == Diagnostic::Note) { + if (Level == Diagnostic::Warning || Level == Diagnostic::Note) { if (const FileEntry *F = SourceMgr.getFileEntryForLoc(Pos)) { DirectoryLookup::DirType DirInfo = TheHeaderSearch->getFileDirFlavor(F); if (DirInfo == DirectoryLookup::SystemHeaderDir || diff --git a/clang/Driver/TextDiagnostics.h b/clang/Driver/TextDiagnostics.h index 2ab0066d034b..27d9d3a8e426 100644 --- a/clang/Driver/TextDiagnostics.h +++ b/clang/Driver/TextDiagnostics.h @@ -26,7 +26,7 @@ class TextDiagnostics : public DiagnosticClient { protected: SourceManager &SourceMgr; - std::string FormatDiagnostic(Diagnostic::Level Level, + std::string FormatDiagnostic(Diagnostic &Diags, Diagnostic::Level Level, diag::kind ID, const std::string *Strs, unsigned NumStrs); @@ -38,7 +38,7 @@ public: virtual bool IgnoreDiagnostic(Diagnostic::Level Level, SourceLocation Pos); - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, + virtual void HandleDiagnostic(Diagnostic &Diags, Diagnostic::Level DiagLevel, SourceLocation Pos, diag::kind ID, const std::string *Strs, unsigned NumStrs, diff --git a/clang/Lex/Lexer.cpp b/clang/Lex/Lexer.cpp index ffa352f37540..f712bec7194b 100644 --- a/clang/Lex/Lexer.cpp +++ b/clang/Lex/Lexer.cpp @@ -304,13 +304,13 @@ SourceLocation Lexer::getSourceLocation(const char *Loc) const { /// position in the current buffer into a SourceLocation object for rendering. void Lexer::Diag(const char *Loc, unsigned DiagID, const std::string &Msg) const { - if (LexingRawMode && Diagnostic::isNoteWarningOrExtension(DiagID)) + if (LexingRawMode && Diagnostic::isBuiltinNoteWarningOrExtension(DiagID)) return; PP->Diag(getSourceLocation(Loc), DiagID, Msg); } void Lexer::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) const { - if (LexingRawMode && Diagnostic::isNoteWarningOrExtension(DiagID)) + if (LexingRawMode && Diagnostic::isBuiltinNoteWarningOrExtension(DiagID)) return; PP->Diag(Loc, DiagID, Msg); } diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index 9d7188639f54..2d2fffad37b0 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -28,7 +28,7 @@ namespace clang { enum kind { #define DIAG(ENUM,FLAGS,DESC) ENUM, #include "DiagnosticKinds.def" - NUM_DIAGNOSTICS + NUM_BUILTIN_DIAGNOSTICS }; /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs @@ -54,7 +54,7 @@ class Diagnostic { /// DiagMappings - Mapping information for diagnostics. Mapping info is /// packed into two bits per diagnostic. - unsigned char DiagMappings[(diag::NUM_DIAGNOSTICS+3)/4]; + unsigned char DiagMappings[(diag::NUM_BUILTIN_DIAGNOSTICS+3)/4]; /// ErrorOccurred - This is set to true when an error is emitted, and is /// sticky. @@ -88,7 +88,9 @@ public: /// setDiagnosticMapping - This allows the client to specify that certain /// warnings are ignored. Only NOTEs, WARNINGs, and EXTENSIONs can be mapped. void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) { - assert(isNoteWarningOrExtension(Diag) && "Cannot map errors!"); + assert(Diag < diag::NUM_BUILTIN_DIAGNOSTICS && + "Can only map builtin diagnostics"); + assert(isBuiltinNoteWarningOrExtension(Diag) && "Cannot map errors!"); unsigned char &Slot = DiagMappings[Diag/4]; unsigned Bits = (Diag & 3)*2; Slot &= ~(3 << Bits); @@ -112,16 +114,17 @@ public: /// getDescription - Given a diagnostic ID, return a description of the /// issue. - static const char *getDescription(unsigned DiagID); + const char *getDescription(unsigned DiagID); - /// Level - The level of the diagnostic + /// Level - The level of the diagnostic, after it has been through mapping. enum Level { Ignored, Note, Warning, Error, Fatal }; - /// isNoteWarningOrExtension - Return true if the unmapped diagnostic level of - /// the specified diagnostic ID is a Note, Warning, or Extension. - static bool isNoteWarningOrExtension(unsigned DiagID); + /// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic + /// level of the specified diagnostic ID is a Note, Warning, or Extension. + /// Note that this only works on builtin diagnostics, not custom ones. + static bool isBuiltinNoteWarningOrExtension(unsigned DiagID); /// getDiagnosticLevel - Based on the way the client configured the Diagnostic /// object, classify the specified diagnostic ID into a Level, consumable by @@ -148,7 +151,8 @@ public: /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or /// capturing it to a log as needed. - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, SourceLocation Pos, + virtual void HandleDiagnostic(Diagnostic &Diags, + Diagnostic::Level DiagLevel, SourceLocation Pos, diag::kind ID, const std::string *Strs, unsigned NumStrs, const SourceRange *Ranges, unsigned NumRanges) = 0;