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