Diagnostic.h revision 2bf78fba7a37a42d4295999706053fdf4c9625e2
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 WarningsAsErrors; // Treat warnings like errors: 61 bool WarnOnExtensions; // Enables warnings for gcc extensions: -pedantic. 62 bool ErrorOnExtensions; // Error on extensions: -pedantic-errors. 63 DiagnosticClient &Client; 64 65 /// DiagMappings - Mapping information for diagnostics. Mapping info is 66 /// packed into two bits per diagnostic. 67 unsigned char DiagMappings[(diag::NUM_BUILTIN_DIAGNOSTICS+3)/4]; 68 69 /// ErrorOccurred - This is set to true when an error is emitted, and is 70 /// sticky. 71 bool ErrorOccurred; 72 73 unsigned NumDiagnostics; // Number of diagnostics reported 74 unsigned NumErrors; // Number of diagnostics that are errors 75 76 /// CustomDiagInfo - Information for uniquing and looking up custom diags. 77 diag::CustomDiagInfo *CustomDiagInfo; 78public: 79 explicit Diagnostic(DiagnosticClient &client); 80 ~Diagnostic(); 81 82 //===--------------------------------------------------------------------===// 83 // Diagnostic characterization methods, used by a client to customize how 84 // 85 86 DiagnosticClient &getClient() { return Client; }; 87 88 const DiagnosticClient &getClient() const { return Client; }; 89 90 /// setWarningsAsErrors - When set to true, any warnings reported are issued 91 /// as errors. 92 void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; } 93 bool getWarningsAsErrors() const { return WarningsAsErrors; } 94 95 /// setWarnOnExtensions - When set to true, issue warnings on GCC extensions, 96 /// the equivalent of GCC's -pedantic. 97 void setWarnOnExtensions(bool Val) { WarnOnExtensions = Val; } 98 bool getWarnOnExtensions() const { return WarnOnExtensions; } 99 100 /// setErrorOnExtensions - When set to true issue errors for GCC extensions 101 /// instead of warnings. This is the equivalent to GCC's -pedantic-errors. 102 void setErrorOnExtensions(bool Val) { ErrorOnExtensions = Val; } 103 bool getErrorOnExtensions() const { return ErrorOnExtensions; } 104 105 /// setDiagnosticMapping - This allows the client to specify that certain 106 /// warnings are ignored. Only NOTEs, WARNINGs, and EXTENSIONs can be mapped. 107 void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) { 108 assert(Diag < diag::NUM_BUILTIN_DIAGNOSTICS && 109 "Can only map builtin diagnostics"); 110 assert(isBuiltinNoteWarningOrExtension(Diag) && "Cannot map errors!"); 111 unsigned char &Slot = DiagMappings[Diag/4]; 112 unsigned Bits = (Diag & 3)*2; 113 Slot &= ~(3 << Bits); 114 Slot |= Map << Bits; 115 } 116 117 /// getDiagnosticMapping - Return the mapping currently set for the specified 118 /// diagnostic. 119 diag::Mapping getDiagnosticMapping(diag::kind Diag) const { 120 return (diag::Mapping)((DiagMappings[Diag/4] >> (Diag & 3)*2) & 3); 121 } 122 123 bool hasErrorOccurred() const { return ErrorOccurred; } 124 125 unsigned getNumErrors() const { return NumErrors; } 126 unsigned getNumDiagnostics() const { return NumDiagnostics; } 127 128 /// getCustomDiagID - Return an ID for a diagnostic with the specified message 129 /// and level. If this is the first request for this diagnosic, it is 130 /// registered and created, otherwise the existing ID is returned. 131 unsigned getCustomDiagID(Level L, const char *Message); 132 133 //===--------------------------------------------------------------------===// 134 // Diagnostic classification and reporting interfaces. 135 // 136 137 /// getDescription - Given a diagnostic ID, return a description of the 138 /// issue. 139 const char *getDescription(unsigned DiagID); 140 141 /// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic 142 /// level of the specified diagnostic ID is a Note, Warning, or Extension. 143 /// Note that this only works on builtin diagnostics, not custom ones. 144 static bool isBuiltinNoteWarningOrExtension(unsigned DiagID); 145 146 /// getDiagnosticLevel - Based on the way the client configured the Diagnostic 147 /// object, classify the specified diagnostic ID into a Level, consumable by 148 /// the DiagnosticClient. 149 Level getDiagnosticLevel(unsigned DiagID) const; 150 151 /// Report - Issue the message to the client. DiagID is a member of the 152 /// diag::kind enum. 153 void Report(FullSourceLoc Pos, unsigned DiagID, 154 const std::string *Strs = 0, unsigned NumStrs = 0, 155 const SourceRange *Ranges = 0, unsigned NumRanges = 0) { 156 Report(NULL, Pos, DiagID, Strs, NumStrs, Ranges, NumRanges); 157 } 158 159 /// Report - Issue the message to the client. DiagID is a member of the 160 /// diag::kind enum. 161 void Report(unsigned DiagID, 162 const std::string *Strs = 0, unsigned NumStrs = 0, 163 const SourceRange *Ranges = 0, unsigned NumRanges = 0) { 164 Report(FullSourceLoc(), DiagID, Strs, NumStrs, Ranges, NumRanges); 165 } 166 167 /// Report - Issue the message to the specified client. 168 /// DiagID is a member of the diag::kind enum. 169 void Report(DiagnosticClient* C, FullSourceLoc Pos, unsigned DiagID, 170 const std::string *Strs = 0, unsigned NumStrs = 0, 171 const SourceRange *Ranges = 0, unsigned NumRanges = 0); 172}; 173 174/// DiagnosticClient - This is an abstract interface implemented by clients of 175/// the front-end, which formats and prints fully processed diagnostics. 176class DiagnosticClient { 177public: 178 virtual ~DiagnosticClient(); 179 180 /// isInSystemHeader - If the client can tell that this is a system header, 181 /// return true. 182 virtual bool isInSystemHeader(FullSourceLoc Pos) const { return false; } 183 184 /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or 185 /// capturing it to a log as needed. 186 virtual void HandleDiagnostic(Diagnostic &Diags, 187 Diagnostic::Level DiagLevel, 188 FullSourceLoc Pos, 189 diag::kind ID, 190 const std::string *Strs, 191 unsigned NumStrs, 192 const SourceRange *Ranges, 193 unsigned NumRanges) = 0; 194}; 195 196} // end namespace clang 197 198#endif 199