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