]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/clang/Basic/Diagnostic.h
Update clang to r84949.
[FreeBSD/FreeBSD.git] / include / clang / Basic / Diagnostic.h
1 //===--- Diagnostic.h - C Language Family Diagnostic 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-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 "llvm/ADT/StringRef.h"
19 #include "llvm/Support/type_traits.h"
20 #include <string>
21 #include <vector>
22 #include <cassert>
23
24 namespace llvm {
25   template <typename T> class SmallVectorImpl;
26 }
27
28 namespace clang {
29   class DeclContext;
30   class DiagnosticBuilder;
31   class DiagnosticClient;
32   class IdentifierInfo;
33   class LangOptions;
34   class PartialDiagnostic;
35   class SourceRange;
36
37   // Import the diagnostic enums themselves.
38   namespace diag {
39     // Start position for diagnostics.
40     enum {
41       DIAG_START_DRIVER   =                        300,
42       DIAG_START_FRONTEND = DIAG_START_DRIVER   +  100,
43       DIAG_START_LEX      = DIAG_START_FRONTEND +  100,
44       DIAG_START_PARSE    = DIAG_START_LEX      +  300,
45       DIAG_START_AST      = DIAG_START_PARSE    +  300,
46       DIAG_START_SEMA     = DIAG_START_AST      +  100,
47       DIAG_START_ANALYSIS = DIAG_START_SEMA     + 1100,
48       DIAG_UPPER_LIMIT    = DIAG_START_ANALYSIS +  100
49     };
50
51     class CustomDiagInfo;
52
53     /// diag::kind - All of the diagnostics that can be emitted by the frontend.
54     typedef unsigned kind;
55
56     // Get typedefs for common diagnostics.
57     enum {
58 #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
59 #include "clang/Basic/DiagnosticCommonKinds.inc"
60       NUM_BUILTIN_COMMON_DIAGNOSTICS
61 #undef DIAG
62     };
63
64     /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
65     /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
66     /// (emit as an error).  It allows clients to map errors to
67     /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this
68     /// one).
69     enum Mapping {
70       // NOTE: 0 means "uncomputed".
71       MAP_IGNORE  = 1,     //< Map this diagnostic to nothing, ignore it.
72       MAP_WARNING = 2,     //< Map this diagnostic to a warning.
73       MAP_ERROR   = 3,     //< Map this diagnostic to an error.
74       MAP_FATAL   = 4,     //< Map this diagnostic to a fatal error.
75
76       /// Map this diagnostic to "warning", but make it immune to -Werror.  This
77       /// happens when you specify -Wno-error=foo.
78       MAP_WARNING_NO_WERROR = 5
79     };
80   }
81
82 /// \brief Annotates a diagnostic with some code that should be
83 /// inserted, removed, or replaced to fix the problem.
84 ///
85 /// This kind of hint should be used when we are certain that the
86 /// introduction, removal, or modification of a particular (small!)
87 /// amount of code will correct a compilation error. The compiler
88 /// should also provide full recovery from such errors, such that
89 /// suppressing the diagnostic output can still result in successful
90 /// compilation.
91 class CodeModificationHint {
92 public:
93   /// \brief Tokens that should be removed to correct the error.
94   SourceRange RemoveRange;
95
96   /// \brief The location at which we should insert code to correct
97   /// the error.
98   SourceLocation InsertionLoc;
99
100   /// \brief The actual code to insert at the insertion location, as a
101   /// string.
102   std::string CodeToInsert;
103
104   /// \brief Empty code modification hint, indicating that no code
105   /// modification is known.
106   CodeModificationHint() : RemoveRange(), InsertionLoc() { }
107
108   /// \brief Create a code modification hint that inserts the given
109   /// code string at a specific location.
110   static CodeModificationHint CreateInsertion(SourceLocation InsertionLoc,
111                                               llvm::StringRef Code) {
112     CodeModificationHint Hint;
113     Hint.InsertionLoc = InsertionLoc;
114     Hint.CodeToInsert = Code;
115     return Hint;
116   }
117
118   /// \brief Create a code modification hint that removes the given
119   /// source range.
120   static CodeModificationHint CreateRemoval(SourceRange RemoveRange) {
121     CodeModificationHint Hint;
122     Hint.RemoveRange = RemoveRange;
123     return Hint;
124   }
125
126   /// \brief Create a code modification hint that replaces the given
127   /// source range with the given code string.
128   static CodeModificationHint CreateReplacement(SourceRange RemoveRange,
129                                                 llvm::StringRef Code) {
130     CodeModificationHint Hint;
131     Hint.RemoveRange = RemoveRange;
132     Hint.InsertionLoc = RemoveRange.getBegin();
133     Hint.CodeToInsert = Code;
134     return Hint;
135   }
136 };
137
138 /// Diagnostic - This concrete class is used by the front-end to report
139 /// problems and issues.  It massages the diagnostics (e.g. handling things like
140 /// "report warnings as errors" and passes them off to the DiagnosticClient for
141 /// reporting to the user.
142 class Diagnostic {
143 public:
144   /// Level - The level of the diagnostic, after it has been through mapping.
145   enum Level {
146     Ignored, Note, Warning, Error, Fatal
147   };
148
149   /// ExtensionHandling - How do we handle otherwise-unmapped extension?  This
150   /// is controlled by -pedantic and -pedantic-errors.
151   enum ExtensionHandling {
152     Ext_Ignore, Ext_Warn, Ext_Error
153   };
154
155   enum ArgumentKind {
156     ak_std_string,      // std::string
157     ak_c_string,        // const char *
158     ak_sint,            // int
159     ak_uint,            // unsigned
160     ak_identifierinfo,  // IdentifierInfo
161     ak_qualtype,        // QualType
162     ak_declarationname, // DeclarationName
163     ak_nameddecl,       // NamedDecl *
164     ak_nestednamespec,  // NestedNameSpecifier *
165     ak_declcontext      // DeclContext *
166   };
167   
168   /// ArgumentValue - This typedef represents on argument value, which is a
169   /// union discriminated by ArgumentKind, with a value.
170   typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
171
172 private:
173   unsigned char AllExtensionsSilenced; // Used by __extension__
174   bool IgnoreAllWarnings;        // Ignore all warnings: -w
175   bool WarningsAsErrors;         // Treat warnings like errors:
176   bool SuppressSystemWarnings;   // Suppress warnings in system headers.
177   bool SuppressAllDiagnostics;   // Suppress all diagnostics.
178   ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
179   DiagnosticClient *Client;
180
181   /// DiagMappings - Mapping information for diagnostics.  Mapping info is
182   /// packed into four bits per diagnostic.  The low three bits are the mapping
183   /// (an instance of diag::Mapping), or zero if unset.  The high bit is set
184   /// when the mapping was established as a user mapping.  If the high bit is
185   /// clear, then the low bits are set to the default value, and should be
186   /// mapped with -pedantic, -Werror, etc.
187
188   typedef std::vector<unsigned char> DiagMappings;
189   mutable std::vector<DiagMappings> DiagMappingsStack;
190
191   /// ErrorOccurred / FatalErrorOccurred - This is set to true when an error or
192   /// fatal error is emitted, and is sticky.
193   bool ErrorOccurred;
194   bool FatalErrorOccurred;
195
196   /// LastDiagLevel - This is the level of the last diagnostic emitted.  This is
197   /// used to emit continuation diagnostics with the same level as the
198   /// diagnostic that they follow.
199   Diagnostic::Level LastDiagLevel;
200
201   unsigned NumDiagnostics;    // Number of diagnostics reported
202   unsigned NumErrors;         // Number of diagnostics that are errors
203
204   /// CustomDiagInfo - Information for uniquing and looking up custom diags.
205   diag::CustomDiagInfo *CustomDiagInfo;
206
207   /// ArgToStringFn - A function pointer that converts an opaque diagnostic
208   /// argument to a strings.  This takes the modifiers and argument that was
209   /// present in the diagnostic.
210   ///
211   /// The PrevArgs array (whose length is NumPrevArgs) indicates the previous
212   /// arguments formatted for this diagnostic.  Implementations of this function
213   /// can use this information to avoid redundancy across arguments.
214   ///
215   /// This is a hack to avoid a layering violation between libbasic and libsema.
216   typedef void (*ArgToStringFnTy)(ArgumentKind Kind, intptr_t Val,
217                                   const char *Modifier, unsigned ModifierLen,
218                                   const char *Argument, unsigned ArgumentLen,
219                                   const ArgumentValue *PrevArgs,
220                                   unsigned NumPrevArgs,
221                                   llvm::SmallVectorImpl<char> &Output,
222                                   void *Cookie);
223   void *ArgToStringCookie;
224   ArgToStringFnTy ArgToStringFn;
225 public:
226   explicit Diagnostic(DiagnosticClient *client = 0);
227   ~Diagnostic();
228
229   //===--------------------------------------------------------------------===//
230   //  Diagnostic characterization methods, used by a client to customize how
231   //
232
233   DiagnosticClient *getClient() { return Client; };
234   const DiagnosticClient *getClient() const { return Client; };
235
236
237   /// pushMappings - Copies the current DiagMappings and pushes the new copy
238   /// onto the top of the stack.
239   void pushMappings();
240
241   /// popMappings - Pops the current DiagMappings off the top of the stack
242   /// causing the new top of the stack to be the active mappings. Returns
243   /// true if the pop happens, false if there is only one DiagMapping on the
244   /// stack.
245   bool popMappings();
246
247   void setClient(DiagnosticClient* client) { Client = client; }
248
249   /// setIgnoreAllWarnings - When set to true, any unmapped warnings are
250   /// ignored.  If this and WarningsAsErrors are both set, then this one wins.
251   void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
252   bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; }
253
254   /// setWarningsAsErrors - When set to true, any warnings reported are issued
255   /// as errors.
256   void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
257   bool getWarningsAsErrors() const { return WarningsAsErrors; }
258
259   /// setSuppressSystemWarnings - When set to true mask warnings that
260   /// come from system headers.
261   void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
262   bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
263
264   /// \brief Suppress all diagnostics, to silence the front end when we 
265   /// know that we don't want any more diagnostics to be passed along to the
266   /// client
267   void setSuppressAllDiagnostics(bool Val = true) { 
268     SuppressAllDiagnostics = Val; 
269   }
270   bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
271   
272   /// \brief Pretend that the last diagnostic issued was ignored. This can
273   /// be used by clients who suppress diagnostics themselves.
274   void setLastDiagnosticIgnored() {
275     LastDiagLevel = Ignored;
276   }
277   
278   /// setExtensionHandlingBehavior - This controls whether otherwise-unmapped
279   /// extension diagnostics are mapped onto ignore/warning/error.  This
280   /// corresponds to the GCC -pedantic and -pedantic-errors option.
281   void setExtensionHandlingBehavior(ExtensionHandling H) {
282     ExtBehavior = H;
283   }
284
285   /// AllExtensionsSilenced - This is a counter bumped when an __extension__
286   /// block is encountered.  When non-zero, all extension diagnostics are
287   /// entirely silenced, no matter how they are mapped.
288   void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
289   void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
290   bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
291
292   /// setDiagnosticMapping - This allows the client to specify that certain
293   /// warnings are ignored.  Notes can never be mapped, errors can only be
294   /// mapped to fatal, and WARNINGs and EXTENSIONs can be mapped arbitrarily.
295   void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) {
296     assert(Diag < diag::DIAG_UPPER_LIMIT &&
297            "Can only map builtin diagnostics");
298     assert((isBuiltinWarningOrExtension(Diag) || Map == diag::MAP_FATAL) &&
299            "Cannot map errors!");
300     setDiagnosticMappingInternal(Diag, Map, true);
301   }
302
303   /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
304   /// "unknown-pragmas" to have the specified mapping.  This returns true and
305   /// ignores the request if "Group" was unknown, false otherwise.
306   bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map);
307
308   bool hasErrorOccurred() const { return ErrorOccurred; }
309   bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
310
311   unsigned getNumErrors() const { return NumErrors; }
312   unsigned getNumDiagnostics() const { return NumDiagnostics; }
313
314   /// getCustomDiagID - Return an ID for a diagnostic with the specified message
315   /// and level.  If this is the first request for this diagnosic, it is
316   /// registered and created, otherwise the existing ID is returned.
317   unsigned getCustomDiagID(Level L, const char *Message);
318
319
320   /// ConvertArgToString - This method converts a diagnostic argument (as an
321   /// intptr_t) into the string that represents it.
322   void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
323                           const char *Modifier, unsigned ModLen,
324                           const char *Argument, unsigned ArgLen,
325                           const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
326                           llvm::SmallVectorImpl<char> &Output) const {
327     ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
328                   PrevArgs, NumPrevArgs, Output, ArgToStringCookie);
329   }
330
331   void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
332     ArgToStringFn = Fn;
333     ArgToStringCookie = Cookie;
334   }
335
336   //===--------------------------------------------------------------------===//
337   // Diagnostic classification and reporting interfaces.
338   //
339
340   /// getDescription - Given a diagnostic ID, return a description of the
341   /// issue.
342   const char *getDescription(unsigned DiagID) const;
343
344   /// isNoteWarningOrExtension - Return true if the unmapped diagnostic
345   /// level of the specified diagnostic ID is a Warning or Extension.
346   /// This only works on builtin diagnostics, not custom ones, and is not legal to
347   /// call on NOTEs.
348   static bool isBuiltinWarningOrExtension(unsigned DiagID);
349
350   /// \brief Determine whether the given built-in diagnostic ID is a
351   /// Note.
352   static bool isBuiltinNote(unsigned DiagID);
353
354   /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
355   /// ID is for an extension of some sort.
356   ///
357   static bool isBuiltinExtensionDiag(unsigned DiagID);
358
359   /// getWarningOptionForDiag - Return the lowest-level warning option that
360   /// enables the specified diagnostic.  If there is no -Wfoo flag that controls
361   /// the diagnostic, this returns null.
362   static const char *getWarningOptionForDiag(unsigned DiagID);
363
364   /// \brief Determines whether the given built-in diagnostic ID is
365   /// for an error that is suppressed if it occurs during C++ template
366   /// argument deduction.
367   ///
368   /// When an error is suppressed due to SFINAE, the template argument
369   /// deduction fails but no diagnostic is emitted. Certain classes of
370   /// errors, such as those errors that involve C++ access control,
371   /// are not SFINAE errors.
372   static bool isBuiltinSFINAEDiag(unsigned DiagID);
373
374   /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
375   /// object, classify the specified diagnostic ID into a Level, consumable by
376   /// the DiagnosticClient.
377   Level getDiagnosticLevel(unsigned DiagID) const;
378
379   /// Report - Issue the message to the client.  @c DiagID is a member of the
380   /// @c diag::kind enum.  This actually returns aninstance of DiagnosticBuilder
381   /// which emits the diagnostics (through @c ProcessDiag) when it is destroyed.
382   /// @c Pos represents the source location associated with the diagnostic,
383   /// which can be an invalid location if no position information is available.
384   inline DiagnosticBuilder Report(FullSourceLoc Pos, unsigned DiagID);
385
386   /// \brief Clear out the current diagnostic.
387   void Clear() { CurDiagID = ~0U; }
388
389 private:
390   /// getDiagnosticMappingInfo - Return the mapping info currently set for the
391   /// specified builtin diagnostic.  This returns the high bit encoding, or zero
392   /// if the field is completely uninitialized.
393   unsigned getDiagnosticMappingInfo(diag::kind Diag) const {
394     const DiagMappings &currentMappings = DiagMappingsStack.back();
395     return (diag::Mapping)((currentMappings[Diag/2] >> (Diag & 1)*4) & 15);
396   }
397
398   void setDiagnosticMappingInternal(unsigned DiagId, unsigned Map,
399                                     bool isUser) const {
400     if (isUser) Map |= 8;  // Set the high bit for user mappings.
401     unsigned char &Slot = DiagMappingsStack.back()[DiagId/2];
402     unsigned Shift = (DiagId & 1)*4;
403     Slot &= ~(15 << Shift);
404     Slot |= Map << Shift;
405   }
406
407   /// getDiagnosticLevel - This is an internal implementation helper used when
408   /// DiagClass is already known.
409   Level getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const;
410
411   // This is private state used by DiagnosticBuilder.  We put it here instead of
412   // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight
413   // object.  This implementation choice means that we can only have one
414   // diagnostic "in flight" at a time, but this seems to be a reasonable
415   // tradeoff to keep these objects small.  Assertions verify that only one
416   // diagnostic is in flight at a time.
417   friend class DiagnosticBuilder;
418   friend class DiagnosticInfo;
419
420   /// CurDiagLoc - This is the location of the current diagnostic that is in
421   /// flight.
422   FullSourceLoc CurDiagLoc;
423
424   /// CurDiagID - This is the ID of the current diagnostic that is in flight.
425   /// This is set to ~0U when there is no diagnostic in flight.
426   unsigned CurDiagID;
427
428   enum {
429     /// MaxArguments - The maximum number of arguments we can hold. We currently
430     /// only support up to 10 arguments (%0-%9).  A single diagnostic with more
431     /// than that almost certainly has to be simplified anyway.
432     MaxArguments = 10
433   };
434
435   /// NumDiagArgs - This contains the number of entries in Arguments.
436   signed char NumDiagArgs;
437   /// NumRanges - This is the number of ranges in the DiagRanges array.
438   unsigned char NumDiagRanges;
439   /// \brief The number of code modifications hints in the
440   /// CodeModificationHints array.
441   unsigned char NumCodeModificationHints;
442
443   /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
444   /// values, with one for each argument.  This specifies whether the argument
445   /// is in DiagArgumentsStr or in DiagArguments.
446   unsigned char DiagArgumentsKind[MaxArguments];
447
448   /// DiagArgumentsStr - This holds the values of each string argument for the
449   /// current diagnostic.  This value is only used when the corresponding
450   /// ArgumentKind is ak_std_string.
451   std::string DiagArgumentsStr[MaxArguments];
452
453   /// DiagArgumentsVal - The values for the various substitution positions. This
454   /// is used when the argument is not an std::string.  The specific value is
455   /// mangled into an intptr_t and the intepretation depends on exactly what
456   /// sort of argument kind it is.
457   intptr_t DiagArgumentsVal[MaxArguments];
458
459   /// DiagRanges - The list of ranges added to this diagnostic.  It currently
460   /// only support 10 ranges, could easily be extended if needed.
461   const SourceRange *DiagRanges[10];
462
463   enum { MaxCodeModificationHints = 3 };
464
465   /// CodeModificationHints - If valid, provides a hint with some code
466   /// to insert, remove, or modify at a particular position.
467   CodeModificationHint CodeModificationHints[MaxCodeModificationHints];
468
469   /// ProcessDiag - This is the method used to report a diagnostic that is
470   /// finally fully formed.
471   ///
472   /// \returns true if the diagnostic was emitted, false if it was
473   /// suppressed.
474   bool ProcessDiag();
475 };
476
477 //===----------------------------------------------------------------------===//
478 // DiagnosticBuilder
479 //===----------------------------------------------------------------------===//
480
481 /// DiagnosticBuilder - This is a little helper class used to produce
482 /// diagnostics.  This is constructed by the Diagnostic::Report method, and
483 /// allows insertion of extra information (arguments and source ranges) into the
484 /// currently "in flight" diagnostic.  When the temporary for the builder is
485 /// destroyed, the diagnostic is issued.
486 ///
487 /// Note that many of these will be created as temporary objects (many call
488 /// sites), so we want them to be small and we never want their address taken.
489 /// This ensures that compilers with somewhat reasonable optimizers will promote
490 /// the common fields to registers, eliminating increments of the NumArgs field,
491 /// for example.
492 class DiagnosticBuilder {
493   mutable Diagnostic *DiagObj;
494   mutable unsigned NumArgs, NumRanges, NumCodeModificationHints;
495
496   void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
497   friend class Diagnostic;
498   explicit DiagnosticBuilder(Diagnostic *diagObj)
499     : DiagObj(diagObj), NumArgs(0), NumRanges(0),
500       NumCodeModificationHints(0) {}
501
502 public:
503   /// Copy constructor.  When copied, this "takes" the diagnostic info from the
504   /// input and neuters it.
505   DiagnosticBuilder(const DiagnosticBuilder &D) {
506     DiagObj = D.DiagObj;
507     D.DiagObj = 0;
508     NumArgs = D.NumArgs;
509     NumRanges = D.NumRanges;
510     NumCodeModificationHints = D.NumCodeModificationHints;
511   }
512
513   /// \brief Simple enumeration value used to give a name to the
514   /// suppress-diagnostic constructor.
515   enum SuppressKind { Suppress };
516
517   /// \brief Create an empty DiagnosticBuilder object that represents
518   /// no actual diagnostic.
519   explicit DiagnosticBuilder(SuppressKind)
520     : DiagObj(0), NumArgs(0), NumRanges(0), NumCodeModificationHints(0) { }
521
522   /// \brief Force the diagnostic builder to emit the diagnostic now.
523   ///
524   /// Once this function has been called, the DiagnosticBuilder object
525   /// should not be used again before it is destroyed.
526   ///
527   /// \returns true if a diagnostic was emitted, false if the
528   /// diagnostic was suppressed.
529   bool Emit() {
530     // If DiagObj is null, then its soul was stolen by the copy ctor
531     // or the user called Emit().
532     if (DiagObj == 0) return false;
533
534     // When emitting diagnostics, we set the final argument count into
535     // the Diagnostic object.
536     DiagObj->NumDiagArgs = NumArgs;
537     DiagObj->NumDiagRanges = NumRanges;
538     DiagObj->NumCodeModificationHints = NumCodeModificationHints;
539
540     // Process the diagnostic, sending the accumulated information to the
541     // DiagnosticClient.
542     bool Emitted = DiagObj->ProcessDiag();
543
544     // Clear out the current diagnostic object.
545     DiagObj->Clear();
546
547     // This diagnostic is dead.
548     DiagObj = 0;
549
550     return Emitted;
551   }
552
553   /// Destructor - The dtor emits the diagnostic if it hasn't already
554   /// been emitted.
555   ~DiagnosticBuilder() { Emit(); }
556
557   /// Operator bool: conversion of DiagnosticBuilder to bool always returns
558   /// true.  This allows is to be used in boolean error contexts like:
559   /// return Diag(...);
560   operator bool() const { return true; }
561
562   void AddString(llvm::StringRef S) const {
563     assert(NumArgs < Diagnostic::MaxArguments &&
564            "Too many arguments to diagnostic!");
565     if (DiagObj) {
566       DiagObj->DiagArgumentsKind[NumArgs] = Diagnostic::ak_std_string;
567       DiagObj->DiagArgumentsStr[NumArgs++] = S;
568     }
569   }
570
571   void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const {
572     assert(NumArgs < Diagnostic::MaxArguments &&
573            "Too many arguments to diagnostic!");
574     if (DiagObj) {
575       DiagObj->DiagArgumentsKind[NumArgs] = Kind;
576       DiagObj->DiagArgumentsVal[NumArgs++] = V;
577     }
578   }
579
580   void AddSourceRange(const SourceRange &R) const {
581     assert(NumRanges <
582            sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) &&
583            "Too many arguments to diagnostic!");
584     if (DiagObj)
585       DiagObj->DiagRanges[NumRanges++] = &R;
586   }
587
588   void AddCodeModificationHint(const CodeModificationHint &Hint) const {
589     assert(NumCodeModificationHints < Diagnostic::MaxCodeModificationHints &&
590            "Too many code modification hints!");
591     if (DiagObj)
592       DiagObj->CodeModificationHints[NumCodeModificationHints++] = Hint;
593   }
594 };
595
596 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
597                                            llvm::StringRef S) {
598   DB.AddString(S);
599   return DB;
600 }
601
602 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
603                                            const char *Str) {
604   DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
605                   Diagnostic::ak_c_string);
606   return DB;
607 }
608
609 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
610   DB.AddTaggedVal(I, Diagnostic::ak_sint);
611   return DB;
612 }
613
614 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,bool I) {
615   DB.AddTaggedVal(I, Diagnostic::ak_sint);
616   return DB;
617 }
618
619 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
620                                            unsigned I) {
621   DB.AddTaggedVal(I, Diagnostic::ak_uint);
622   return DB;
623 }
624
625 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
626                                            const IdentifierInfo *II) {
627   DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
628                   Diagnostic::ak_identifierinfo);
629   return DB;
630 }
631
632 // Adds a DeclContext to the diagnostic. The enable_if template magic is here
633 // so that we only match those arguments that are (statically) DeclContexts;
634 // other arguments that derive from DeclContext (e.g., RecordDecls) will not
635 // match.
636 template<typename T>
637 inline
638 typename llvm::enable_if<llvm::is_same<T, DeclContext>, 
639                          const DiagnosticBuilder &>::type
640 operator<<(const DiagnosticBuilder &DB, T *DC) {
641   DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
642                   Diagnostic::ak_declcontext);
643   return DB;
644 }
645   
646 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
647                                            const SourceRange &R) {
648   DB.AddSourceRange(R);
649   return DB;
650 }
651
652 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
653                                            const CodeModificationHint &Hint) {
654   DB.AddCodeModificationHint(Hint);
655   return DB;
656 }
657
658 /// Report - Issue the message to the client.  DiagID is a member of the
659 /// diag::kind enum.  This actually returns a new instance of DiagnosticBuilder
660 /// which emits the diagnostics (through ProcessDiag) when it is destroyed.
661 inline DiagnosticBuilder Diagnostic::Report(FullSourceLoc Loc, unsigned DiagID){
662   assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
663   CurDiagLoc = Loc;
664   CurDiagID = DiagID;
665   return DiagnosticBuilder(this);
666 }
667
668 //===----------------------------------------------------------------------===//
669 // DiagnosticInfo
670 //===----------------------------------------------------------------------===//
671
672 /// DiagnosticInfo - This is a little helper class (which is basically a smart
673 /// pointer that forward info from Diagnostic) that allows clients to enquire
674 /// about the currently in-flight diagnostic.
675 class DiagnosticInfo {
676   const Diagnostic *DiagObj;
677 public:
678   explicit DiagnosticInfo(const Diagnostic *DO) : DiagObj(DO) {}
679
680   const Diagnostic *getDiags() const { return DiagObj; }
681   unsigned getID() const { return DiagObj->CurDiagID; }
682   const FullSourceLoc &getLocation() const { return DiagObj->CurDiagLoc; }
683
684   unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
685
686   /// getArgKind - Return the kind of the specified index.  Based on the kind
687   /// of argument, the accessors below can be used to get the value.
688   Diagnostic::ArgumentKind getArgKind(unsigned Idx) const {
689     assert(Idx < getNumArgs() && "Argument index out of range!");
690     return (Diagnostic::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
691   }
692
693   /// getArgStdStr - Return the provided argument string specified by Idx.
694   const std::string &getArgStdStr(unsigned Idx) const {
695     assert(getArgKind(Idx) == Diagnostic::ak_std_string &&
696            "invalid argument accessor!");
697     return DiagObj->DiagArgumentsStr[Idx];
698   }
699
700   /// getArgCStr - Return the specified C string argument.
701   const char *getArgCStr(unsigned Idx) const {
702     assert(getArgKind(Idx) == Diagnostic::ak_c_string &&
703            "invalid argument accessor!");
704     return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
705   }
706
707   /// getArgSInt - Return the specified signed integer argument.
708   int getArgSInt(unsigned Idx) const {
709     assert(getArgKind(Idx) == Diagnostic::ak_sint &&
710            "invalid argument accessor!");
711     return (int)DiagObj->DiagArgumentsVal[Idx];
712   }
713
714   /// getArgUInt - Return the specified unsigned integer argument.
715   unsigned getArgUInt(unsigned Idx) const {
716     assert(getArgKind(Idx) == Diagnostic::ak_uint &&
717            "invalid argument accessor!");
718     return (unsigned)DiagObj->DiagArgumentsVal[Idx];
719   }
720
721   /// getArgIdentifier - Return the specified IdentifierInfo argument.
722   const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
723     assert(getArgKind(Idx) == Diagnostic::ak_identifierinfo &&
724            "invalid argument accessor!");
725     return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
726   }
727
728   /// getRawArg - Return the specified non-string argument in an opaque form.
729   intptr_t getRawArg(unsigned Idx) const {
730     assert(getArgKind(Idx) != Diagnostic::ak_std_string &&
731            "invalid argument accessor!");
732     return DiagObj->DiagArgumentsVal[Idx];
733   }
734
735
736   /// getNumRanges - Return the number of source ranges associated with this
737   /// diagnostic.
738   unsigned getNumRanges() const {
739     return DiagObj->NumDiagRanges;
740   }
741
742   const SourceRange &getRange(unsigned Idx) const {
743     assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
744     return *DiagObj->DiagRanges[Idx];
745   }
746
747   unsigned getNumCodeModificationHints() const {
748     return DiagObj->NumCodeModificationHints;
749   }
750
751   const CodeModificationHint &getCodeModificationHint(unsigned Idx) const {
752     return DiagObj->CodeModificationHints[Idx];
753   }
754
755   const CodeModificationHint *getCodeModificationHints() const {
756     return DiagObj->NumCodeModificationHints?
757              &DiagObj->CodeModificationHints[0] : 0;
758   }
759
760   /// FormatDiagnostic - Format this diagnostic into a string, substituting the
761   /// formal arguments into the %0 slots.  The result is appended onto the Str
762   /// array.
763   void FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const;
764 };
765
766 /// DiagnosticClient - This is an abstract interface implemented by clients of
767 /// the front-end, which formats and prints fully processed diagnostics.
768 class DiagnosticClient {
769 public:
770   virtual ~DiagnosticClient();
771
772   /// setLangOptions - This is set by clients of diagnostics when they know the
773   /// language parameters of the diagnostics that may be sent through.  Note
774   /// that this can change over time if a DiagClient has multiple languages sent
775   /// through it.  It may also be set to null (e.g. when processing command line
776   /// options).
777   virtual void setLangOptions(const LangOptions *LO) {}
778
779   /// IncludeInDiagnosticCounts - This method (whose default implementation
780   ///  returns true) indicates whether the diagnostics handled by this
781   ///  DiagnosticClient should be included in the number of diagnostics
782   ///  reported by Diagnostic.
783   virtual bool IncludeInDiagnosticCounts() const;
784
785   /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
786   /// capturing it to a log as needed.
787   virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
788                                 const DiagnosticInfo &Info) = 0;
789 };
790
791 }  // end namespace clang
792
793 #endif