Diagnostic.h revision 5917fe1189ee7cbb6f61b804b1f1ab6ef16a94cb
1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- C++ -*-===//
2651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//
3c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel//                     The LLVM Compiler Infrastructure
4c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel//
5c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel// This file is distributed under the University of Illinois Open Source
6c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel// License. See LICENSE.TXT for details.
7c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel//
8c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel//===----------------------------------------------------------------------===//
9c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel//
10c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel//  This file defines the Diagnostic-related interfaces.
11c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel//
12c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel//===----------------------------------------------------------------------===//
13c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel
14c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel#ifndef LLVM_CLANG_DIAGNOSTIC_H
15c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel#define LLVM_CLANG_DIAGNOSTIC_H
16c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel
17c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel#include "clang/Basic/SourceLocation.h"
18c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel#include <string>
19c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel#include <cassert>
20c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel
21c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patelnamespace clang {
22c1cabfbdff3986724ee8c4b350a440872e6b8f00Devang Patel  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  bool SuppressSystemWarnings;// Suppress warnings in system headers.
65  DiagnosticClient *Client;
66
67  /// DiagMappings - Mapping information for diagnostics.  Mapping info is
68  /// packed into two bits per diagnostic.
69  unsigned char DiagMappings[(diag::NUM_BUILTIN_DIAGNOSTICS+3)/4];
70
71  /// ErrorOccurred - This is set to true when an error is emitted, and is
72  /// sticky.
73  bool ErrorOccurred;
74
75  unsigned NumDiagnostics;    // Number of diagnostics reported
76  unsigned NumErrors;         // Number of diagnostics that are errors
77
78  /// CustomDiagInfo - Information for uniquing and looking up custom diags.
79  diag::CustomDiagInfo *CustomDiagInfo;
80
81public:
82  explicit Diagnostic(DiagnosticClient *client = 0);
83  ~Diagnostic();
84
85  //===--------------------------------------------------------------------===//
86  //  Diagnostic characterization methods, used by a client to customize how
87  //
88
89  DiagnosticClient *getClient() { return Client; };
90  const DiagnosticClient *getClient() const { return Client; };
91
92  void setClient(DiagnosticClient* client) { Client = client; }
93
94  /// setIgnoreAllWarnings - When set to true, any unmapped warnings are
95  /// ignored.  If this and WarningsAsErrors are both set, then this one wins.
96  void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
97  bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; }
98
99  /// setWarningsAsErrors - When set to true, any warnings reported are issued
100  /// as errors.
101  void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
102  bool getWarningsAsErrors() const { return WarningsAsErrors; }
103
104  /// setWarnOnExtensions - When set to true, issue warnings on GCC extensions,
105  /// the equivalent of GCC's -pedantic.
106  void setWarnOnExtensions(bool Val) { WarnOnExtensions = Val; }
107  bool getWarnOnExtensions() const { return WarnOnExtensions; }
108
109  /// setErrorOnExtensions - When set to true issue errors for GCC extensions
110  /// instead of warnings.  This is the equivalent to GCC's -pedantic-errors.
111  void setErrorOnExtensions(bool Val) { ErrorOnExtensions = Val; }
112  bool getErrorOnExtensions() const { return ErrorOnExtensions; }
113
114  /// setSuppressSystemWarnings - When set to true mask warnings that
115  /// come from system headers.
116  void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
117  bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
118
119  /// setDiagnosticMapping - This allows the client to specify that certain
120  /// warnings are ignored.  Only NOTEs, WARNINGs, and EXTENSIONs can be mapped.
121  void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) {
122    assert(Diag < diag::NUM_BUILTIN_DIAGNOSTICS &&
123           "Can only map builtin diagnostics");
124    assert(isBuiltinNoteWarningOrExtension(Diag) && "Cannot map errors!");
125    unsigned char &Slot = DiagMappings[Diag/4];
126    unsigned Bits = (Diag & 3)*2;
127    Slot &= ~(3 << Bits);
128    Slot |= Map << Bits;
129  }
130
131  /// getDiagnosticMapping - Return the mapping currently set for the specified
132  /// diagnostic.
133  diag::Mapping getDiagnosticMapping(diag::kind Diag) const {
134    return (diag::Mapping)((DiagMappings[Diag/4] >> (Diag & 3)*2) & 3);
135  }
136
137  bool hasErrorOccurred() const { return ErrorOccurred; }
138
139  unsigned getNumErrors() const { return NumErrors; }
140  unsigned getNumDiagnostics() const { return NumDiagnostics; }
141
142  /// getCustomDiagID - Return an ID for a diagnostic with the specified message
143  /// and level.  If this is the first request for this diagnosic, it is
144  /// registered and created, otherwise the existing ID is returned.
145  unsigned getCustomDiagID(Level L, const char *Message);
146
147  //===--------------------------------------------------------------------===//
148  // Diagnostic classification and reporting interfaces.
149  //
150
151  /// getDescription - Given a diagnostic ID, return a description of the
152  /// issue.
153  const char *getDescription(unsigned DiagID);
154
155  /// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic
156  /// level of the specified diagnostic ID is a Note, Warning, or Extension.
157  /// Note that this only works on builtin diagnostics, not custom ones.
158  static bool isBuiltinNoteWarningOrExtension(unsigned DiagID);
159
160  /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
161  /// object, classify the specified diagnostic ID into a Level, consumable by
162  /// the DiagnosticClient.
163  Level getDiagnosticLevel(unsigned DiagID) const;
164
165  /// Report - Issue the message to the client.  DiagID is a member of the
166  /// diag::kind enum.
167  void Report(FullSourceLoc Pos, unsigned DiagID,
168              const std::string **Strs = 0, unsigned NumStrs = 0,
169              const SourceRange *Ranges = 0, unsigned NumRanges = 0) {
170    Report(NULL, Pos, DiagID, Strs, NumStrs, Ranges, NumRanges);
171  }
172
173  /// Report - Issue the message to the specified client.
174  ///  DiagID is a member of the diag::kind enum.
175  void Report(DiagnosticClient* C, FullSourceLoc Pos, unsigned DiagID,
176              const std::string **Strs = 0, unsigned NumStrs = 0,
177              const SourceRange *Ranges = 0, unsigned NumRanges = 0);
178};
179
180/// DiagnosticClient - This is an abstract interface implemented by clients of
181/// the front-end, which formats and prints fully processed diagnostics.
182class DiagnosticClient {
183protected:
184  std::string FormatDiagnostic(Diagnostic &Diags, Diagnostic::Level Level,
185                               diag::kind ID,
186                               const std::string **Strs, unsigned NumStrs);
187public:
188  virtual ~DiagnosticClient();
189
190  /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
191  /// capturing it to a log as needed.
192  virtual void HandleDiagnostic(Diagnostic &Diags,
193                                Diagnostic::Level DiagLevel,
194                                FullSourceLoc Pos,
195                                diag::kind ID,
196                                const std::string **Strs,
197                                unsigned NumStrs,
198                                const SourceRange *Ranges,
199                                unsigned NumRanges) = 0;
200};
201
202}  // end namespace clang
203
204#endif
205