Diagnostic.h revision 7bfaaaecb3113f955db31e8d8a51acffd1bc0c27
1//===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the Diagnostic-related interfaces. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_DIAGNOSTIC_H 15#define LLVM_CLANG_DIAGNOSTIC_H 16 17#include "clang/Basic/SourceLocation.h" 18#include <string> 19#include <cassert> 20 21namespace clang { 22 class DiagnosticClient; 23 class SourceRange; 24 class SourceManager; 25 26 // Import the diagnostic enums themselves. 27 namespace diag { 28 class CustomDiagInfo; 29 30 /// diag::kind - All of the diagnostics that can be emitted by the frontend. 31 enum kind { 32#define DIAG(ENUM,FLAGS,DESC) ENUM, 33#include "DiagnosticKinds.def" 34 NUM_BUILTIN_DIAGNOSTICS 35 }; 36 37 /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs 38 /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR 39 /// (emit as an error), or MAP_DEFAULT (handle the default way). 40 enum Mapping { 41 MAP_DEFAULT = 0, //< Do not map this diagnostic. 42 MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it. 43 MAP_WARNING = 2, //< Map this diagnostic to a warning. 44 MAP_ERROR = 3 //< Map this diagnostic to an error. 45 }; 46 } 47 48/// Diagnostic - This concrete class is used by the front-end to report 49/// problems and issues. It massages the diagnostics (e.g. handling things like 50/// "report warnings as errors" and passes them off to the DiagnosticClient for 51/// reporting to the user. 52class Diagnostic { 53public: 54 /// Level - The level of the diagnostic, after it has been through mapping. 55 enum Level { 56 Ignored, Note, Warning, Error, Fatal 57 }; 58 59private: 60 bool IgnoreAllWarnings; // Ignore all warnings: -w 61 bool WarningsAsErrors; // Treat warnings like errors: 62 bool WarnOnExtensions; // Enables warnings for gcc extensions: -pedantic. 63 bool ErrorOnExtensions; // Error on extensions: -pedantic-errors. 64 DiagnosticClient *Client; 65 66 /// DiagMappings - Mapping information for diagnostics. Mapping info is 67 /// packed into two bits per diagnostic. 68 unsigned char DiagMappings[(diag::NUM_BUILTIN_DIAGNOSTICS+3)/4]; 69 70 /// ErrorOccurred - This is set to true when an error is emitted, and is 71 /// sticky. 72 bool ErrorOccurred; 73 74 unsigned NumDiagnostics; // Number of diagnostics reported 75 unsigned NumErrors; // Number of diagnostics that are errors 76 77 /// CustomDiagInfo - Information for uniquing and looking up custom diags. 78 diag::CustomDiagInfo *CustomDiagInfo; 79 80public: 81 explicit Diagnostic(DiagnosticClient *client = 0); 82 ~Diagnostic(); 83 84 //===--------------------------------------------------------------------===// 85 // Diagnostic characterization methods, used by a client to customize how 86 // 87 88 DiagnosticClient *getClient() { return Client; }; 89 const DiagnosticClient *getClient() const { return Client; }; 90 91 void setClient(DiagnosticClient* client) { Client = client; } 92 93 /// setIgnoreAllWarnings - When set to true, any unmapped warnings are 94 /// ignored. If this and WarningsAsErrors are both set, then this one wins. 95 void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; } 96 bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; } 97 98 /// setWarningsAsErrors - When set to true, any warnings reported are issued 99 /// as errors. 100 void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; } 101 bool getWarningsAsErrors() const { return WarningsAsErrors; } 102 103 /// setWarnOnExtensions - When set to true, issue warnings on GCC extensions, 104 /// the equivalent of GCC's -pedantic. 105 void setWarnOnExtensions(bool Val) { WarnOnExtensions = Val; } 106 bool getWarnOnExtensions() const { return WarnOnExtensions; } 107 108 /// setErrorOnExtensions - When set to true issue errors for GCC extensions 109 /// instead of warnings. This is the equivalent to GCC's -pedantic-errors. 110 void setErrorOnExtensions(bool Val) { ErrorOnExtensions = Val; } 111 bool getErrorOnExtensions() const { return ErrorOnExtensions; } 112 113 /// setDiagnosticMapping - This allows the client to specify that certain 114 /// warnings are ignored. Only NOTEs, WARNINGs, and EXTENSIONs can be mapped. 115 void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) { 116 assert(Diag < diag::NUM_BUILTIN_DIAGNOSTICS && 117 "Can only map builtin diagnostics"); 118 assert(isBuiltinNoteWarningOrExtension(Diag) && "Cannot map errors!"); 119 unsigned char &Slot = DiagMappings[Diag/4]; 120 unsigned Bits = (Diag & 3)*2; 121 Slot &= ~(3 << Bits); 122 Slot |= Map << Bits; 123 } 124 125 /// getDiagnosticMapping - Return the mapping currently set for the specified 126 /// diagnostic. 127 diag::Mapping getDiagnosticMapping(diag::kind Diag) const { 128 return (diag::Mapping)((DiagMappings[Diag/4] >> (Diag & 3)*2) & 3); 129 } 130 131 bool hasErrorOccurred() const { return ErrorOccurred; } 132 133 unsigned getNumErrors() const { return NumErrors; } 134 unsigned getNumDiagnostics() const { return NumDiagnostics; } 135 136 /// getCustomDiagID - Return an ID for a diagnostic with the specified message 137 /// and level. If this is the first request for this diagnosic, it is 138 /// registered and created, otherwise the existing ID is returned. 139 unsigned getCustomDiagID(Level L, const char *Message); 140 141 //===--------------------------------------------------------------------===// 142 // Diagnostic classification and reporting interfaces. 143 // 144 145 /// getDescription - Given a diagnostic ID, return a description of the 146 /// issue. 147 const char *getDescription(unsigned DiagID); 148 149 /// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic 150 /// level of the specified diagnostic ID is a Note, Warning, or Extension. 151 /// Note that this only works on builtin diagnostics, not custom ones. 152 static bool isBuiltinNoteWarningOrExtension(unsigned DiagID); 153 154 /// getDiagnosticLevel - Based on the way the client configured the Diagnostic 155 /// object, classify the specified diagnostic ID into a Level, consumable by 156 /// the DiagnosticClient. 157 Level getDiagnosticLevel(unsigned DiagID) const; 158 159 /// Report - Issue the message to the client. DiagID is a member of the 160 /// diag::kind enum. 161 void Report(FullSourceLoc Pos, unsigned DiagID, 162 const std::string *Strs = 0, unsigned NumStrs = 0, 163 const SourceRange *Ranges = 0, unsigned NumRanges = 0) { 164 Report(NULL, Pos, DiagID, Strs, NumStrs, Ranges, NumRanges); 165 } 166 167 /// Report - Issue the message to the client. DiagID is a member of the 168 /// diag::kind enum. 169 void Report(unsigned DiagID, 170 const std::string *Strs = 0, unsigned NumStrs = 0, 171 const SourceRange *Ranges = 0, unsigned NumRanges = 0) { 172 Report(FullSourceLoc(), DiagID, Strs, NumStrs, Ranges, NumRanges); 173 } 174 175 /// Report - Issue the message to the specified client. 176 /// DiagID is a member of the diag::kind enum. 177 void Report(DiagnosticClient* C, FullSourceLoc Pos, unsigned DiagID, 178 const std::string *Strs = 0, unsigned NumStrs = 0, 179 const SourceRange *Ranges = 0, unsigned NumRanges = 0); 180}; 181 182/// DiagnosticClient - This is an abstract interface implemented by clients of 183/// the front-end, which formats and prints fully processed diagnostics. 184class DiagnosticClient { 185protected: 186 std::string FormatDiagnostic(Diagnostic &Diags, Diagnostic::Level Level, 187 diag::kind ID, 188 const std::string *Strs, 189 unsigned NumStrs); 190public: 191 virtual ~DiagnosticClient(); 192 193 /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or 194 /// capturing it to a log as needed. 195 virtual void HandleDiagnostic(Diagnostic &Diags, 196 Diagnostic::Level DiagLevel, 197 FullSourceLoc Pos, 198 diag::kind ID, 199 const std::string *Strs, 200 unsigned NumStrs, 201 const SourceRange *Ranges, 202 unsigned NumRanges) = 0; 203}; 204 205} // end namespace clang 206 207#endif 208