clang API Documentation
00001 //===--- DiagnosticIDs.cpp - Diagnostic IDs Handling ----------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the Diagnostic IDs-related interfaces. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/Basic/DiagnosticIDs.h" 00015 #include "clang/Basic/AllDiagnostics.h" 00016 #include "clang/Basic/DiagnosticCategories.h" 00017 #include "clang/Basic/SourceManager.h" 00018 #include "llvm/ADT/SmallVector.h" 00019 #include "llvm/Support/ErrorHandling.h" 00020 00021 #include <map> 00022 using namespace clang; 00023 00024 //===----------------------------------------------------------------------===// 00025 // Builtin Diagnostic information 00026 //===----------------------------------------------------------------------===// 00027 00028 namespace { 00029 00030 // Diagnostic classes. 00031 enum { 00032 CLASS_NOTE = 0x01, 00033 CLASS_WARNING = 0x02, 00034 CLASS_EXTENSION = 0x03, 00035 CLASS_ERROR = 0x04 00036 }; 00037 00038 struct StaticDiagInfoRec { 00039 unsigned short DiagID; 00040 unsigned Mapping : 3; 00041 unsigned Class : 3; 00042 unsigned SFINAE : 1; 00043 unsigned AccessControl : 1; 00044 unsigned WarnNoWerror : 1; 00045 unsigned WarnShowInSystemHeader : 1; 00046 unsigned Category : 5; 00047 00048 uint16_t OptionGroupIndex; 00049 00050 uint16_t DescriptionLen; 00051 const char *DescriptionStr; 00052 00053 unsigned getOptionGroupIndex() const { 00054 return OptionGroupIndex; 00055 } 00056 00057 StringRef getDescription() const { 00058 return StringRef(DescriptionStr, DescriptionLen); 00059 } 00060 00061 bool operator<(const StaticDiagInfoRec &RHS) const { 00062 return DiagID < RHS.DiagID; 00063 } 00064 }; 00065 00066 } // namespace anonymous 00067 00068 static const StaticDiagInfoRec StaticDiagInfo[] = { 00069 #define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \ 00070 SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER, \ 00071 CATEGORY) \ 00072 { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, ACCESS, \ 00073 NOWERROR, SHOWINSYSHEADER, CATEGORY, GROUP, \ 00074 STR_SIZE(DESC, uint16_t), DESC }, 00075 #include "clang/Basic/DiagnosticCommonKinds.inc" 00076 #include "clang/Basic/DiagnosticDriverKinds.inc" 00077 #include "clang/Basic/DiagnosticFrontendKinds.inc" 00078 #include "clang/Basic/DiagnosticSerializationKinds.inc" 00079 #include "clang/Basic/DiagnosticLexKinds.inc" 00080 #include "clang/Basic/DiagnosticParseKinds.inc" 00081 #include "clang/Basic/DiagnosticASTKinds.inc" 00082 #include "clang/Basic/DiagnosticSemaKinds.inc" 00083 #include "clang/Basic/DiagnosticAnalysisKinds.inc" 00084 #undef DIAG 00085 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 00086 }; 00087 00088 static const unsigned StaticDiagInfoSize = 00089 sizeof(StaticDiagInfo)/sizeof(StaticDiagInfo[0])-1; 00090 00091 /// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID, 00092 /// or null if the ID is invalid. 00093 static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) { 00094 // If assertions are enabled, verify that the StaticDiagInfo array is sorted. 00095 #ifndef NDEBUG 00096 static bool IsFirst = true; 00097 if (IsFirst) { 00098 for (unsigned i = 1; i != StaticDiagInfoSize; ++i) { 00099 assert(StaticDiagInfo[i-1].DiagID != StaticDiagInfo[i].DiagID && 00100 "Diag ID conflict, the enums at the start of clang::diag (in " 00101 "DiagnosticIDs.h) probably need to be increased"); 00102 00103 assert(StaticDiagInfo[i-1] < StaticDiagInfo[i] && 00104 "Improperly sorted diag info"); 00105 } 00106 IsFirst = false; 00107 } 00108 #endif 00109 00110 // Search the diagnostic table with a binary search. 00111 StaticDiagInfoRec Find = { static_cast<unsigned short>(DiagID), 00112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 00113 00114 const StaticDiagInfoRec *Found = 00115 std::lower_bound(StaticDiagInfo, StaticDiagInfo + StaticDiagInfoSize, Find); 00116 if (Found == StaticDiagInfo + StaticDiagInfoSize || 00117 Found->DiagID != DiagID) 00118 return 0; 00119 00120 return Found; 00121 } 00122 00123 static DiagnosticMappingInfo GetDefaultDiagMappingInfo(unsigned DiagID) { 00124 DiagnosticMappingInfo Info = DiagnosticMappingInfo::Make( 00125 diag::MAP_FATAL, /*IsUser=*/false, /*IsPragma=*/false); 00126 00127 if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) { 00128 Info.setMapping((diag::Mapping) StaticInfo->Mapping); 00129 00130 if (StaticInfo->WarnNoWerror) { 00131 assert(Info.getMapping() == diag::MAP_WARNING && 00132 "Unexpected mapping with no-Werror bit!"); 00133 Info.setNoWarningAsError(true); 00134 } 00135 00136 if (StaticInfo->WarnShowInSystemHeader) { 00137 assert(Info.getMapping() == diag::MAP_WARNING && 00138 "Unexpected mapping with show-in-system-header bit!"); 00139 Info.setShowInSystemHeader(true); 00140 } 00141 } 00142 00143 return Info; 00144 } 00145 00146 /// getCategoryNumberForDiag - Return the category number that a specified 00147 /// DiagID belongs to, or 0 if no category. 00148 unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) { 00149 if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) 00150 return Info->Category; 00151 return 0; 00152 } 00153 00154 namespace { 00155 // The diagnostic category names. 00156 struct StaticDiagCategoryRec { 00157 const char *NameStr; 00158 uint8_t NameLen; 00159 00160 StringRef getName() const { 00161 return StringRef(NameStr, NameLen); 00162 } 00163 }; 00164 } 00165 00166 // Unfortunately, the split between DiagnosticIDs and Diagnostic is not 00167 // particularly clean, but for now we just implement this method here so we can 00168 // access GetDefaultDiagMapping. 00169 DiagnosticMappingInfo &DiagnosticsEngine::DiagState::getOrAddMappingInfo( 00170 diag::kind Diag) 00171 { 00172 std::pair<iterator, bool> Result = DiagMap.insert( 00173 std::make_pair(Diag, DiagnosticMappingInfo())); 00174 00175 // Initialize the entry if we added it. 00176 if (Result.second) 00177 Result.first->second = GetDefaultDiagMappingInfo(Diag); 00178 00179 return Result.first->second; 00180 } 00181 00182 static const StaticDiagCategoryRec CategoryNameTable[] = { 00183 #define GET_CATEGORY_TABLE 00184 #define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) }, 00185 #include "clang/Basic/DiagnosticGroups.inc" 00186 #undef GET_CATEGORY_TABLE 00187 { 0, 0 } 00188 }; 00189 00190 /// getNumberOfCategories - Return the number of categories 00191 unsigned DiagnosticIDs::getNumberOfCategories() { 00192 return sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1; 00193 } 00194 00195 /// getCategoryNameFromID - Given a category ID, return the name of the 00196 /// category, an empty string if CategoryID is zero, or null if CategoryID is 00197 /// invalid. 00198 StringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) { 00199 if (CategoryID >= getNumberOfCategories()) 00200 return StringRef(); 00201 return CategoryNameTable[CategoryID].getName(); 00202 } 00203 00204 00205 00206 DiagnosticIDs::SFINAEResponse 00207 DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) { 00208 if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) { 00209 if (Info->AccessControl) 00210 return SFINAE_AccessControl; 00211 00212 if (!Info->SFINAE) 00213 return SFINAE_Report; 00214 00215 if (Info->Class == CLASS_ERROR) 00216 return SFINAE_SubstitutionFailure; 00217 00218 // Suppress notes, warnings, and extensions; 00219 return SFINAE_Suppress; 00220 } 00221 00222 return SFINAE_Report; 00223 } 00224 00225 /// getBuiltinDiagClass - Return the class field of the diagnostic. 00226 /// 00227 static unsigned getBuiltinDiagClass(unsigned DiagID) { 00228 if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) 00229 return Info->Class; 00230 return ~0U; 00231 } 00232 00233 //===----------------------------------------------------------------------===// 00234 // Custom Diagnostic information 00235 //===----------------------------------------------------------------------===// 00236 00237 namespace clang { 00238 namespace diag { 00239 class CustomDiagInfo { 00240 typedef std::pair<DiagnosticIDs::Level, std::string> DiagDesc; 00241 std::vector<DiagDesc> DiagInfo; 00242 std::map<DiagDesc, unsigned> DiagIDs; 00243 public: 00244 00245 /// getDescription - Return the description of the specified custom 00246 /// diagnostic. 00247 StringRef getDescription(unsigned DiagID) const { 00248 assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() && 00249 "Invalid diagnosic ID"); 00250 return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second; 00251 } 00252 00253 /// getLevel - Return the level of the specified custom diagnostic. 00254 DiagnosticIDs::Level getLevel(unsigned DiagID) const { 00255 assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() && 00256 "Invalid diagnosic ID"); 00257 return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first; 00258 } 00259 00260 unsigned getOrCreateDiagID(DiagnosticIDs::Level L, StringRef Message, 00261 DiagnosticIDs &Diags) { 00262 DiagDesc D(L, Message); 00263 // Check to see if it already exists. 00264 std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D); 00265 if (I != DiagIDs.end() && I->first == D) 00266 return I->second; 00267 00268 // If not, assign a new ID. 00269 unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT; 00270 DiagIDs.insert(std::make_pair(D, ID)); 00271 DiagInfo.push_back(D); 00272 return ID; 00273 } 00274 }; 00275 00276 } // end diag namespace 00277 } // end clang namespace 00278 00279 00280 //===----------------------------------------------------------------------===// 00281 // Common Diagnostic implementation 00282 //===----------------------------------------------------------------------===// 00283 00284 DiagnosticIDs::DiagnosticIDs() { 00285 CustomDiagInfo = 0; 00286 } 00287 00288 DiagnosticIDs::~DiagnosticIDs() { 00289 delete CustomDiagInfo; 00290 } 00291 00292 /// getCustomDiagID - Return an ID for a diagnostic with the specified message 00293 /// and level. If this is the first request for this diagnosic, it is 00294 /// registered and created, otherwise the existing ID is returned. 00295 unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef Message) { 00296 if (CustomDiagInfo == 0) 00297 CustomDiagInfo = new diag::CustomDiagInfo(); 00298 return CustomDiagInfo->getOrCreateDiagID(L, Message, *this); 00299 } 00300 00301 00302 /// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic 00303 /// level of the specified diagnostic ID is a Warning or Extension. 00304 /// This only works on builtin diagnostics, not custom ones, and is not legal to 00305 /// call on NOTEs. 00306 bool DiagnosticIDs::isBuiltinWarningOrExtension(unsigned DiagID) { 00307 return DiagID < diag::DIAG_UPPER_LIMIT && 00308 getBuiltinDiagClass(DiagID) != CLASS_ERROR; 00309 } 00310 00311 /// \brief Determine whether the given built-in diagnostic ID is a 00312 /// Note. 00313 bool DiagnosticIDs::isBuiltinNote(unsigned DiagID) { 00314 return DiagID < diag::DIAG_UPPER_LIMIT && 00315 getBuiltinDiagClass(DiagID) == CLASS_NOTE; 00316 } 00317 00318 /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic 00319 /// ID is for an extension of some sort. This also returns EnabledByDefault, 00320 /// which is set to indicate whether the diagnostic is ignored by default (in 00321 /// which case -pedantic enables it) or treated as a warning/error by default. 00322 /// 00323 bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID, 00324 bool &EnabledByDefault) { 00325 if (DiagID >= diag::DIAG_UPPER_LIMIT || 00326 getBuiltinDiagClass(DiagID) != CLASS_EXTENSION) 00327 return false; 00328 00329 EnabledByDefault = 00330 GetDefaultDiagMappingInfo(DiagID).getMapping() != diag::MAP_IGNORE; 00331 return true; 00332 } 00333 00334 bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) { 00335 if (DiagID >= diag::DIAG_UPPER_LIMIT) 00336 return false; 00337 00338 return GetDefaultDiagMappingInfo(DiagID).getMapping() == diag::MAP_ERROR; 00339 } 00340 00341 /// getDescription - Given a diagnostic ID, return a description of the 00342 /// issue. 00343 StringRef DiagnosticIDs::getDescription(unsigned DiagID) const { 00344 if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) 00345 return Info->getDescription(); 00346 return CustomDiagInfo->getDescription(DiagID); 00347 } 00348 00349 /// getDiagnosticLevel - Based on the way the client configured the 00350 /// DiagnosticsEngine object, classify the specified diagnostic ID into a Level, 00351 /// by consumable the DiagnosticClient. 00352 DiagnosticIDs::Level 00353 DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, 00354 const DiagnosticsEngine &Diag) const { 00355 // Handle custom diagnostics, which cannot be mapped. 00356 if (DiagID >= diag::DIAG_UPPER_LIMIT) 00357 return CustomDiagInfo->getLevel(DiagID); 00358 00359 unsigned DiagClass = getBuiltinDiagClass(DiagID); 00360 assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!"); 00361 return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag); 00362 } 00363 00364 /// \brief Based on the way the client configured the Diagnostic 00365 /// object, classify the specified diagnostic ID into a Level, consumable by 00366 /// the DiagnosticClient. 00367 /// 00368 /// \param Loc The source location we are interested in finding out the 00369 /// diagnostic state. Can be null in order to query the latest state. 00370 DiagnosticIDs::Level 00371 DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass, 00372 SourceLocation Loc, 00373 const DiagnosticsEngine &Diag) const { 00374 // Specific non-error diagnostics may be mapped to various levels from ignored 00375 // to error. Errors can only be mapped to fatal. 00376 DiagnosticIDs::Level Result = DiagnosticIDs::Fatal; 00377 00378 DiagnosticsEngine::DiagStatePointsTy::iterator 00379 Pos = Diag.GetDiagStatePointForLoc(Loc); 00380 DiagnosticsEngine::DiagState *State = Pos->State; 00381 00382 // Get the mapping information, or compute it lazily. 00383 DiagnosticMappingInfo &MappingInfo = State->getOrAddMappingInfo( 00384 (diag::kind)DiagID); 00385 00386 switch (MappingInfo.getMapping()) { 00387 case diag::MAP_IGNORE: 00388 Result = DiagnosticIDs::Ignored; 00389 break; 00390 case diag::MAP_WARNING: 00391 Result = DiagnosticIDs::Warning; 00392 break; 00393 case diag::MAP_ERROR: 00394 Result = DiagnosticIDs::Error; 00395 break; 00396 case diag::MAP_FATAL: 00397 Result = DiagnosticIDs::Fatal; 00398 break; 00399 } 00400 00401 // Upgrade ignored diagnostics if -Weverything is enabled. 00402 if (Diag.EnableAllWarnings && Result == DiagnosticIDs::Ignored && 00403 !MappingInfo.isUser()) 00404 Result = DiagnosticIDs::Warning; 00405 00406 // Ignore -pedantic diagnostics inside __extension__ blocks. 00407 // (The diagnostics controlled by -pedantic are the extension diagnostics 00408 // that are not enabled by default.) 00409 bool EnabledByDefault = false; 00410 bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault); 00411 if (Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault) 00412 return DiagnosticIDs::Ignored; 00413 00414 // For extension diagnostics that haven't been explicitly mapped, check if we 00415 // should upgrade the diagnostic. 00416 if (IsExtensionDiag && !MappingInfo.isUser()) { 00417 switch (Diag.ExtBehavior) { 00418 case DiagnosticsEngine::Ext_Ignore: 00419 break; 00420 case DiagnosticsEngine::Ext_Warn: 00421 // Upgrade ignored diagnostics to warnings. 00422 if (Result == DiagnosticIDs::Ignored) 00423 Result = DiagnosticIDs::Warning; 00424 break; 00425 case DiagnosticsEngine::Ext_Error: 00426 // Upgrade ignored or warning diagnostics to errors. 00427 if (Result == DiagnosticIDs::Ignored || Result == DiagnosticIDs::Warning) 00428 Result = DiagnosticIDs::Error; 00429 break; 00430 } 00431 } 00432 00433 // At this point, ignored errors can no longer be upgraded. 00434 if (Result == DiagnosticIDs::Ignored) 00435 return Result; 00436 00437 // Honor -w, which is lower in priority than pedantic-errors, but higher than 00438 // -Werror. 00439 if (Result == DiagnosticIDs::Warning && Diag.IgnoreAllWarnings) 00440 return DiagnosticIDs::Ignored; 00441 00442 // If -Werror is enabled, map warnings to errors unless explicitly disabled. 00443 if (Result == DiagnosticIDs::Warning) { 00444 if (Diag.WarningsAsErrors && !MappingInfo.hasNoWarningAsError()) 00445 Result = DiagnosticIDs::Error; 00446 } 00447 00448 // If -Wfatal-errors is enabled, map errors to fatal unless explicity 00449 // disabled. 00450 if (Result == DiagnosticIDs::Error) { 00451 if (Diag.ErrorsAsFatal && !MappingInfo.hasNoErrorAsFatal()) 00452 Result = DiagnosticIDs::Fatal; 00453 } 00454 00455 // If we are in a system header, we ignore it. We look at the diagnostic class 00456 // because we also want to ignore extensions and warnings in -Werror and 00457 // -pedantic-errors modes, which *map* warnings/extensions to errors. 00458 if (Result >= DiagnosticIDs::Warning && 00459 DiagClass != CLASS_ERROR && 00460 // Custom diagnostics always are emitted in system headers. 00461 DiagID < diag::DIAG_UPPER_LIMIT && 00462 !MappingInfo.hasShowInSystemHeader() && 00463 Diag.SuppressSystemWarnings && 00464 Loc.isValid() && 00465 Diag.getSourceManager().isInSystemHeader( 00466 Diag.getSourceManager().getExpansionLoc(Loc))) 00467 return DiagnosticIDs::Ignored; 00468 00469 return Result; 00470 } 00471 00472 struct clang::WarningOption { 00473 // Be safe with the size of 'NameLen' because we don't statically check if 00474 // the size will fit in the field; the struct size won't decrease with a 00475 // shorter type anyway. 00476 size_t NameLen; 00477 const char *NameStr; 00478 const short *Members; 00479 const short *SubGroups; 00480 00481 StringRef getName() const { 00482 return StringRef(NameStr, NameLen); 00483 } 00484 }; 00485 00486 #define GET_DIAG_ARRAYS 00487 #include "clang/Basic/DiagnosticGroups.inc" 00488 #undef GET_DIAG_ARRAYS 00489 00490 // Second the table of options, sorted by name for fast binary lookup. 00491 static const WarningOption OptionTable[] = { 00492 #define GET_DIAG_TABLE 00493 #include "clang/Basic/DiagnosticGroups.inc" 00494 #undef GET_DIAG_TABLE 00495 }; 00496 static const size_t OptionTableSize = 00497 sizeof(OptionTable) / sizeof(OptionTable[0]); 00498 00499 static bool WarningOptionCompare(const WarningOption &LHS, 00500 const WarningOption &RHS) { 00501 return LHS.getName() < RHS.getName(); 00502 } 00503 00504 /// getWarningOptionForDiag - Return the lowest-level warning option that 00505 /// enables the specified diagnostic. If there is no -Wfoo flag that controls 00506 /// the diagnostic, this returns null. 00507 StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) { 00508 if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) 00509 return OptionTable[Info->getOptionGroupIndex()].getName(); 00510 return StringRef(); 00511 } 00512 00513 void DiagnosticIDs::getDiagnosticsInGroup( 00514 const WarningOption *Group, 00515 llvm::SmallVectorImpl<diag::kind> &Diags) const 00516 { 00517 // Add the members of the option diagnostic set. 00518 if (const short *Member = Group->Members) { 00519 for (; *Member != -1; ++Member) 00520 Diags.push_back(*Member); 00521 } 00522 00523 // Add the members of the subgroups. 00524 if (const short *SubGroups = Group->SubGroups) { 00525 for (; *SubGroups != (short)-1; ++SubGroups) 00526 getDiagnosticsInGroup(&OptionTable[(short)*SubGroups], Diags); 00527 } 00528 } 00529 00530 bool DiagnosticIDs::getDiagnosticsInGroup( 00531 StringRef Group, 00532 llvm::SmallVectorImpl<diag::kind> &Diags) const 00533 { 00534 WarningOption Key = { Group.size(), Group.data(), 0, 0 }; 00535 const WarningOption *Found = 00536 std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key, 00537 WarningOptionCompare); 00538 if (Found == OptionTable + OptionTableSize || 00539 Found->getName() != Group) 00540 return true; // Option not found. 00541 00542 getDiagnosticsInGroup(Found, Diags); 00543 return false; 00544 } 00545 00546 void DiagnosticIDs::getAllDiagnostics( 00547 llvm::SmallVectorImpl<diag::kind> &Diags) const { 00548 for (unsigned i = 0; i != StaticDiagInfoSize; ++i) 00549 Diags.push_back(StaticDiagInfo[i].DiagID); 00550 } 00551 00552 StringRef DiagnosticIDs::getNearestWarningOption(StringRef Group) { 00553 StringRef Best; 00554 unsigned BestDistance = Group.size() + 1; // Sanity threshold. 00555 for (const WarningOption *i = OptionTable, *e = OptionTable + OptionTableSize; 00556 i != e; ++i) { 00557 // Don't suggest ignored warning flags. 00558 if (!i->Members && !i->SubGroups) 00559 continue; 00560 00561 unsigned Distance = i->getName().edit_distance(Group, true, BestDistance); 00562 if (Distance == BestDistance) { 00563 // Two matches with the same distance, don't prefer one over the other. 00564 Best = ""; 00565 } else if (Distance < BestDistance) { 00566 // This is a better match. 00567 Best = i->getName(); 00568 BestDistance = Distance; 00569 } 00570 } 00571 00572 return Best; 00573 } 00574 00575 /// ProcessDiag - This is the method used to report a diagnostic that is 00576 /// finally fully formed. 00577 bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const { 00578 Diagnostic Info(&Diag); 00579 00580 if (Diag.SuppressAllDiagnostics) 00581 return false; 00582 00583 assert(Diag.getClient() && "DiagnosticClient not set!"); 00584 00585 // Figure out the diagnostic level of this message. 00586 DiagnosticIDs::Level DiagLevel; 00587 unsigned DiagID = Info.getID(); 00588 00589 if (DiagID >= diag::DIAG_UPPER_LIMIT) { 00590 // Handle custom diagnostics, which cannot be mapped. 00591 DiagLevel = CustomDiagInfo->getLevel(DiagID); 00592 } else { 00593 // Get the class of the diagnostic. If this is a NOTE, map it onto whatever 00594 // the diagnostic level was for the previous diagnostic so that it is 00595 // filtered the same as the previous diagnostic. 00596 unsigned DiagClass = getBuiltinDiagClass(DiagID); 00597 if (DiagClass == CLASS_NOTE) { 00598 DiagLevel = DiagnosticIDs::Note; 00599 } else { 00600 DiagLevel = getDiagnosticLevel(DiagID, DiagClass, Info.getLocation(), 00601 Diag); 00602 } 00603 } 00604 00605 if (DiagLevel != DiagnosticIDs::Note) { 00606 // Record that a fatal error occurred only when we see a second 00607 // non-note diagnostic. This allows notes to be attached to the 00608 // fatal error, but suppresses any diagnostics that follow those 00609 // notes. 00610 if (Diag.LastDiagLevel == DiagnosticIDs::Fatal) 00611 Diag.FatalErrorOccurred = true; 00612 00613 Diag.LastDiagLevel = DiagLevel; 00614 } 00615 00616 // Update counts for DiagnosticErrorTrap even if a fatal error occurred. 00617 if (DiagLevel >= DiagnosticIDs::Error) { 00618 ++Diag.TrapNumErrorsOccurred; 00619 if (isUnrecoverable(DiagID)) 00620 ++Diag.TrapNumUnrecoverableErrorsOccurred; 00621 } 00622 00623 // If a fatal error has already been emitted, silence all subsequent 00624 // diagnostics. 00625 if (Diag.FatalErrorOccurred) { 00626 if (DiagLevel >= DiagnosticIDs::Error && 00627 Diag.Client->IncludeInDiagnosticCounts()) { 00628 ++Diag.NumErrors; 00629 ++Diag.NumErrorsSuppressed; 00630 } 00631 00632 return false; 00633 } 00634 00635 // If the client doesn't care about this message, don't issue it. If this is 00636 // a note and the last real diagnostic was ignored, ignore it too. 00637 if (DiagLevel == DiagnosticIDs::Ignored || 00638 (DiagLevel == DiagnosticIDs::Note && 00639 Diag.LastDiagLevel == DiagnosticIDs::Ignored)) 00640 return false; 00641 00642 if (DiagLevel >= DiagnosticIDs::Error) { 00643 if (isUnrecoverable(DiagID)) 00644 Diag.UnrecoverableErrorOccurred = true; 00645 00646 if (Diag.Client->IncludeInDiagnosticCounts()) { 00647 Diag.ErrorOccurred = true; 00648 ++Diag.NumErrors; 00649 } 00650 00651 // If we've emitted a lot of errors, emit a fatal error instead of it to 00652 // stop a flood of bogus errors. 00653 if (Diag.ErrorLimit && Diag.NumErrors > Diag.ErrorLimit && 00654 DiagLevel == DiagnosticIDs::Error) { 00655 Diag.SetDelayedDiagnostic(diag::fatal_too_many_errors); 00656 return false; 00657 } 00658 } 00659 00660 // Finally, report it. 00661 Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info); 00662 if (Diag.Client->IncludeInDiagnosticCounts()) { 00663 if (DiagLevel == DiagnosticIDs::Warning) 00664 ++Diag.NumWarnings; 00665 } 00666 00667 Diag.CurDiagID = ~0U; 00668 00669 return true; 00670 } 00671 00672 bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const { 00673 if (DiagID >= diag::DIAG_UPPER_LIMIT) { 00674 // Custom diagnostics. 00675 return CustomDiagInfo->getLevel(DiagID) >= DiagnosticIDs::Error; 00676 } 00677 00678 // Only errors may be unrecoverable. 00679 if (getBuiltinDiagClass(DiagID) < CLASS_ERROR) 00680 return false; 00681 00682 if (DiagID == diag::err_unavailable || 00683 DiagID == diag::err_unavailable_message) 00684 return false; 00685 00686 // Currently we consider all ARC errors as recoverable. 00687 if (isARCDiagnostic(DiagID)) 00688 return false; 00689 00690 return true; 00691 } 00692 00693 bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) { 00694 unsigned cat = getCategoryNumberForDiag(DiagID); 00695 return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC "); 00696 } 00697