]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / llvm / tools / clang / include / clang / Basic / DiagnosticIDs.h
1 //===--- DiagnosticIDs.h - Diagnostic IDs 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 IDs-related interfaces.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CLANG_DIAGNOSTICIDS_H
15 #define LLVM_CLANG_DIAGNOSTICIDS_H
16
17 #include "llvm/ADT/IntrusiveRefCntPtr.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "clang/Basic/LLVM.h"
20
21 namespace llvm {
22   template<typename T, unsigned> class SmallVector;
23 }
24
25 namespace clang {
26   class DiagnosticsEngine;
27   class SourceLocation;
28   struct WarningOption;
29
30   // Import the diagnostic enums themselves.
31   namespace diag {
32     // Start position for diagnostics.
33     enum {
34       DIAG_START_DRIVER   =                        300,
35       DIAG_START_FRONTEND = DIAG_START_DRIVER   +  100,
36       DIAG_START_LEX      = DIAG_START_FRONTEND +  120,
37       DIAG_START_PARSE    = DIAG_START_LEX      +  300,
38       DIAG_START_AST      = DIAG_START_PARSE    +  300,
39       DIAG_START_SEMA     = DIAG_START_AST      +  100,
40       DIAG_START_ANALYSIS = DIAG_START_SEMA     + 3000,
41       DIAG_UPPER_LIMIT    = DIAG_START_ANALYSIS +  100
42     };
43
44     class CustomDiagInfo;
45
46     /// diag::kind - All of the diagnostics that can be emitted by the frontend.
47     typedef unsigned kind;
48
49     // Get typedefs for common diagnostics.
50     enum {
51 #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
52              SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER,BRIEF,FULL) ENUM,
53 #include "clang/Basic/DiagnosticCommonKinds.inc"
54       NUM_BUILTIN_COMMON_DIAGNOSTICS
55 #undef DIAG
56     };
57
58     /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
59     /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
60     /// (emit as an error).  It allows clients to map errors to
61     /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this
62     /// one).
63     enum Mapping {
64       // NOTE: 0 means "uncomputed".
65       MAP_IGNORE  = 1,     //< Map this diagnostic to nothing, ignore it.
66       MAP_WARNING = 2,     //< Map this diagnostic to a warning.
67       MAP_ERROR   = 3,     //< Map this diagnostic to an error.
68       MAP_FATAL   = 4      //< Map this diagnostic to a fatal error.
69     };
70   }
71
72 class DiagnosticMappingInfo {
73   unsigned Mapping : 3;
74   unsigned IsUser : 1;
75   unsigned IsPragma : 1;
76   unsigned HasShowInSystemHeader : 1;
77   unsigned HasNoWarningAsError : 1;
78   unsigned HasNoErrorAsFatal : 1;
79
80 public:
81   static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser,
82                                     bool IsPragma) {
83     DiagnosticMappingInfo Result;
84     Result.Mapping = Mapping;
85     Result.IsUser = IsUser;
86     Result.IsPragma = IsPragma;
87     Result.HasShowInSystemHeader = 0;
88     Result.HasNoWarningAsError = 0;
89     Result.HasNoErrorAsFatal = 0;
90     return Result;
91   }
92
93   diag::Mapping getMapping() const { return diag::Mapping(Mapping); }
94   void setMapping(diag::Mapping Value) { Mapping = Value; }
95
96   bool isUser() const { return IsUser; }
97   bool isPragma() const { return IsPragma; }
98
99   bool hasShowInSystemHeader() const { return HasShowInSystemHeader; }
100   void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; }
101
102   bool hasNoWarningAsError() const { return HasNoWarningAsError; }
103   void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; }
104
105   bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; }
106   void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; }
107 };
108
109 /// \brief Used for handling and querying diagnostic IDs. Can be used and shared
110 /// by multiple Diagnostics for multiple translation units.
111 class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
112 public:
113   /// Level - The level of the diagnostic, after it has been through mapping.
114   enum Level {
115     Ignored, Note, Warning, Error, Fatal
116   };
117
118 private:
119   /// CustomDiagInfo - Information for uniquing and looking up custom diags.
120   diag::CustomDiagInfo *CustomDiagInfo;
121
122 public:
123   DiagnosticIDs();
124   ~DiagnosticIDs();
125
126   /// getCustomDiagID - Return an ID for a diagnostic with the specified message
127   /// and level.  If this is the first request for this diagnosic, it is
128   /// registered and created, otherwise the existing ID is returned.
129   unsigned getCustomDiagID(Level L, StringRef Message);
130
131   //===--------------------------------------------------------------------===//
132   // Diagnostic classification and reporting interfaces.
133   //
134
135   /// getDescription - Given a diagnostic ID, return a description of the
136   /// issue.
137   StringRef getDescription(unsigned DiagID) const;
138
139   /// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic level
140   /// of the specified diagnostic ID is a Warning or Extension.  This only works
141   /// on builtin diagnostics, not custom ones, and is not legal to call on
142   /// NOTEs.
143   static bool isBuiltinWarningOrExtension(unsigned DiagID);
144
145   /// \brief Return true if the specified diagnostic is mapped to errors by
146   /// default.
147   static bool isDefaultMappingAsError(unsigned DiagID);
148
149   /// \brief Determine whether the given built-in diagnostic ID is a
150   /// Note.
151   static bool isBuiltinNote(unsigned DiagID);
152
153   /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
154   /// ID is for an extension of some sort.
155   ///
156   static bool isBuiltinExtensionDiag(unsigned DiagID) {
157     bool ignored;
158     return isBuiltinExtensionDiag(DiagID, ignored);
159   }
160   
161   /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
162   /// ID is for an extension of some sort.  This also returns EnabledByDefault,
163   /// which is set to indicate whether the diagnostic is ignored by default (in
164   /// which case -pedantic enables it) or treated as a warning/error by default.
165   ///
166   static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
167   
168
169   /// getWarningOptionForDiag - Return the lowest-level warning option that
170   /// enables the specified diagnostic.  If there is no -Wfoo flag that controls
171   /// the diagnostic, this returns null.
172   static StringRef getWarningOptionForDiag(unsigned DiagID);
173   
174   /// getCategoryNumberForDiag - Return the category number that a specified
175   /// DiagID belongs to, or 0 if no category.
176   static unsigned getCategoryNumberForDiag(unsigned DiagID);
177
178   /// getNumberOfCategories - Return the number of categories
179   static unsigned getNumberOfCategories();
180
181   /// getCategoryNameFromID - Given a category ID, return the name of the
182   /// category.
183   static StringRef getCategoryNameFromID(unsigned CategoryID);
184   
185   /// \brief Enumeration describing how the the emission of a diagnostic should
186   /// be treated when it occurs during C++ template argument deduction.
187   enum SFINAEResponse {
188     /// \brief The diagnostic should not be reported, but it should cause
189     /// template argument deduction to fail.
190     ///
191     /// The vast majority of errors that occur during template argument 
192     /// deduction fall into this category.
193     SFINAE_SubstitutionFailure,
194     
195     /// \brief The diagnostic should be suppressed entirely.
196     ///
197     /// Warnings generally fall into this category.
198     SFINAE_Suppress,
199     
200     /// \brief The diagnostic should be reported.
201     ///
202     /// The diagnostic should be reported. Various fatal errors (e.g., 
203     /// template instantiation depth exceeded) fall into this category.
204     SFINAE_Report,
205     
206     /// \brief The diagnostic is an access-control diagnostic, which will be
207     /// substitution failures in some contexts and reported in others.
208     SFINAE_AccessControl
209   };
210   
211   /// \brief Determines whether the given built-in diagnostic ID is
212   /// for an error that is suppressed if it occurs during C++ template
213   /// argument deduction.
214   ///
215   /// When an error is suppressed due to SFINAE, the template argument
216   /// deduction fails but no diagnostic is emitted. Certain classes of
217   /// errors, such as those errors that involve C++ access control,
218   /// are not SFINAE errors.
219   static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
220
221   /// getName - Given a diagnostic ID, return its name
222   static StringRef getName(unsigned DiagID);
223   
224   /// getIdFromName - Given a diagnostic name, return its ID, or 0
225   static unsigned getIdFromName(StringRef Name);
226   
227   /// getBriefExplanation - Given a diagnostic ID, return a brief explanation
228   /// of the issue
229   static StringRef getBriefExplanation(unsigned DiagID);
230
231   /// getFullExplanation - Given a diagnostic ID, return a full explanation
232   /// of the issue
233   static StringRef getFullExplanation(unsigned DiagID);
234   
235   /// Iterator class used for traversing all statically declared
236   /// diagnostics.
237   class diag_iterator {
238     const void *impl;
239
240     friend class DiagnosticIDs;    
241     diag_iterator(const void *im) : impl(im) {}
242   public:
243     diag_iterator &operator++();
244     bool operator==(const diag_iterator &x) const { return impl == x.impl; }
245     bool operator!=(const diag_iterator &x) const { return impl != x.impl; }
246     
247     llvm::StringRef getDiagName() const;
248     unsigned getDiagID() const;    
249   };
250
251   static diag_iterator diags_begin();
252   static diag_iterator diags_end();
253
254   /// \brief Get the set of all diagnostic IDs in the group with the given name.
255   ///
256   /// \param Diags [out] - On return, the diagnostics in the group.
257   /// \returns True if the given group is unknown, false otherwise.
258   bool getDiagnosticsInGroup(StringRef Group,
259                              llvm::SmallVectorImpl<diag::kind> &Diags) const;
260
261 private:
262   /// \brief Get the set of all diagnostic IDs in the given group.
263   ///
264   /// \param Diags [out] - On return, the diagnostics in the group.
265   void getDiagnosticsInGroup(const WarningOption *Group,
266                              llvm::SmallVectorImpl<diag::kind> &Diags) const;
267  
268   /// \brief Based on the way the client configured the DiagnosticsEngine
269   /// object, classify the specified diagnostic ID into a Level, consumable by
270   /// the DiagnosticClient.
271   ///
272   /// \param Loc The source location we are interested in finding out the
273   /// diagnostic state. Can be null in order to query the latest state.
274   DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
275                                           const DiagnosticsEngine &Diag) const;
276
277   /// getDiagnosticLevel - This is an internal implementation helper used when
278   /// DiagClass is already known.
279   DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID,
280                                           unsigned DiagClass,
281                                           SourceLocation Loc,
282                                           const DiagnosticsEngine &Diag) const;
283
284   /// ProcessDiag - This is the method used to report a diagnostic that is
285   /// finally fully formed.
286   ///
287   /// \returns true if the diagnostic was emitted, false if it was
288   /// suppressed.
289   bool ProcessDiag(DiagnosticsEngine &Diag) const;
290
291   /// \brief Whether the diagnostic may leave the AST in a state where some
292   /// invariants can break.
293   bool isUnrecoverable(unsigned DiagID) const;
294
295   friend class DiagnosticsEngine;
296 };
297
298 }  // end namespace clang
299
300 #endif