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