Diagnostic.h revision 3936c585cc07361a69cdf0c2c66c72f482b39dbe
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 <string>
18#include <cassert>
19
20namespace clang {
21  class DiagnosticClient;
22  class SourceLocation;
23  class SourceRange;
24
25  // Import the diagnostic enums themselves.
26  namespace diag {
27    /// diag::kind - All of the diagnostics that can be emitted by the frontend.
28    enum kind {
29#define DIAG(ENUM,FLAGS,DESC) ENUM,
30#include "DiagnosticKinds.def"
31      NUM_DIAGNOSTICS
32    };
33
34    /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
35    /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
36    /// (emit as an error), or MAP_DEFAULT (handle the default way).
37    enum Mapping {
38      MAP_DEFAULT = 0,     //< Do not map this diagnostic.
39      MAP_IGNORE  = 1,     //< Map this diagnostic to nothing, ignore it.
40      MAP_WARNING = 2,     //< Map this diagnostic to a warning.
41      MAP_ERROR   = 3      //< Map this diagnostic to an error.
42    };
43  }
44
45/// Diagnostic - This concrete class is used by the front-end to report
46/// problems and issues.  It massages the diagnostics (e.g. handling things like
47/// "report warnings as errors" and passes them off to the DiagnosticClient for
48/// reporting to the user.
49class Diagnostic {
50  bool WarningsAsErrors;      // Treat warnings like errors:
51  bool WarnOnExtensions;      // Enables warnings for gcc extensions: -pedantic.
52  bool ErrorOnExtensions;     // Error on extensions: -pedantic-errors.
53  DiagnosticClient &Client;
54
55  /// DiagMappings - Mapping information for diagnostics.  Mapping info is
56  /// packed into two bits per diagnostic.
57  unsigned char DiagMappings[(diag::NUM_DIAGNOSTICS+3)/4];
58
59  /// ErrorOccurred - This is set to true when an error is emitted, and is
60  /// sticky.
61  bool ErrorOccurred;
62
63  unsigned NumDiagnostics;    // Number of diagnostics reported
64  unsigned NumErrors;         // Number of diagnostics that are errors
65public:
66  explicit Diagnostic(DiagnosticClient &client);
67
68  //===--------------------------------------------------------------------===//
69  //  Diagnostic characterization methods, used by a client to customize how
70  //
71  const DiagnosticClient &getClient() const { return Client; };
72
73  /// setWarningsAsErrors - When set to true, any warnings reported are issued
74  /// as errors.
75  void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
76  bool getWarningsAsErrors() const { return WarningsAsErrors; }
77
78  /// setWarnOnExtensions - When set to true, issue warnings on GCC extensions,
79  /// the equivalent of GCC's -pedantic.
80  void setWarnOnExtensions(bool Val) { WarnOnExtensions = Val; }
81  bool getWarnOnExtensions() const { return WarnOnExtensions; }
82
83  /// setErrorOnExtensions - When set to true issue errors for GCC extensions
84  /// instead of warnings.  This is the equivalent to GCC's -pedantic-errors.
85  void setErrorOnExtensions(bool Val) { ErrorOnExtensions = Val; }
86  bool getErrorOnExtensions() const { return ErrorOnExtensions; }
87
88  /// setDiagnosticMapping - This allows the client to specify that certain
89  /// warnings are ignored.  Only NOTEs, WARNINGs, and EXTENSIONs can be mapped.
90  void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) {
91    assert(isNoteWarningOrExtension(Diag) && "Cannot map errors!");
92    unsigned char &Slot = DiagMappings[Diag/4];
93    unsigned Bits = (Diag & 3)*2;
94    Slot &= ~(3 << Bits);
95    Slot |= Map << Bits;
96  }
97
98  /// getDiagnosticMapping - Return the mapping currently set for the specified
99  /// diagnostic.
100  diag::Mapping getDiagnosticMapping(diag::kind Diag) const {
101    return (diag::Mapping)((DiagMappings[Diag/4] >> (Diag & 3)*2) & 3);
102  }
103
104  bool hasErrorOccurred() const { return ErrorOccurred; }
105
106  unsigned getNumErrors() const { return NumErrors; }
107  unsigned getNumDiagnostics() const { return NumDiagnostics; }
108
109  //===--------------------------------------------------------------------===//
110  // Diagnostic classification and reporting interfaces.
111  //
112
113  /// getDescription - Given a diagnostic ID, return a description of the
114  /// issue.
115  static const char *getDescription(unsigned DiagID);
116
117  /// Level - The level of the diagnostic
118  enum Level {
119    Ignored, Note, Warning, Error, Fatal
120  };
121
122  /// isNoteWarningOrExtension - Return true if the unmapped diagnostic level of
123  /// the specified diagnostic ID is a Note, Warning, or Extension.
124  static bool isNoteWarningOrExtension(unsigned DiagID);
125
126  /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
127  /// object, classify the specified diagnostic ID into a Level, consumable by
128  /// the DiagnosticClient.
129  Level getDiagnosticLevel(unsigned DiagID) const;
130
131  /// Report - Issue the message to the client.  DiagID is a member of the
132  /// diag::kind enum.
133  void Report(SourceLocation Pos, unsigned DiagID,
134              const std::string *Strs = 0, unsigned NumStrs = 0,
135              const SourceRange *Ranges = 0, unsigned NumRanges = 0);
136};
137
138/// DiagnosticClient - This is an abstract interface implemented by clients of
139/// the front-end, which formats and prints fully processed diagnostics.
140class DiagnosticClient {
141public:
142  virtual ~DiagnosticClient();
143
144  /// IgnoreDiagnostic - If the client wants to ignore this diagnostic, then
145  /// return true.
146  virtual bool IgnoreDiagnostic(Diagnostic::Level DiagLevel,
147                                SourceLocation Pos) = 0;
148
149  /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
150  /// capturing it to a log as needed.
151  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, SourceLocation Pos,
152                                diag::kind ID, const std::string *Strs,
153                                unsigned NumStrs, const SourceRange *Ranges,
154                                unsigned NumRanges) = 0;
155};
156
157}  // end namespace clang
158
159#endif
160