DiagnosticIDs.cpp revision 234353
1//===--- DiagnosticIDs.cpp - Diagnostic IDs Handling ----------------------===//
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 implements the Diagnostic IDs-related interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Basic/DiagnosticIDs.h"
15#include "clang/Basic/AllDiagnostics.h"
16#include "clang/Basic/DiagnosticCategories.h"
17#include "clang/Basic/SourceManager.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/Support/ErrorHandling.h"
20
21#include <map>
22using namespace clang;
23
24//===----------------------------------------------------------------------===//
25// Builtin Diagnostic information
26//===----------------------------------------------------------------------===//
27
28namespace {
29
30// Diagnostic classes.
31enum {
32  CLASS_NOTE       = 0x01,
33  CLASS_WARNING    = 0x02,
34  CLASS_EXTENSION  = 0x03,
35  CLASS_ERROR      = 0x04
36};
37
38struct StaticDiagInfoRec {
39  unsigned short DiagID;
40  unsigned Mapping : 3;
41  unsigned Class : 3;
42  unsigned SFINAE : 1;
43  unsigned AccessControl : 1;
44  unsigned WarnNoWerror : 1;
45  unsigned WarnShowInSystemHeader : 1;
46  unsigned Category : 5;
47
48  uint16_t OptionGroupIndex;
49
50  uint16_t DescriptionLen;
51  const char *DescriptionStr;
52
53  unsigned getOptionGroupIndex() const {
54    return OptionGroupIndex;
55  }
56
57  StringRef getDescription() const {
58    return StringRef(DescriptionStr, DescriptionLen);
59  }
60
61  bool operator<(const StaticDiagInfoRec &RHS) const {
62    return DiagID < RHS.DiagID;
63  }
64};
65
66} // namespace anonymous
67
68static const StaticDiagInfoRec StaticDiagInfo[] = {
69#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,               \
70             SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,              \
71             CATEGORY)                                            \
72  { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, ACCESS,           \
73    NOWERROR, SHOWINSYSHEADER, CATEGORY, GROUP,                   \
74    STR_SIZE(DESC, uint16_t), DESC },
75#include "clang/Basic/DiagnosticCommonKinds.inc"
76#include "clang/Basic/DiagnosticDriverKinds.inc"
77#include "clang/Basic/DiagnosticFrontendKinds.inc"
78#include "clang/Basic/DiagnosticSerializationKinds.inc"
79#include "clang/Basic/DiagnosticLexKinds.inc"
80#include "clang/Basic/DiagnosticParseKinds.inc"
81#include "clang/Basic/DiagnosticASTKinds.inc"
82#include "clang/Basic/DiagnosticSemaKinds.inc"
83#include "clang/Basic/DiagnosticAnalysisKinds.inc"
84#undef DIAG
85  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
86};
87
88static const unsigned StaticDiagInfoSize =
89  sizeof(StaticDiagInfo)/sizeof(StaticDiagInfo[0])-1;
90
91/// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID,
92/// or null if the ID is invalid.
93static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
94  // If assertions are enabled, verify that the StaticDiagInfo array is sorted.
95#ifndef NDEBUG
96  static bool IsFirst = true;
97  if (IsFirst) {
98    for (unsigned i = 1; i != StaticDiagInfoSize; ++i) {
99      assert(StaticDiagInfo[i-1].DiagID != StaticDiagInfo[i].DiagID &&
100             "Diag ID conflict, the enums at the start of clang::diag (in "
101             "DiagnosticIDs.h) probably need to be increased");
102
103      assert(StaticDiagInfo[i-1] < StaticDiagInfo[i] &&
104             "Improperly sorted diag info");
105    }
106    IsFirst = false;
107  }
108#endif
109
110  // Search the diagnostic table with a binary search.
111  StaticDiagInfoRec Find = { static_cast<unsigned short>(DiagID),
112                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
113
114  const StaticDiagInfoRec *Found =
115    std::lower_bound(StaticDiagInfo, StaticDiagInfo + StaticDiagInfoSize, Find);
116  if (Found == StaticDiagInfo + StaticDiagInfoSize ||
117      Found->DiagID != DiagID)
118    return 0;
119
120  return Found;
121}
122
123static DiagnosticMappingInfo GetDefaultDiagMappingInfo(unsigned DiagID) {
124  DiagnosticMappingInfo Info = DiagnosticMappingInfo::Make(
125    diag::MAP_FATAL, /*IsUser=*/false, /*IsPragma=*/false);
126
127  if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) {
128    Info.setMapping((diag::Mapping) StaticInfo->Mapping);
129
130    if (StaticInfo->WarnNoWerror) {
131      assert(Info.getMapping() == diag::MAP_WARNING &&
132             "Unexpected mapping with no-Werror bit!");
133      Info.setNoWarningAsError(true);
134    }
135
136    if (StaticInfo->WarnShowInSystemHeader) {
137      assert(Info.getMapping() == diag::MAP_WARNING &&
138             "Unexpected mapping with show-in-system-header bit!");
139      Info.setShowInSystemHeader(true);
140    }
141  }
142
143  return Info;
144}
145
146/// getCategoryNumberForDiag - Return the category number that a specified
147/// DiagID belongs to, or 0 if no category.
148unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) {
149  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
150    return Info->Category;
151  return 0;
152}
153
154namespace {
155  // The diagnostic category names.
156  struct StaticDiagCategoryRec {
157    const char *NameStr;
158    uint8_t NameLen;
159
160    StringRef getName() const {
161      return StringRef(NameStr, NameLen);
162    }
163  };
164}
165
166// Unfortunately, the split between DiagnosticIDs and Diagnostic is not
167// particularly clean, but for now we just implement this method here so we can
168// access GetDefaultDiagMapping.
169DiagnosticMappingInfo &DiagnosticsEngine::DiagState::getOrAddMappingInfo(
170  diag::kind Diag)
171{
172  std::pair<iterator, bool> Result = DiagMap.insert(
173    std::make_pair(Diag, DiagnosticMappingInfo()));
174
175  // Initialize the entry if we added it.
176  if (Result.second)
177    Result.first->second = GetDefaultDiagMappingInfo(Diag);
178
179  return Result.first->second;
180}
181
182static const StaticDiagCategoryRec CategoryNameTable[] = {
183#define GET_CATEGORY_TABLE
184#define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) },
185#include "clang/Basic/DiagnosticGroups.inc"
186#undef GET_CATEGORY_TABLE
187  { 0, 0 }
188};
189
190/// getNumberOfCategories - Return the number of categories
191unsigned DiagnosticIDs::getNumberOfCategories() {
192  return sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1;
193}
194
195/// getCategoryNameFromID - Given a category ID, return the name of the
196/// category, an empty string if CategoryID is zero, or null if CategoryID is
197/// invalid.
198StringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
199  if (CategoryID >= getNumberOfCategories())
200   return StringRef();
201  return CategoryNameTable[CategoryID].getName();
202}
203
204
205
206DiagnosticIDs::SFINAEResponse
207DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) {
208  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) {
209    if (Info->AccessControl)
210      return SFINAE_AccessControl;
211
212    if (!Info->SFINAE)
213      return SFINAE_Report;
214
215    if (Info->Class == CLASS_ERROR)
216      return SFINAE_SubstitutionFailure;
217
218    // Suppress notes, warnings, and extensions;
219    return SFINAE_Suppress;
220  }
221
222  return SFINAE_Report;
223}
224
225/// getBuiltinDiagClass - Return the class field of the diagnostic.
226///
227static unsigned getBuiltinDiagClass(unsigned DiagID) {
228  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
229    return Info->Class;
230  return ~0U;
231}
232
233//===----------------------------------------------------------------------===//
234// Custom Diagnostic information
235//===----------------------------------------------------------------------===//
236
237namespace clang {
238  namespace diag {
239    class CustomDiagInfo {
240      typedef std::pair<DiagnosticIDs::Level, std::string> DiagDesc;
241      std::vector<DiagDesc> DiagInfo;
242      std::map<DiagDesc, unsigned> DiagIDs;
243    public:
244
245      /// getDescription - Return the description of the specified custom
246      /// diagnostic.
247      StringRef getDescription(unsigned DiagID) const {
248        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
249               "Invalid diagnosic ID");
250        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second;
251      }
252
253      /// getLevel - Return the level of the specified custom diagnostic.
254      DiagnosticIDs::Level getLevel(unsigned DiagID) const {
255        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
256               "Invalid diagnosic ID");
257        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
258      }
259
260      unsigned getOrCreateDiagID(DiagnosticIDs::Level L, StringRef Message,
261                                 DiagnosticIDs &Diags) {
262        DiagDesc D(L, Message);
263        // Check to see if it already exists.
264        std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D);
265        if (I != DiagIDs.end() && I->first == D)
266          return I->second;
267
268        // If not, assign a new ID.
269        unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT;
270        DiagIDs.insert(std::make_pair(D, ID));
271        DiagInfo.push_back(D);
272        return ID;
273      }
274    };
275
276  } // end diag namespace
277} // end clang namespace
278
279
280//===----------------------------------------------------------------------===//
281// Common Diagnostic implementation
282//===----------------------------------------------------------------------===//
283
284DiagnosticIDs::DiagnosticIDs() {
285  CustomDiagInfo = 0;
286}
287
288DiagnosticIDs::~DiagnosticIDs() {
289  delete CustomDiagInfo;
290}
291
292/// getCustomDiagID - Return an ID for a diagnostic with the specified message
293/// and level.  If this is the first request for this diagnosic, it is
294/// registered and created, otherwise the existing ID is returned.
295unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef Message) {
296  if (CustomDiagInfo == 0)
297    CustomDiagInfo = new diag::CustomDiagInfo();
298  return CustomDiagInfo->getOrCreateDiagID(L, Message, *this);
299}
300
301
302/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic
303/// level of the specified diagnostic ID is a Warning or Extension.
304/// This only works on builtin diagnostics, not custom ones, and is not legal to
305/// call on NOTEs.
306bool DiagnosticIDs::isBuiltinWarningOrExtension(unsigned DiagID) {
307  return DiagID < diag::DIAG_UPPER_LIMIT &&
308         getBuiltinDiagClass(DiagID) != CLASS_ERROR;
309}
310
311/// \brief Determine whether the given built-in diagnostic ID is a
312/// Note.
313bool DiagnosticIDs::isBuiltinNote(unsigned DiagID) {
314  return DiagID < diag::DIAG_UPPER_LIMIT &&
315    getBuiltinDiagClass(DiagID) == CLASS_NOTE;
316}
317
318/// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
319/// ID is for an extension of some sort.  This also returns EnabledByDefault,
320/// which is set to indicate whether the diagnostic is ignored by default (in
321/// which case -pedantic enables it) or treated as a warning/error by default.
322///
323bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID,
324                                        bool &EnabledByDefault) {
325  if (DiagID >= diag::DIAG_UPPER_LIMIT ||
326      getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
327    return false;
328
329  EnabledByDefault =
330    GetDefaultDiagMappingInfo(DiagID).getMapping() != diag::MAP_IGNORE;
331  return true;
332}
333
334bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) {
335  if (DiagID >= diag::DIAG_UPPER_LIMIT)
336    return false;
337
338  return GetDefaultDiagMappingInfo(DiagID).getMapping() == diag::MAP_ERROR;
339}
340
341/// getDescription - Given a diagnostic ID, return a description of the
342/// issue.
343StringRef DiagnosticIDs::getDescription(unsigned DiagID) const {
344  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
345    return Info->getDescription();
346  return CustomDiagInfo->getDescription(DiagID);
347}
348
349/// getDiagnosticLevel - Based on the way the client configured the
350/// DiagnosticsEngine object, classify the specified diagnostic ID into a Level,
351/// by consumable the DiagnosticClient.
352DiagnosticIDs::Level
353DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
354                                  const DiagnosticsEngine &Diag) const {
355  // Handle custom diagnostics, which cannot be mapped.
356  if (DiagID >= diag::DIAG_UPPER_LIMIT)
357    return CustomDiagInfo->getLevel(DiagID);
358
359  unsigned DiagClass = getBuiltinDiagClass(DiagID);
360  assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!");
361  return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag);
362}
363
364/// \brief Based on the way the client configured the Diagnostic
365/// object, classify the specified diagnostic ID into a Level, consumable by
366/// the DiagnosticClient.
367///
368/// \param Loc The source location we are interested in finding out the
369/// diagnostic state. Can be null in order to query the latest state.
370DiagnosticIDs::Level
371DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
372                                  SourceLocation Loc,
373                                  const DiagnosticsEngine &Diag) const {
374  // Specific non-error diagnostics may be mapped to various levels from ignored
375  // to error.  Errors can only be mapped to fatal.
376  DiagnosticIDs::Level Result = DiagnosticIDs::Fatal;
377
378  DiagnosticsEngine::DiagStatePointsTy::iterator
379    Pos = Diag.GetDiagStatePointForLoc(Loc);
380  DiagnosticsEngine::DiagState *State = Pos->State;
381
382  // Get the mapping information, or compute it lazily.
383  DiagnosticMappingInfo &MappingInfo = State->getOrAddMappingInfo(
384    (diag::kind)DiagID);
385
386  switch (MappingInfo.getMapping()) {
387  case diag::MAP_IGNORE:
388    Result = DiagnosticIDs::Ignored;
389    break;
390  case diag::MAP_WARNING:
391    Result = DiagnosticIDs::Warning;
392    break;
393  case diag::MAP_ERROR:
394    Result = DiagnosticIDs::Error;
395    break;
396  case diag::MAP_FATAL:
397    Result = DiagnosticIDs::Fatal;
398    break;
399  }
400
401  // Upgrade ignored diagnostics if -Weverything is enabled.
402  if (Diag.EnableAllWarnings && Result == DiagnosticIDs::Ignored &&
403      !MappingInfo.isUser())
404    Result = DiagnosticIDs::Warning;
405
406  // Ignore -pedantic diagnostics inside __extension__ blocks.
407  // (The diagnostics controlled by -pedantic are the extension diagnostics
408  // that are not enabled by default.)
409  bool EnabledByDefault = false;
410  bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault);
411  if (Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault)
412    return DiagnosticIDs::Ignored;
413
414  // For extension diagnostics that haven't been explicitly mapped, check if we
415  // should upgrade the diagnostic.
416  if (IsExtensionDiag && !MappingInfo.isUser()) {
417    switch (Diag.ExtBehavior) {
418    case DiagnosticsEngine::Ext_Ignore:
419      break;
420    case DiagnosticsEngine::Ext_Warn:
421      // Upgrade ignored diagnostics to warnings.
422      if (Result == DiagnosticIDs::Ignored)
423        Result = DiagnosticIDs::Warning;
424      break;
425    case DiagnosticsEngine::Ext_Error:
426      // Upgrade ignored or warning diagnostics to errors.
427      if (Result == DiagnosticIDs::Ignored || Result == DiagnosticIDs::Warning)
428        Result = DiagnosticIDs::Error;
429      break;
430    }
431  }
432
433  // At this point, ignored errors can no longer be upgraded.
434  if (Result == DiagnosticIDs::Ignored)
435    return Result;
436
437  // Honor -w, which is lower in priority than pedantic-errors, but higher than
438  // -Werror.
439  if (Result == DiagnosticIDs::Warning && Diag.IgnoreAllWarnings)
440    return DiagnosticIDs::Ignored;
441
442  // If -Werror is enabled, map warnings to errors unless explicitly disabled.
443  if (Result == DiagnosticIDs::Warning) {
444    if (Diag.WarningsAsErrors && !MappingInfo.hasNoWarningAsError())
445      Result = DiagnosticIDs::Error;
446  }
447
448  // If -Wfatal-errors is enabled, map errors to fatal unless explicity
449  // disabled.
450  if (Result == DiagnosticIDs::Error) {
451    if (Diag.ErrorsAsFatal && !MappingInfo.hasNoErrorAsFatal())
452      Result = DiagnosticIDs::Fatal;
453  }
454
455  // If we are in a system header, we ignore it. We look at the diagnostic class
456  // because we also want to ignore extensions and warnings in -Werror and
457  // -pedantic-errors modes, which *map* warnings/extensions to errors.
458  if (Result >= DiagnosticIDs::Warning &&
459      DiagClass != CLASS_ERROR &&
460      // Custom diagnostics always are emitted in system headers.
461      DiagID < diag::DIAG_UPPER_LIMIT &&
462      !MappingInfo.hasShowInSystemHeader() &&
463      Diag.SuppressSystemWarnings &&
464      Loc.isValid() &&
465      Diag.getSourceManager().isInSystemHeader(
466          Diag.getSourceManager().getExpansionLoc(Loc)))
467    return DiagnosticIDs::Ignored;
468
469  return Result;
470}
471
472struct clang::WarningOption {
473  // Be safe with the size of 'NameLen' because we don't statically check if
474  // the size will fit in the field; the struct size won't decrease with a
475  // shorter type anyway.
476  size_t NameLen;
477  const char *NameStr;
478  const short *Members;
479  const short *SubGroups;
480
481  StringRef getName() const {
482    return StringRef(NameStr, NameLen);
483  }
484};
485
486#define GET_DIAG_ARRAYS
487#include "clang/Basic/DiagnosticGroups.inc"
488#undef GET_DIAG_ARRAYS
489
490// Second the table of options, sorted by name for fast binary lookup.
491static const WarningOption OptionTable[] = {
492#define GET_DIAG_TABLE
493#include "clang/Basic/DiagnosticGroups.inc"
494#undef GET_DIAG_TABLE
495};
496static const size_t OptionTableSize =
497sizeof(OptionTable) / sizeof(OptionTable[0]);
498
499static bool WarningOptionCompare(const WarningOption &LHS,
500                                 const WarningOption &RHS) {
501  return LHS.getName() < RHS.getName();
502}
503
504/// getWarningOptionForDiag - Return the lowest-level warning option that
505/// enables the specified diagnostic.  If there is no -Wfoo flag that controls
506/// the diagnostic, this returns null.
507StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
508  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
509    return OptionTable[Info->getOptionGroupIndex()].getName();
510  return StringRef();
511}
512
513void DiagnosticIDs::getDiagnosticsInGroup(
514  const WarningOption *Group,
515  llvm::SmallVectorImpl<diag::kind> &Diags) const
516{
517  // Add the members of the option diagnostic set.
518  if (const short *Member = Group->Members) {
519    for (; *Member != -1; ++Member)
520      Diags.push_back(*Member);
521  }
522
523  // Add the members of the subgroups.
524  if (const short *SubGroups = Group->SubGroups) {
525    for (; *SubGroups != (short)-1; ++SubGroups)
526      getDiagnosticsInGroup(&OptionTable[(short)*SubGroups], Diags);
527  }
528}
529
530bool DiagnosticIDs::getDiagnosticsInGroup(
531  StringRef Group,
532  llvm::SmallVectorImpl<diag::kind> &Diags) const
533{
534  WarningOption Key = { Group.size(), Group.data(), 0, 0 };
535  const WarningOption *Found =
536  std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
537                   WarningOptionCompare);
538  if (Found == OptionTable + OptionTableSize ||
539      Found->getName() != Group)
540    return true; // Option not found.
541
542  getDiagnosticsInGroup(Found, Diags);
543  return false;
544}
545
546void DiagnosticIDs::getAllDiagnostics(
547                               llvm::SmallVectorImpl<diag::kind> &Diags) const {
548  for (unsigned i = 0; i != StaticDiagInfoSize; ++i)
549    Diags.push_back(StaticDiagInfo[i].DiagID);
550}
551
552StringRef DiagnosticIDs::getNearestWarningOption(StringRef Group) {
553  StringRef Best;
554  unsigned BestDistance = Group.size() + 1; // Sanity threshold.
555  for (const WarningOption *i = OptionTable, *e = OptionTable + OptionTableSize;
556       i != e; ++i) {
557    // Don't suggest ignored warning flags.
558    if (!i->Members && !i->SubGroups)
559      continue;
560
561    unsigned Distance = i->getName().edit_distance(Group, true, BestDistance);
562    if (Distance == BestDistance) {
563      // Two matches with the same distance, don't prefer one over the other.
564      Best = "";
565    } else if (Distance < BestDistance) {
566      // This is a better match.
567      Best = i->getName();
568      BestDistance = Distance;
569    }
570  }
571
572  return Best;
573}
574
575/// ProcessDiag - This is the method used to report a diagnostic that is
576/// finally fully formed.
577bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const {
578  Diagnostic Info(&Diag);
579
580  if (Diag.SuppressAllDiagnostics)
581    return false;
582
583  assert(Diag.getClient() && "DiagnosticClient not set!");
584
585  // Figure out the diagnostic level of this message.
586  DiagnosticIDs::Level DiagLevel;
587  unsigned DiagID = Info.getID();
588
589  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
590    // Handle custom diagnostics, which cannot be mapped.
591    DiagLevel = CustomDiagInfo->getLevel(DiagID);
592  } else {
593    // Get the class of the diagnostic.  If this is a NOTE, map it onto whatever
594    // the diagnostic level was for the previous diagnostic so that it is
595    // filtered the same as the previous diagnostic.
596    unsigned DiagClass = getBuiltinDiagClass(DiagID);
597    if (DiagClass == CLASS_NOTE) {
598      DiagLevel = DiagnosticIDs::Note;
599    } else {
600      DiagLevel = getDiagnosticLevel(DiagID, DiagClass, Info.getLocation(),
601                                     Diag);
602    }
603  }
604
605  if (DiagLevel != DiagnosticIDs::Note) {
606    // Record that a fatal error occurred only when we see a second
607    // non-note diagnostic. This allows notes to be attached to the
608    // fatal error, but suppresses any diagnostics that follow those
609    // notes.
610    if (Diag.LastDiagLevel == DiagnosticIDs::Fatal)
611      Diag.FatalErrorOccurred = true;
612
613    Diag.LastDiagLevel = DiagLevel;
614  }
615
616  // Update counts for DiagnosticErrorTrap even if a fatal error occurred.
617  if (DiagLevel >= DiagnosticIDs::Error) {
618    ++Diag.TrapNumErrorsOccurred;
619    if (isUnrecoverable(DiagID))
620      ++Diag.TrapNumUnrecoverableErrorsOccurred;
621  }
622
623  // If a fatal error has already been emitted, silence all subsequent
624  // diagnostics.
625  if (Diag.FatalErrorOccurred) {
626    if (DiagLevel >= DiagnosticIDs::Error &&
627        Diag.Client->IncludeInDiagnosticCounts()) {
628      ++Diag.NumErrors;
629      ++Diag.NumErrorsSuppressed;
630    }
631
632    return false;
633  }
634
635  // If the client doesn't care about this message, don't issue it.  If this is
636  // a note and the last real diagnostic was ignored, ignore it too.
637  if (DiagLevel == DiagnosticIDs::Ignored ||
638      (DiagLevel == DiagnosticIDs::Note &&
639       Diag.LastDiagLevel == DiagnosticIDs::Ignored))
640    return false;
641
642  if (DiagLevel >= DiagnosticIDs::Error) {
643    if (isUnrecoverable(DiagID))
644      Diag.UnrecoverableErrorOccurred = true;
645
646    if (Diag.Client->IncludeInDiagnosticCounts()) {
647      Diag.ErrorOccurred = true;
648      ++Diag.NumErrors;
649    }
650
651    // If we've emitted a lot of errors, emit a fatal error instead of it to
652    // stop a flood of bogus errors.
653    if (Diag.ErrorLimit && Diag.NumErrors > Diag.ErrorLimit &&
654        DiagLevel == DiagnosticIDs::Error) {
655      Diag.SetDelayedDiagnostic(diag::fatal_too_many_errors);
656      return false;
657    }
658  }
659
660  // Finally, report it.
661  Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info);
662  if (Diag.Client->IncludeInDiagnosticCounts()) {
663    if (DiagLevel == DiagnosticIDs::Warning)
664      ++Diag.NumWarnings;
665  }
666
667  Diag.CurDiagID = ~0U;
668
669  return true;
670}
671
672bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {
673  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
674    // Custom diagnostics.
675    return CustomDiagInfo->getLevel(DiagID) >= DiagnosticIDs::Error;
676  }
677
678  // Only errors may be unrecoverable.
679  if (getBuiltinDiagClass(DiagID) < CLASS_ERROR)
680    return false;
681
682  if (DiagID == diag::err_unavailable ||
683      DiagID == diag::err_unavailable_message)
684    return false;
685
686  // Currently we consider all ARC errors as recoverable.
687  if (isARCDiagnostic(DiagID))
688    return false;
689
690  return true;
691}
692
693bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) {
694  unsigned cat = getCategoryNumberForDiag(DiagID);
695  return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC ");
696}
697
698