start partitioning the diagnostics into two classes: those

that are builtin and those that are aren't.  This is a bunch
of API refactoring that will make this possible, but there is
no functionality change yet.

llvm-svn: 44473
This commit is contained in:
Chris Lattner 2007-11-30 22:53:43 +00:00
parent 7a9a38abe0
commit 4431a1b19b
11 changed files with 57 additions and 39 deletions

View File

@ -36,8 +36,9 @@ static unsigned char DiagnosticFlags[] = {
/// getDiagClass - Return the class field of the diagnostic. /// getDiagClass - Return the class field of the diagnostic.
/// ///
static unsigned getDiagClass(unsigned DiagID) { static unsigned getBuiltinDiagClass(unsigned DiagID) {
assert(DiagID < diag::NUM_DIAGNOSTICS && "Diagnostic ID out of range!"); assert(DiagID < diag::NUM_BUILTIN_DIAGNOSTICS &&
"Diagnostic ID out of range!");
return DiagnosticFlags[DiagID] & class_mask; return DiagnosticFlags[DiagID] & class_mask;
} }
@ -61,25 +62,34 @@ Diagnostic::Diagnostic(DiagnosticClient &client) : Client(client) {
NumErrors = 0; NumErrors = 0;
} }
/// isNoteWarningOrExtension - Return true if the unmapped diagnostic level of /// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic
/// the specified diagnostic ID is a Note, Warning, or Extension. /// level of the specified diagnostic ID is a Note, Warning, or Extension.
bool Diagnostic::isNoteWarningOrExtension(unsigned DiagID) { /// Note that this only works on builtin diagnostics, not custom ones.
return getDiagClass(DiagID) < ERROR; bool Diagnostic::isBuiltinNoteWarningOrExtension(unsigned DiagID) {
return DiagID < diag::NUM_BUILTIN_DIAGNOSTICS &&
getBuiltinDiagClass(DiagID) < ERROR;
} }
/// getDescription - Given a diagnostic ID, return a description of the /// getDescription - Given a diagnostic ID, return a description of the
/// issue. /// issue.
const char *Diagnostic::getDescription(unsigned DiagID) { const char *Diagnostic::getDescription(unsigned DiagID) {
assert(DiagID < diag::NUM_DIAGNOSTICS && "Diagnostic ID out of range!"); if (DiagID < diag::NUM_BUILTIN_DIAGNOSTICS)
return DiagnosticText[DiagID]; return DiagnosticText[DiagID];
else
assert(0 && "FIXME: IMPLEMENT");
} }
/// getDiagnosticLevel - Based on the way the client configured the Diagnostic /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
/// object, classify the specified diagnostic ID into a Level, consumable by /// object, classify the specified diagnostic ID into a Level, consumable by
/// the DiagnosticClient. /// the DiagnosticClient.
Diagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const { 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 // Specific non-error diagnostics may be mapped to various levels from ignored
// to error. // to error.
@ -137,8 +147,8 @@ void Diagnostic::Report(SourceLocation Pos, unsigned DiagID,
return; return;
// Finally, report it. // Finally, report it.
Client.HandleDiagnostic(DiagLevel, Pos, (diag::kind)DiagID, Strs, NumStrs, Client.HandleDiagnostic(*this, DiagLevel, Pos, (diag::kind)DiagID,
Ranges, NumRanges); Strs, NumStrs, Ranges, NumRanges);
++NumDiagnostics; ++NumDiagnostics;
} }

View File

@ -96,8 +96,8 @@ static void FindExpectedDiags(Preprocessor &PP, unsigned MainFileID,
// Turn off all warnings from relexing or preprocessing. // Turn off all warnings from relexing or preprocessing.
PP.getDiagnostics().setWarnOnExtensions(false); PP.getDiagnostics().setWarnOnExtensions(false);
PP.getDiagnostics().setErrorOnExtensions(false); PP.getDiagnostics().setErrorOnExtensions(false);
for (unsigned i = 0; i != diag::NUM_DIAGNOSTICS; ++i) for (unsigned i = 0; i != diag::NUM_BUILTIN_DIAGNOSTICS; ++i)
if (PP.getDiagnostics().isNoteWarningOrExtension((diag::kind)i)) if (PP.getDiagnostics().isBuiltinNoteWarningOrExtension((diag::kind)i))
PP.getDiagnostics().setDiagnosticMapping((diag::kind)i, diag::MAP_IGNORE); PP.getDiagnostics().setDiagnosticMapping((diag::kind)i, diag::MAP_IGNORE);
Token Tok; Token Tok;

View File

@ -17,6 +17,7 @@
#include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTConsumer.h"
#include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManager.h"
#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "clang/Lex/Lexer.h" #include "clang/Lex/Lexer.h"
@ -869,6 +870,7 @@ Stmt *RewriteTest::RewriteAtEncode(ObjCEncodeExpr *Exp) {
return Exp; return Exp;
} }
// Replace this subexpr in the parent.
delete Exp; delete Exp;
return Replacement; return Replacement;
} }

