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