From 691f1ae7164ba78c3dd7ac20c487399935b9544b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 16 Apr 2009 04:12:40 +0000 Subject: [PATCH] change mappings to distinguish between "unset", "set by the user" and "set to the default value". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69264 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Diagnostic.h | 47 +++++++++++++++++++------------- lib/Basic/Diagnostic.cpp | 30 +++++++++++++++----- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 6ac2494d07..1d071110bc 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -61,10 +61,11 @@ namespace clang { /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this /// one). enum Mapping { - MAP_IGNORE = 0, //< Map this diagnostic to nothing, ignore it. - MAP_WARNING = 1, //< Map this diagnostic to a warning. - MAP_ERROR = 2, //< Map this diagnostic to an error. - MAP_FATAL = 3 //< Map this diagnostic to a fatal error. + // NOTE: 0 means "uncomputed". + MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it. + MAP_WARNING = 2, //< Map this diagnostic to a warning. + MAP_ERROR = 3, //< Map this diagnostic to an error. + MAP_FATAL = 4 //< Map this diagnostic to a fatal error. }; } @@ -154,8 +155,12 @@ private: DiagnosticClient *Client; /// DiagMappings - Mapping information for diagnostics. Mapping info is - /// packed into two bits per diagnostic. - unsigned char DiagMappings[diag::DIAG_UPPER_LIMIT/2]; + /// packed into four bits per diagnostic. The low three bits are the mapping + /// (an instance of diag::Mapping), or zero if unset. The high bit is set + /// when the mapping was established as a user mapping. If the high bit is + /// clear, then the low bits are set to the default value, and should be + /// mapped with -pedantic, -Werror, etc. + mutable unsigned char DiagMappings[diag::DIAG_UPPER_LIMIT/2]; /// ErrorOccurred / FatalErrorOccurred - This is set to true when an error or /// fatal error is emitted, and is sticky. @@ -219,21 +224,16 @@ public: void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; } /// setDiagnosticMapping - This allows the client to specify that certain - /// warnings are ignored. Only WARNINGs and EXTENSIONs can be mapped. + /// warnings are ignored. Notes can never be mapped, errors can only be + /// mapped to fatal, and WARNINGs and EXTENSIONs can be mapped arbitrarily. void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) { assert(Diag < diag::DIAG_UPPER_LIMIT && "Can only map builtin diagnostics"); assert((isBuiltinWarningOrExtension(Diag) || Map == diag::MAP_FATAL) && "Cannot map errors!"); - setDiagnosticMappingInternal(Diag, Map); + setDiagnosticMappingInternal(Diag, Map, true); } - /// getDiagnosticMapping - Return the mapping currently set for the specified - /// diagnostic. - diag::Mapping getDiagnosticMapping(diag::kind Diag) const { - return (diag::Mapping)((DiagMappings[Diag/2] >> (Diag & 1)*4) & 7); - } - bool hasErrorOccurred() const { return ErrorOccurred; } bool hasFatalErrorOccurred() const { return FatalErrorOccurred; } @@ -301,11 +301,20 @@ public: void Clear() { CurDiagID = ~0U; } private: - void setDiagnosticMappingInternal(unsigned Diag, unsigned Map) { - unsigned char &Slot = DiagMappings[Diag/2]; - unsigned Bits = (Diag & 1)*4; - Slot &= ~(7 << Bits); - Slot |= Map << Bits; + /// getDiagnosticMappingInfo - Return the mapping info currently set for the + /// specified builtin diagnostic. This returns the high bit encoding, or zero + /// if the field is completely uninitialized. + unsigned getDiagnosticMappingInfo(diag::kind Diag) const { + return (diag::Mapping)((DiagMappings[Diag/2] >> (Diag & 1)*4) & 15); + } + + void setDiagnosticMappingInternal(unsigned DiagId, unsigned Map, + bool isUser) const { + if (isUser) Map |= 8; // Set the high bit for user mappings. + unsigned char &Slot = DiagMappings[DiagId/2]; + unsigned Shift = (DiagId & 1)*4; + Slot &= ~(15 << Shift); + Slot |= Map << Shift; } /// getDiagnosticLevel - This is an internal implementation helper used when diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index caf30fac63..19bfeeea72 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -43,7 +43,7 @@ struct DefaultMappingInfo { }; static const DefaultMappingInfo DefaultMappings[] = { -#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC) { diag::ENUM, DEFAULT_MAPPING }, +#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC) { diag::ENUM, DEFAULT_MAPPING-1 }, #include "clang/Basic/DiagnosticCommonKinds.inc" #include "clang/Basic/DiagnosticDriverKinds.inc" #include "clang/Basic/DiagnosticFrontendKinds.inc" @@ -56,6 +56,16 @@ static const DefaultMappingInfo DefaultMappings[] = { }; #undef DIAG +static unsigned GetDefaultDiagMapping(unsigned DiagID) { + // FIXME: Binary search. + for (unsigned i = 0, e = sizeof(DefaultMappings)/sizeof(DefaultMappings[0]); + i != e; ++i) + if (DefaultMappings[i].DiagID == DiagID) + return DefaultMappings[i].Mapping+1; + return diag::MAP_FATAL; +} + + // Diagnostic classes. enum { CLASS_NOTE = 0x01, @@ -264,11 +274,8 @@ Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) { ArgToStringFn = DummyArgToStringFn; ArgToStringCookie = 0; - // Set all mappings to their default. - for (unsigned i = 0, e = sizeof(DefaultMappings)/sizeof(DefaultMappings[0]); - i != e; ++i) - setDiagnosticMappingInternal(DefaultMappings[i].DiagID, - DefaultMappings[i].Mapping); + // Set all mappings to 'unset'. + memset(DiagMappings, 0, sizeof(DiagMappings)); } Diagnostic::~Diagnostic() { @@ -353,7 +360,16 @@ Diagnostic::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const { // Specific non-error diagnostics may be mapped to various levels from ignored // to error. Errors can only be mapped to fatal. Diagnostic::Level Result = Diagnostic::Fatal; - switch (getDiagnosticMapping((diag::kind)DiagID)) { + + // Get the mapping information, if unset, compute it lazily. + unsigned MappingInfo = getDiagnosticMappingInfo((diag::kind)DiagID); + if (MappingInfo == 0) { + MappingInfo = GetDefaultDiagMapping(DiagID); + setDiagnosticMappingInternal(DiagID, MappingInfo, false); + } + + switch (MappingInfo & 7) { + default: assert(0 && "Unknown mapping!"); case diag::MAP_IGNORE: return Diagnostic::Ignored; case diag::MAP_ERROR: -- 2.40.0