View File

@ -17,7 +17,8 @@ using namespace clang;
/// HandleDiagnostic - Store the errors & warnings that are reported. /// HandleDiagnostic - Store the errors & warnings that are reported.
/// ///
void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic::Level Level, void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic &Diags,
Diagnostic::Level Level,
SourceLocation Pos, SourceLocation Pos,
diag::kind ID, diag::kind ID,
const std::string *Strs, const std::string *Strs,
@ -27,12 +28,12 @@ void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic::Level Level,
switch (Level) { switch (Level) {
default: assert(0 && "Diagnostic not handled during diagnostic buffering!"); default: assert(0 && "Diagnostic not handled during diagnostic buffering!");
case Diagnostic::Warning: case Diagnostic::Warning:
Warnings.push_back(std::make_pair(Pos, FormatDiagnostic(Level, ID, Strs, Warnings.push_back(std::make_pair(Pos, FormatDiagnostic(Diags, Level, ID,
NumStrs))); Strs, NumStrs)));
break; break;
case Diagnostic::Error: case Diagnostic::Error:
Errors.push_back(std::make_pair(Pos, FormatDiagnostic(Level, ID, Strs, Errors.push_back(std::make_pair(Pos, FormatDiagnostic(Diags, Level, ID,
NumStrs))); Strs, NumStrs)));
break; break;
} }
} }

View File

