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