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