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.
///
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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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.

View File

@ -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,

View File

@ -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 ||

View File

@ -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,

View File

@ -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);
}

View File

@ -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;