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