Diagnostic.h revision 9c728dc4d8da89c73fcae74c9e72d7a83ffd7b6d
1//===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source 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 const DiagnosticClient &getClient() const { return Client; }; 86 87 /// setWarningsAsErrors - When set to true, any warnings reported are issued 88 /// as errors. 89 void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; } 90 bool getWarningsAsErrors() const { return WarningsAsErrors; } 91 92 /// setWarnOnExtensions - When set to true, issue warnings on GCC extensions, 93 /// the equivalent of GCC's -pedantic. 94 void setWarnOnExtensions(bool Val) { WarnOnExtensions = Val; } 95 bool getWarnOnExtensions() const { return WarnOnExtensions; } 96 97 /// setErrorOnExtensions - When set to true issue errors for GCC extensions 98 /// instead of warnings. This is the equivalent to GCC's -pedantic-errors. 99 void setErrorOnExtensions(bool Val) { ErrorOnExtensions = Val; } 100 bool getErrorOnExtensions() const { return ErrorOnExtensions; } 101 102 /// setDiagnosticMapping - This allows the client to specify that certain 103 /// warnings are ignored. Only NOTEs, WARNINGs, and EXTENSIONs can be mapped. 104 void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) { 105 assert(Diag < diag::NUM_BUILTIN_DIAGNOSTICS && 106 "Can only map builtin diagnostics"); 107 assert(isBuiltinNoteWarningOrExtension(Diag) && "Cannot map errors!"); 108 unsigned char &Slot = DiagMappings[Diag/4]; 109 unsigned Bits = (Diag & 3)*2; 110 Slot &= ~(3 << Bits); 111 Slot |= Map << Bits; 112 } 113 114 /// getDiagnosticMapping - Return the mapping currently set for the specified 115 /// diagnostic. 116 diag::Mapping getDiagnosticMapping(diag::kind Diag) const { 117 return (diag::Mapping)((DiagMappings[Diag/4] >> (Diag & 3)*2) & 3); 118 } 119 120 bool hasErrorOccurred() const { return ErrorOccurred; } 121 122 unsigned getNumErrors() const { return NumErrors; } 123 unsigned getNumDiagnostics() const { return NumDiagnostics; } 124 125 /// getCustomDiagID - Return an ID for a diagnostic with the specified message 126 /// and level. If this is the first request for this diagnosic, it is 127 /// registered and created, otherwise the existing ID is returned. 128 unsigned getCustomDiagID(Level L, const char *Message); 129 130 //===--------------------------------------------------------------------===// 131 // Diagnostic classification and reporting interfaces. 132 // 133 134 /// getDescription - Given a diagnostic ID, return a description of the 135 /// issue. 136 const char *getDescription(unsigned DiagID); 137 138 /// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic 139 /// level of the specified diagnostic ID is a Note, Warning, or Extension. 140 /// Note that this only works on builtin diagnostics, not custom ones. 141 static bool isBuiltinNoteWarningOrExtension(unsigned DiagID); 142 143 /// getDiagnosticLevel - Based on the way the client configured the Diagnostic 144 /// object, classify the specified diagnostic ID into a Level, consumable by 145 /// the DiagnosticClient. 146 Level getDiagnosticLevel(unsigned DiagID) const; 147 148 /// Report - Issue the message to the client. DiagID is a member of the 149 /// diag::kind enum. 150 void Report(FullSourceLoc Pos, unsigned DiagID, 151 const std::string *Strs = 0, unsigned NumStrs = 0, 152 const SourceRange *Ranges = 0, unsigned NumRanges = 0); 153 154 /// Report - Issue the message to the client. DiagID is a member of the 155 /// diag::kind enum. 156 void Report(unsigned DiagID, 157 const std::string *Strs = 0, unsigned NumStrs = 0, 158 const SourceRange *Ranges = 0, unsigned NumRanges = 0) { 159 Report(FullSourceLoc(),DiagID,Strs,NumStrs,Ranges,NumRanges); 160 } 161}; 162 163/// DiagnosticClient - This is an abstract interface implemented by clients of 164/// the front-end, which formats and prints fully processed diagnostics. 165class DiagnosticClient { 166public: 167 virtual ~DiagnosticClient(); 168 169 /// IgnoreDiagnostic - If the client wants to ignore this diagnostic, then 170 /// return true. 171 virtual bool IgnoreDiagnostic(Diagnostic::Level DiagLevel, 172 FullSourceLoc Pos) = 0; 173 174 /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or 175 /// capturing it to a log as needed. 176 virtual void HandleDiagnostic(Diagnostic &Diags, 177 Diagnostic::Level DiagLevel, 178 FullSourceLoc Pos, 179 diag::kind ID, 180 const std::string *Strs, 181 unsigned NumStrs, 182 const SourceRange *Ranges, 183 unsigned NumRanges) = 0; 184}; 185 186} // end namespace clang 187 188#endif 189