mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-26 11:25:27 +00:00
Implement support for arbitrarily mapping non-error diagnostics to be either
ignored, warned about, or error'd. Use this to implement the -Wunused_macros command line option. llvm-svn: 38676
This commit is contained in:
parent
ecbf7b4bb0
commit
ae41157ee5
@ -51,6 +51,14 @@ static const char * const DiagnosticText[] = {
|
||||
0
|
||||
};
|
||||
|
||||
Diagnostic::Diagnostic(DiagnosticClient &client) : Client(client) {
|
||||
WarningsAsErrors = false;
|
||||
WarnOnExtensions = false;
|
||||
ErrorOnExtensions = false;
|
||||
// Clear all mappings, setting them to MAP_DEFAULT.
|
||||
memset(DiagMappings, 0, sizeof(DiagMappings));
|
||||
}
|
||||
|
||||
/// isNoteWarningOrExtension - Return true if the unmapped diagnostic level of
|
||||
/// the specified diagnostic ID is a Note, Warning, or Extension.
|
||||
bool Diagnostic::isNoteWarningOrExtension(unsigned DiagID) {
|
||||
@ -71,8 +79,16 @@ const char *Diagnostic::getDescription(unsigned DiagID) {
|
||||
Diagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const {
|
||||
unsigned DiagClass = getDiagClass(DiagID);
|
||||
|
||||
// TODO: specific diagnostics may be enabled or disabled. Filter those based
|
||||
// on their DiagID.
|
||||
// Specific non-error diagnostics may be mapped to various levels from ignored
|
||||
// to error.
|
||||
if (DiagClass < ERROR) {
|
||||
switch (getDiagnosticMapping((diag::kind)DiagID)) {
|
||||
case diag::MAP_DEFAULT: break;
|
||||
case diag::MAP_IGNORE: return Ignored;
|
||||
case diag::MAP_WARNING: DiagClass = WARNING; break;
|
||||
case diag::MAP_ERROR: DiagClass = ERROR; break;
|
||||
}
|
||||
}
|
||||
|
||||
// Map diagnostic classes based on command line argument settings.
|
||||
if (DiagClass == EXTENSION) {
|
||||
|
@ -78,12 +78,21 @@ static cl::opt<bool>
|
||||
ErrorOnExtensions("pedantic-errors",
|
||||
cl::desc("Issue an error on uses of GCC extensions"));
|
||||
|
||||
static cl::opt<bool>
|
||||
WarnUnusedMacros("Wunused_macros",
|
||||
cl::desc("Warn for unused macros in the main translation unit"));
|
||||
|
||||
|
||||
/// InitializeDiagnostics - Initialize the diagnostic object, based on the
|
||||
/// current command line option settings.
|
||||
static void InitializeDiagnostics(Diagnostic &Diags) {
|
||||
Diags.setWarningsAsErrors(WarningsAsErrors);
|
||||
Diags.setWarnOnExtensions(WarnOnExtensions);
|
||||
Diags.setErrorOnExtensions(ErrorOnExtensions);
|
||||
|
||||
// Silence the "macro is not used" warning unless requested.
|
||||
if (!WarnUnusedMacros)
|
||||
Diags.setDiagnosticMapping(diag::pp_macro_not_used, diag::MAP_IGNORE);
|
||||
}
|
||||
|
||||
static cl::opt<bool>
|
||||
|
@ -23,11 +23,12 @@ II. Current advantages over GCC:
|
||||
* All languages supported linked into same library (no cc1,cc1obj, ...).
|
||||
* mmap's code in read-only, does not dirty the pages like GCC (mem footprint).
|
||||
* BSD License, can be linked into non-GPL projects.
|
||||
* Full diagnostic control, per diagnostic.
|
||||
* Faster than GCC at lexing and preprocessing.
|
||||
|
||||
Future Features:
|
||||
* Full diagnostic control, per diagnostic (use enums).
|
||||
* Fine grained control within the source (#pragma enable/disable warning)
|
||||
* Faster than GCC, preprocessing, parsing, IR generation.
|
||||
* Fine grained diag control within the source (#pragma enable/disable warning).
|
||||
* Faster than GCC at parsing, IR generation.
|
||||
* Better token tracking within macros? (Token came from this line, which is
|
||||
a macro argument instantiated here, recursively instantiated here).
|
||||
* Fast #import!!
|
||||
@ -118,4 +119,5 @@ Cocoa GUI Front-end:
|
||||
* Tight integration with compiler components.
|
||||
* Primary advantage: batch compiles, keeping digests in memory, dependency mgmt
|
||||
between app frameworks, building code/digests in the background, etc.
|
||||
|
||||
* Interesting idea: http://nickgravgaard.com/elastictabstops/
|
||||
|
||||
|
@ -24,11 +24,22 @@ namespace clang {
|
||||
|
||||
// Import the diagnostic enums themselves.
|
||||
namespace diag {
|
||||
/// diag::kind - All of the diagnostics that can be emitted by the frontend.
|
||||
enum kind {
|
||||
#define DIAG(ENUM,FLAGS,DESC) ENUM,
|
||||
#include "DiagnosticKinds.def"
|
||||
NUM_DIAGNOSTICS
|
||||
};
|
||||
|
||||
/// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
|
||||
/// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
|
||||
/// (emit as an error), or MAP_DEFAULT (handle the default way).
|
||||
enum Mapping {
|
||||
MAP_DEFAULT = 0, //< Do not map this diagnostic.
|
||||
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.
|
||||
};
|
||||
}
|
||||
|
||||
/// Diagnostic - This concrete class is used by the front-end to report
|
||||
@ -40,12 +51,12 @@ class Diagnostic {
|
||||
bool WarnOnExtensions; // Enables warnings for gcc extensions: -pedantic.
|
||||
bool ErrorOnExtensions; // Error on extensions: -pedantic-errors.
|
||||
DiagnosticClient &Client;
|
||||
|
||||
/// DiagMappings - Mapping information for diagnostics. Mapping info is
|
||||
/// packed into two bits per diagnostic.
|
||||
unsigned char DiagMappings[(diag::NUM_DIAGNOSTICS+3)/4];
|
||||
public:
|
||||
Diagnostic(DiagnosticClient &client) : Client(client) {
|
||||
WarningsAsErrors = false;
|
||||
WarnOnExtensions = false;
|
||||
ErrorOnExtensions = false;
|
||||
}
|
||||
Diagnostic(DiagnosticClient &client);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Diagnostic characterization methods, used by a client to customize how
|
||||
@ -66,6 +77,22 @@ public:
|
||||
void setErrorOnExtensions(bool Val) { ErrorOnExtensions = Val; }
|
||||
bool getErrorOnExtensions() const { return ErrorOnExtensions; }
|
||||
|
||||
/// 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!");
|
||||
unsigned char &Slot = DiagMappings[Diag/4];
|
||||
unsigned Bits = (Diag & 3)*2;
|
||||
Slot &= ~(3 << Bits);
|
||||
Slot |= Map << Bits;
|
||||
}
|
||||
|
||||
/// getDiagnosticMapping - Return the mapping currently set for the specified
|
||||
/// diagnostic.
|
||||
diag::Mapping getDiagnosticMapping(diag::kind Diag) const {
|
||||
return (diag::Mapping)((DiagMappings[Diag/4] >> (Diag & 3)*2) & 3);
|
||||
}
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Diagnostic classification and reporting interfaces.
|
||||
@ -77,7 +104,6 @@ public:
|
||||
|
||||
/// Level - The level of the diagnostic
|
||||
enum Level {
|
||||
// FIXME: Anachronism?
|
||||
Ignored, Note, Warning, Error, Fatal, Sorry
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user