@ -38,7 +38,7 @@ public:
const_iterator warn_begin() const { return Warnings.begin(); } const_iterator warn_begin() const { return Warnings.begin(); }
const_iterator warn_end() const { return Warnings.end(); } const_iterator warn_end() const { return Warnings.end(); }
virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, virtual void HandleDiagnostic(Diagnostic &Diags, Diagnostic::Level DiagLevel,
SourceLocation Pos, SourceLocation Pos,
diag::kind ID, const std::string *Strs, diag::kind ID, const std::string *Strs,
unsigned NumStrs, unsigned NumStrs,

View File

@ -97,7 +97,8 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R,
CaratLine[i] = '~'; CaratLine[i] = '~';
} }
void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic &Diags,
Diagnostic::Level Level,
SourceLocation Pos, SourceLocation Pos,
diag::kind ID, diag::kind ID,
const std::string *Strs, const std::string *Strs,
@ -149,7 +150,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
break; break;
} }
std::cerr << FormatDiagnostic(Level, ID, Strs, NumStrs) << "\n"; std::cerr << FormatDiagnostic(Diags, Level, ID, Strs, NumStrs) << "\n";
if (!NoCaretDiagnostics && Pos.isValid()) { if (!NoCaretDiagnostics && Pos.isValid()) {
// Get the line of the source file. // Get the line of the source file.

View File

@ -32,7 +32,7 @@ public:
std::string &CaratLine, std::string &CaratLine,
const std::string &SourceLine); const std::string &SourceLine);
virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, virtual void HandleDiagnostic(Diagnostic &Diags, Diagnostic::Level DiagLevel,
SourceLocation Pos, SourceLocation Pos,
diag::kind ID, const std::string *Strs, diag::kind ID, const std::string *Strs,
unsigned NumStrs, unsigned NumStrs,

View File

@ -19,11 +19,12 @@ using namespace clang;
TextDiagnostics:: ~TextDiagnostics() {} TextDiagnostics:: ~TextDiagnostics() {}
std::string TextDiagnostics::FormatDiagnostic(Diagnostic::Level Level, std::string TextDiagnostics::FormatDiagnostic(Diagnostic &Diags,
Diagnostic::Level Level,
diag::kind ID, diag::kind ID,
const std::string *Strs, const std::string *Strs,
unsigned NumStrs) { unsigned NumStrs) {
std::string Msg = Diagnostic::getDescription(ID); std::string Msg = Diags.getDescription(ID);
// Replace all instances of %0 in Msg with 'Extra'. // Replace all instances of %0 in Msg with 'Extra'.
for (unsigned i = 0; i < Msg.size() - 1; ++i) { for (unsigned i = 0; i < Msg.size() - 1; ++i) {
@ -43,8 +44,7 @@ bool TextDiagnostics::IgnoreDiagnostic(Diagnostic::Level Level,
if (Pos.isValid()) { if (Pos.isValid()) {
// If this is a warning or note, and if it a system header, suppress the // If this is a warning or note, and if it a system header, suppress the
// diagnostic. // diagnostic.
if (Level == Diagnostic::Warning || if (Level == Diagnostic::Warning || Level == Diagnostic::Note) {
Level == Diagnostic::Note) {
if (const FileEntry *F = SourceMgr.getFileEntryForLoc(Pos)) { if (const FileEntry *F = SourceMgr.getFileEntryForLoc(Pos)) {
DirectoryLookup::DirType DirInfo = TheHeaderSearch->getFileDirFlavor(F); DirectoryLookup::DirType DirInfo = TheHeaderSearch->getFileDirFlavor(F);
if (DirInfo == DirectoryLookup::SystemHeaderDir || if (DirInfo == DirectoryLookup::SystemHeaderDir ||

View File

@ -26,7 +26,7 @@ class TextDiagnostics : public DiagnosticClient {
protected: protected:
SourceManager &SourceMgr; SourceManager &SourceMgr;
std::string FormatDiagnostic(Diagnostic::Level Level, std::string FormatDiagnostic(Diagnostic &Diags, Diagnostic::Level Level,
diag::kind ID, diag::kind ID,
const std::string *Strs, const std::string *Strs,
unsigned NumStrs); unsigned NumStrs);
@ -38,7 +38,7 @@ public:
virtual bool IgnoreDiagnostic(Diagnostic::Level Level, virtual bool IgnoreDiagnostic(Diagnostic::Level Level,
SourceLocation Pos); SourceLocation Pos);
virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, virtual void HandleDiagnostic(Diagnostic &Diags, Diagnostic::Level DiagLevel,
SourceLocation Pos, SourceLocation Pos,
diag::kind ID, const std::string *Strs, diag::kind ID, const std::string *Strs,
unsigned NumStrs, unsigned NumStrs,

View File

@ -304,13 +304,13 @@ SourceLocation Lexer::getSourceLocation(const char *Loc) const {
/// position in the current buffer into a SourceLocation object for rendering. /// position in the current buffer into a SourceLocation object for rendering.
void Lexer::Diag(const char *Loc, unsigned DiagID, void Lexer::Diag(const char *Loc, unsigned DiagID,
const std::string &Msg) const { const std::string &Msg) const {
if (LexingRawMode && Diagnostic::isNoteWarningOrExtension(DiagID)) if (LexingRawMode && Diagnostic::isBuiltinNoteWarningOrExtension(DiagID))
return; return;
PP->Diag(getSourceLocation(Loc), DiagID, Msg); PP->Diag(getSourceLocation(Loc), DiagID, Msg);
} }
void Lexer::Diag(SourceLocation Loc, unsigned DiagID, void Lexer::Diag(SourceLocation Loc, unsigned DiagID,
const std::string &Msg) const { const std::string &Msg) const {
if (LexingRawMode && Diagnostic::isNoteWarningOrExtension(DiagID)) if (LexingRawMode && Diagnostic::isBuiltinNoteWarningOrExtension(DiagID))
return; return;
PP->Diag(Loc, DiagID, Msg); PP->Diag(Loc, DiagID, Msg);
} }

View File

@ -28,7 +28,7 @@ namespace clang {
enum kind { enum kind {
#define DIAG(ENUM,FLAGS,DESC) ENUM, #define DIAG(ENUM,FLAGS,DESC) ENUM,
#include "DiagnosticKinds.def" #include "DiagnosticKinds.def"
NUM_DIAGNOSTICS NUM_BUILTIN_DIAGNOSTICS
}; };
/// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs /// 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 /// DiagMappings - Mapping information for diagnostics. Mapping info is
/// packed into two bits per diagnostic. /// 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 /// ErrorOccurred - This is set to true when an error is emitted, and is
/// sticky. /// sticky.
@ -88,7 +88,9 @@ public:
/// setDiagnosticMapping - This allows the client to specify that certain /// setDiagnosticMapping - This allows the client to specify that certain
/// warnings are ignored. Only NOTEs, WARNINGs, and EXTENSIONs can be mapped. /// warnings are ignored. Only NOTEs, WARNINGs, and EXTENSIONs can be mapped.
void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) { 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 char &Slot = DiagMappings[Diag/4];
unsigned Bits = (Diag & 3)*2; unsigned Bits = (Diag & 3)*2;
Slot &= ~(3 << Bits); Slot &= ~(3 << Bits);
@ -112,16 +114,17 @@ public:
/// getDescription - Given a diagnostic ID, return a description of the /// getDescription - Given a diagnostic ID, return a description of the
/// issue. /// 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 { enum Level {
Ignored, Note, Warning, Error, Fatal Ignored, Note, Warning, Error, Fatal
}; };
/// isNoteWarningOrExtension - Return true if the unmapped diagnostic level of /// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic
/// the specified diagnostic ID is a Note, Warning, or Extension. /// level of the specified diagnostic ID is a Note, Warning, or Extension.
static bool isNoteWarningOrExtension(unsigned DiagID); /// 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 /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
/// object, classify the specified diagnostic ID into a Level, consumable by /// 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 /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
/// capturing it to a log as needed. /// 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, diag::kind ID, const std::string *Strs,
unsigned NumStrs, const SourceRange *Ranges, unsigned NumStrs, const SourceRange *Ranges,
unsigned NumRanges) = 0; unsigned NumRanges) = 0;