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