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