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