1 //===- Diagnostic.cpp - C Language Family Diagnostic 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-related interfaces. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/Basic/Diagnostic.h" 14 #include "clang/Basic/CharInfo.h" 15 #include "clang/Basic/DiagnosticDriver.h" 16 #include "clang/Basic/DiagnosticError.h" 17 #include "clang/Basic/DiagnosticFrontend.h" 18 #include "clang/Basic/DiagnosticIDs.h" 19 #include "clang/Basic/DiagnosticOptions.h" 20 #include "clang/Basic/IdentifierTable.h" 21 #include "clang/Basic/SourceLocation.h" 22 #include "clang/Basic/SourceManager.h" 23 #include "clang/Basic/Specifiers.h" 24 #include "clang/Basic/TokenKinds.h" 25 #include "llvm/ADT/IntrusiveRefCntPtr.h" 26 #include "llvm/ADT/SmallVector.h" 27 #include "llvm/ADT/StringExtras.h" 28 #include "llvm/ADT/StringMap.h" 29 #include "llvm/ADT/StringRef.h" 30 #include "llvm/Support/ConvertUTF.h" 31 #include "llvm/Support/CrashRecoveryContext.h" 32 #include "llvm/Support/Error.h" 33 #include "llvm/Support/MemoryBuffer.h" 34 #include "llvm/Support/SpecialCaseList.h" 35 #include "llvm/Support/Unicode.h" 36 #include "llvm/Support/VirtualFileSystem.h" 37 #include "llvm/Support/raw_ostream.h" 38 #include <algorithm> 39 #include <cassert> 40 #include <cstddef> 41 #include <cstdint> 42 #include <cstring> 43 #include <memory> 44 #include <string> 45 #include <utility> 46 #include <vector> 47 48 using namespace clang; 49 50 const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB, 51 DiagNullabilityKind nullability) { 52 DB.AddString( 53 ("'" + 54 getNullabilitySpelling(nullability.first, 55 /*isContextSensitive=*/nullability.second) + 56 "'") 57 .str()); 58 return DB; 59 } 60 61 const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB, 62 llvm::Error &&E) { 63 DB.AddString(toString(std::move(E))); 64 return DB; 65 } 66 67 static void 68 DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, 69 StringRef Modifier, StringRef Argument, 70 ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, 71 SmallVectorImpl<char> &Output, void *Cookie, 72 ArrayRef<intptr_t> QualTypeVals) { 73 StringRef Str = "<can't format argument>"; 74 Output.append(Str.begin(), Str.end()); 75 } 76 77 DiagnosticsEngine::DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> diags, 78 DiagnosticOptions &DiagOpts, 79 DiagnosticConsumer *client, 80 bool ShouldOwnClient) 81 : Diags(std::move(diags)), DiagOpts(DiagOpts) { 82 setClient(client, ShouldOwnClient); 83 ArgToStringFn = DummyArgToStringFn; 84 85 Reset(); 86 } 87 88 DiagnosticsEngine::~DiagnosticsEngine() { 89 // If we own the diagnostic client, destroy it first so that it can access the 90 // engine from its destructor. 91 setClient(nullptr); 92 } 93 94 void DiagnosticsEngine::dump() const { DiagStatesByLoc.dump(*SourceMgr); } 95 96 void DiagnosticsEngine::dump(StringRef DiagName) const { 97 DiagStatesByLoc.dump(*SourceMgr, DiagName); 98 } 99 100 void DiagnosticsEngine::setClient(DiagnosticConsumer *client, 101 bool ShouldOwnClient) { 102 Owner.reset(ShouldOwnClient ? client : nullptr); 103 Client = client; 104 } 105 106 void DiagnosticsEngine::pushMappings(SourceLocation Loc) { 107 DiagStateOnPushStack.push_back(GetCurDiagState()); 108 } 109 110 bool DiagnosticsEngine::popMappings(SourceLocation Loc) { 111 if (DiagStateOnPushStack.empty()) 112 return false; 113 114 if (DiagStateOnPushStack.back() != GetCurDiagState()) { 115 // State changed at some point between push/pop. 116 PushDiagStatePoint(DiagStateOnPushStack.back(), Loc); 117 } 118 DiagStateOnPushStack.pop_back(); 119 return true; 120 } 121 122 void DiagnosticsEngine::ResetPragmas() { DiagStatesByLoc.clear(/*Soft=*/true); } 123 124 void DiagnosticsEngine::Reset(bool soft /*=false*/) { 125 ErrorOccurred = false; 126 UncompilableErrorOccurred = false; 127 FatalErrorOccurred = false; 128 UnrecoverableErrorOccurred = false; 129 130 NumWarnings = 0; 131 NumErrors = 0; 132 TrapNumErrorsOccurred = 0; 133 TrapNumUnrecoverableErrorsOccurred = 0; 134 135 LastDiagLevel = Ignored; 136 137 if (!soft) { 138 // Clear state related to #pragma diagnostic. 139 DiagStates.clear(); 140 DiagStatesByLoc.clear(false); 141 DiagStateOnPushStack.clear(); 142 143 // Create a DiagState and DiagStatePoint representing diagnostic changes 144 // through command-line. 145 DiagStates.emplace_back(*Diags); 146 DiagStatesByLoc.appendFirst(&DiagStates.back()); 147 } 148 } 149 150 DiagnosticMapping & 151 DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) { 152 std::pair<iterator, bool> Result = DiagMap.try_emplace(Diag); 153 154 // Initialize the entry if we added it. 155 if (Result.second) { 156 Result.first->second = DiagIDs.getDefaultMapping(Diag); 157 if (DiagnosticIDs::IsCustomDiag(Diag)) 158 DiagIDs.initCustomDiagMapping(Result.first->second, Diag); 159 } 160 161 return Result.first->second; 162 } 163 164 void DiagnosticsEngine::DiagStateMap::appendFirst(DiagState *State) { 165 assert(Files.empty() && "not first"); 166 FirstDiagState = CurDiagState = State; 167 CurDiagStateLoc = SourceLocation(); 168 } 169 170 void DiagnosticsEngine::DiagStateMap::append(SourceManager &SrcMgr, 171 SourceLocation Loc, 172 DiagState *State) { 173 CurDiagState = State; 174 CurDiagStateLoc = Loc; 175 176 FileIDAndOffset Decomp = SrcMgr.getDecomposedLoc(Loc); 177 unsigned Offset = Decomp.second; 178 for (File *F = getFile(SrcMgr, Decomp.first); F; 179 Offset = F->ParentOffset, F = F->Parent) { 180 F->HasLocalTransitions = true; 181 auto &Last = F->StateTransitions.back(); 182 assert(Last.Offset <= Offset && "state transitions added out of order"); 183 184 if (Last.Offset == Offset) { 185 if (Last.State == State) 186 break; 187 Last.State = State; 188 continue; 189 } 190 191 F->StateTransitions.push_back({State, Offset}); 192 } 193 } 194 195 DiagnosticsEngine::DiagState * 196 DiagnosticsEngine::DiagStateMap::lookup(SourceManager &SrcMgr, 197 SourceLocation Loc) const { 198 // Common case: we have not seen any diagnostic pragmas. 199 if (Files.empty()) 200 return FirstDiagState; 201 202 FileIDAndOffset Decomp = SrcMgr.getDecomposedLoc(Loc); 203 const File *F = getFile(SrcMgr, Decomp.first); 204 return F->lookup(Decomp.second); 205 } 206 207 DiagnosticsEngine::DiagState * 208 DiagnosticsEngine::DiagStateMap::File::lookup(unsigned Offset) const { 209 auto OnePastIt = 210 llvm::partition_point(StateTransitions, [=](const DiagStatePoint &P) { 211 return P.Offset <= Offset; 212 }); 213 assert(OnePastIt != StateTransitions.begin() && "missing initial state"); 214 return OnePastIt[-1].State; 215 } 216 217 DiagnosticsEngine::DiagStateMap::File * 218 DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr, 219 FileID ID) const { 220 // Get or insert the File for this ID. 221 auto Range = Files.equal_range(ID); 222 if (Range.first != Range.second) 223 return &Range.first->second; 224 auto &F = Files.insert(Range.first, std::make_pair(ID, File()))->second; 225 226 // We created a new File; look up the diagnostic state at the start of it and 227 // initialize it. 228 if (ID.isValid()) { 229 FileIDAndOffset Decomp = SrcMgr.getDecomposedIncludedLoc(ID); 230 F.Parent = getFile(SrcMgr, Decomp.first); 231 F.ParentOffset = Decomp.second; 232 F.StateTransitions.push_back({F.Parent->lookup(Decomp.second), 0}); 233 } else { 234 // This is the (imaginary) root file into which we pretend all top-level 235 // files are included; it descends from the initial state. 236 // 237 // FIXME: This doesn't guarantee that we use the same ordering as 238 // isBeforeInTranslationUnit in the cases where someone invented another 239 // top-level file and added diagnostic pragmas to it. See the code at the 240 // end of isBeforeInTranslationUnit for the quirks it deals with. 241 F.StateTransitions.push_back({FirstDiagState, 0}); 242 } 243 return &F; 244 } 245 246 void DiagnosticsEngine::DiagStateMap::dump(SourceManager &SrcMgr, 247 StringRef DiagName) const { 248 llvm::errs() << "diagnostic state at "; 249 CurDiagStateLoc.print(llvm::errs(), SrcMgr); 250 llvm::errs() << ": " << CurDiagState << "\n"; 251 252 for (auto &F : Files) { 253 FileID ID = F.first; 254 File &File = F.second; 255 256 bool PrintedOuterHeading = false; 257 auto PrintOuterHeading = [&] { 258 if (PrintedOuterHeading) 259 return; 260 PrintedOuterHeading = true; 261 262 llvm::errs() << "File " << &File << " <FileID " << ID.getHashValue() 263 << ">: " << SrcMgr.getBufferOrFake(ID).getBufferIdentifier(); 264 265 if (F.second.Parent) { 266 FileIDAndOffset Decomp = SrcMgr.getDecomposedIncludedLoc(ID); 267 assert(File.ParentOffset == Decomp.second); 268 llvm::errs() << " parent " << File.Parent << " <FileID " 269 << Decomp.first.getHashValue() << "> "; 270 SrcMgr.getLocForStartOfFile(Decomp.first) 271 .getLocWithOffset(Decomp.second) 272 .print(llvm::errs(), SrcMgr); 273 } 274 if (File.HasLocalTransitions) 275 llvm::errs() << " has_local_transitions"; 276 llvm::errs() << "\n"; 277 }; 278 279 if (DiagName.empty()) 280 PrintOuterHeading(); 281 282 for (DiagStatePoint &Transition : File.StateTransitions) { 283 bool PrintedInnerHeading = false; 284 auto PrintInnerHeading = [&] { 285 if (PrintedInnerHeading) 286 return; 287 PrintedInnerHeading = true; 288 289 PrintOuterHeading(); 290 llvm::errs() << " "; 291 SrcMgr.getLocForStartOfFile(ID) 292 .getLocWithOffset(Transition.Offset) 293 .print(llvm::errs(), SrcMgr); 294 llvm::errs() << ": state " << Transition.State << ":\n"; 295 }; 296 297 if (DiagName.empty()) 298 PrintInnerHeading(); 299 300 for (auto &Mapping : *Transition.State) { 301 StringRef Option = 302 SrcMgr.getDiagnostics().Diags->getWarningOptionForDiag( 303 Mapping.first); 304 if (!DiagName.empty() && DiagName != Option) 305 continue; 306 307 PrintInnerHeading(); 308 llvm::errs() << " "; 309 if (Option.empty()) 310 llvm::errs() << "<unknown " << Mapping.first << ">"; 311 else 312 llvm::errs() << Option; 313 llvm::errs() << ": "; 314 315 switch (Mapping.second.getSeverity()) { 316 case diag::Severity::Ignored: 317 llvm::errs() << "ignored"; 318 break; 319 case diag::Severity::Remark: 320 llvm::errs() << "remark"; 321 break; 322 case diag::Severity::Warning: 323 llvm::errs() << "warning"; 324 break; 325 case diag::Severity::Error: 326 llvm::errs() << "error"; 327 break; 328 case diag::Severity::Fatal: 329 llvm::errs() << "fatal"; 330 break; 331 } 332 333 if (!Mapping.second.isUser()) 334 llvm::errs() << " default"; 335 if (Mapping.second.isPragma()) 336 llvm::errs() << " pragma"; 337 if (Mapping.second.hasNoWarningAsError()) 338 llvm::errs() << " no-error"; 339 if (Mapping.second.hasNoErrorAsFatal()) 340 llvm::errs() << " no-fatal"; 341 if (Mapping.second.wasUpgradedFromWarning()) 342 llvm::errs() << " overruled"; 343 llvm::errs() << "\n"; 344 } 345 } 346 } 347 } 348 349 void DiagnosticsEngine::PushDiagStatePoint(DiagState *State, 350 SourceLocation Loc) { 351 assert(Loc.isValid() && "Adding invalid loc point"); 352 DiagStatesByLoc.append(*SourceMgr, Loc, State); 353 } 354 355 void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map, 356 SourceLocation L) { 357 assert((Diags->isWarningOrExtension(Diag) || 358 (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) && 359 "Cannot map errors into warnings!"); 360 assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location"); 361 362 // A command line -Wfoo has an invalid L and cannot override error/fatal 363 // mapping, while a warning pragma can. 364 bool WasUpgradedFromWarning = false; 365 if (Map == diag::Severity::Warning && L.isInvalid()) { 366 DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag); 367 if (Info.getSeverity() == diag::Severity::Error || 368 Info.getSeverity() == diag::Severity::Fatal) { 369 Map = Info.getSeverity(); 370 WasUpgradedFromWarning = true; 371 } 372 } 373 DiagnosticMapping Mapping = makeUserMapping(Map, L); 374 Mapping.setUpgradedFromWarning(WasUpgradedFromWarning); 375 376 // Make sure we propagate the NoWarningAsError flag from an existing 377 // mapping (which may be the default mapping). 378 DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag); 379 Mapping.setNoWarningAsError(Info.hasNoWarningAsError() || 380 Mapping.hasNoWarningAsError()); 381 382 // Common case; setting all the diagnostics of a group in one place. 383 if ((L.isInvalid() || L == DiagStatesByLoc.getCurDiagStateLoc()) && 384 DiagStatesByLoc.getCurDiagState()) { 385 // FIXME: This is theoretically wrong: if the current state is shared with 386 // some other location (via push/pop) we will change the state for that 387 // other location as well. This cannot currently happen, as we can't update 388 // the diagnostic state at the same location at which we pop. 389 DiagStatesByLoc.getCurDiagState()->setMapping(Diag, Mapping); 390 return; 391 } 392 393 // A diagnostic pragma occurred, create a new DiagState initialized with 394 // the current one and a new DiagStatePoint to record at which location 395 // the new state became active. 396 DiagStates.push_back(*GetCurDiagState()); 397 DiagStates.back().setMapping(Diag, Mapping); 398 PushDiagStatePoint(&DiagStates.back(), L); 399 } 400 401 bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor, 402 StringRef Group, diag::Severity Map, 403 SourceLocation Loc) { 404 // Get the diagnostics in this group. 405 SmallVector<diag::kind, 256> GroupDiags; 406 if (Diags->getDiagnosticsInGroup(Flavor, Group, GroupDiags)) 407 return true; 408 409 Diags->setGroupSeverity(Group, Map); 410 411 // Set the mapping. 412 for (diag::kind Diag : GroupDiags) 413 setSeverity(Diag, Map, Loc); 414 415 return false; 416 } 417 418 bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor, 419 diag::Group Group, 420 diag::Severity Map, 421 SourceLocation Loc) { 422 return setSeverityForGroup(Flavor, Diags->getWarningOptionForGroup(Group), 423 Map, Loc); 424 } 425 426 bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group, 427 bool Enabled) { 428 // If we are enabling this feature, just set the diagnostic mappings to map to 429 // errors. 430 if (Enabled) 431 return setSeverityForGroup(diag::Flavor::WarningOrError, Group, 432 diag::Severity::Error); 433 Diags->setGroupSeverity(Group, diag::Severity::Warning); 434 435 // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and 436 // potentially downgrade anything already mapped to be a warning. 437 438 // Get the diagnostics in this group. 439 SmallVector<diag::kind, 8> GroupDiags; 440 if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group, 441 GroupDiags)) 442 return true; 443 444 // Perform the mapping change. 445 for (diag::kind Diag : GroupDiags) { 446 DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag); 447 448 if (Info.getSeverity() == diag::Severity::Error || 449 Info.getSeverity() == diag::Severity::Fatal) 450 Info.setSeverity(diag::Severity::Warning); 451 452 Info.setNoWarningAsError(true); 453 } 454 455 return false; 456 } 457 458 bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group, 459 bool Enabled) { 460 // If we are enabling this feature, just set the diagnostic mappings to map to 461 // fatal errors. 462 if (Enabled) 463 return setSeverityForGroup(diag::Flavor::WarningOrError, Group, 464 diag::Severity::Fatal); 465 Diags->setGroupSeverity(Group, diag::Severity::Error); 466 467 // Otherwise, we want to set the diagnostic mapping's "no Wfatal-errors" bit, 468 // and potentially downgrade anything already mapped to be a fatal error. 469 470 // Get the diagnostics in this group. 471 SmallVector<diag::kind, 8> GroupDiags; 472 if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group, 473 GroupDiags)) 474 return true; 475 476 // Perform the mapping change. 477 for (diag::kind Diag : GroupDiags) { 478 DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag); 479 480 if (Info.getSeverity() == diag::Severity::Fatal) 481 Info.setSeverity(diag::Severity::Error); 482 483 Info.setNoErrorAsFatal(true); 484 } 485 486 return false; 487 } 488 489 void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor, 490 diag::Severity Map, 491 SourceLocation Loc) { 492 // Get all the diagnostics. 493 std::vector<diag::kind> AllDiags; 494 DiagnosticIDs::getAllDiagnostics(Flavor, AllDiags); 495 496 // Set the mapping. 497 for (diag::kind Diag : AllDiags) 498 if (Diags->isWarningOrExtension(Diag)) 499 setSeverity(Diag, Map, Loc); 500 } 501 502 namespace { 503 // FIXME: We should isolate the parser from SpecialCaseList and just use it 504 // here. 505 class WarningsSpecialCaseList : public llvm::SpecialCaseList { 506 public: 507 static std::unique_ptr<WarningsSpecialCaseList> 508 create(const llvm::MemoryBuffer &Input, std::string &Err); 509 510 // Section names refer to diagnostic groups, which cover multiple individual 511 // diagnostics. Expand diagnostic groups here to individual diagnostics. 512 // A diagnostic can have multiple diagnostic groups associated with it, we let 513 // the last section take precedence in such cases. 514 void processSections(DiagnosticsEngine &Diags); 515 516 bool isDiagSuppressed(diag::kind DiagId, SourceLocation DiagLoc, 517 const SourceManager &SM) const; 518 519 private: 520 // Find the longest glob pattern that matches FilePath amongst 521 // CategoriesToMatchers, return true iff the match exists and belongs to a 522 // positive category. 523 bool globsMatches(const llvm::StringMap<Matcher> &CategoriesToMatchers, 524 StringRef FilePath) const; 525 526 llvm::DenseMap<diag::kind, const Section *> DiagToSection; 527 }; 528 } // namespace 529 530 std::unique_ptr<WarningsSpecialCaseList> 531 WarningsSpecialCaseList::create(const llvm::MemoryBuffer &Input, 532 std::string &Err) { 533 auto WarningSuppressionList = std::make_unique<WarningsSpecialCaseList>(); 534 if (!WarningSuppressionList->createInternal(&Input, Err)) 535 return nullptr; 536 return WarningSuppressionList; 537 } 538 539 void WarningsSpecialCaseList::processSections(DiagnosticsEngine &Diags) { 540 // Drop the default section introduced by special case list, we only support 541 // exact diagnostic group names. 542 // FIXME: We should make this configurable in the parser instead. 543 // FIXME: C++20 can use std::erase_if(Sections, [](Section &sec) { return 544 // sec.SectionStr == "*"; }); 545 llvm::erase_if(Sections, [](Section &sec) { return sec.SectionStr == "*"; }); 546 // Make sure we iterate sections by their line numbers. 547 std::vector<std::pair<unsigned, const Section *>> LineAndSectionEntry; 548 LineAndSectionEntry.reserve(Sections.size()); 549 for (const auto &Entry : Sections) { 550 StringRef DiagName = Entry.SectionStr; 551 // Each section has a matcher with that section's name, attached to that 552 // line. 553 const auto &DiagSectionMatcher = Entry.SectionMatcher; 554 unsigned DiagLine = 0; 555 for (const auto &Glob : DiagSectionMatcher->Globs) 556 if (Glob->Name == DiagName) { 557 DiagLine = Glob->LineNo; 558 break; 559 } 560 LineAndSectionEntry.emplace_back(DiagLine, &Entry); 561 } 562 llvm::sort(LineAndSectionEntry); 563 static constexpr auto WarningFlavor = clang::diag::Flavor::WarningOrError; 564 for (const auto &[_, SectionEntry] : LineAndSectionEntry) { 565 SmallVector<diag::kind> GroupDiags; 566 StringRef DiagGroup = SectionEntry->SectionStr; 567 if (Diags.getDiagnosticIDs()->getDiagnosticsInGroup( 568 WarningFlavor, DiagGroup, GroupDiags)) { 569 StringRef Suggestion = 570 DiagnosticIDs::getNearestOption(WarningFlavor, DiagGroup); 571 Diags.Report(diag::warn_unknown_diag_option) 572 << static_cast<unsigned>(WarningFlavor) << DiagGroup 573 << !Suggestion.empty() << Suggestion; 574 continue; 575 } 576 for (diag::kind Diag : GroupDiags) 577 // We're intentionally overwriting any previous mappings here to make sure 578 // latest one takes precedence. 579 DiagToSection[Diag] = SectionEntry; 580 } 581 } 582 583 void DiagnosticsEngine::setDiagSuppressionMapping(llvm::MemoryBuffer &Input) { 584 std::string Error; 585 auto WarningSuppressionList = WarningsSpecialCaseList::create(Input, Error); 586 if (!WarningSuppressionList) { 587 // FIXME: Use a `%select` statement instead of printing `Error` as-is. This 588 // should help localization. 589 Report(diag::err_drv_malformed_warning_suppression_mapping) 590 << Input.getBufferIdentifier() << Error; 591 return; 592 } 593 WarningSuppressionList->processSections(*this); 594 DiagSuppressionMapping = 595 [WarningSuppressionList(std::move(WarningSuppressionList))]( 596 diag::kind DiagId, SourceLocation DiagLoc, const SourceManager &SM) { 597 return WarningSuppressionList->isDiagSuppressed(DiagId, DiagLoc, SM); 598 }; 599 } 600 601 bool WarningsSpecialCaseList::isDiagSuppressed(diag::kind DiagId, 602 SourceLocation DiagLoc, 603 const SourceManager &SM) const { 604 const Section *DiagSection = DiagToSection.lookup(DiagId); 605 if (!DiagSection) 606 return false; 607 const SectionEntries &EntityTypeToCategories = DiagSection->Entries; 608 auto SrcEntriesIt = EntityTypeToCategories.find("src"); 609 if (SrcEntriesIt == EntityTypeToCategories.end()) 610 return false; 611 const llvm::StringMap<llvm::SpecialCaseList::Matcher> &CategoriesToMatchers = 612 SrcEntriesIt->getValue(); 613 // We also use presumed locations here to improve reproducibility for 614 // preprocessed inputs. 615 if (PresumedLoc PLoc = SM.getPresumedLoc(DiagLoc); PLoc.isValid()) 616 return globsMatches( 617 CategoriesToMatchers, 618 llvm::sys::path::remove_leading_dotslash(PLoc.getFilename())); 619 return false; 620 } 621 622 bool WarningsSpecialCaseList::globsMatches( 623 const llvm::StringMap<Matcher> &CategoriesToMatchers, 624 StringRef FilePath) const { 625 StringRef LongestMatch; 626 bool LongestIsPositive = false; 627 for (const auto &Entry : CategoriesToMatchers) { 628 StringRef Category = Entry.getKey(); 629 const llvm::SpecialCaseList::Matcher &Matcher = Entry.getValue(); 630 bool IsPositive = Category != "emit"; 631 for (const auto &Glob : Matcher.Globs) { 632 if (Glob->Name.size() < LongestMatch.size()) 633 continue; 634 if (!Glob->Pattern.match(FilePath)) 635 continue; 636 LongestMatch = Glob->Name; 637 LongestIsPositive = IsPositive; 638 } 639 } 640 return LongestIsPositive; 641 } 642 643 bool DiagnosticsEngine::isSuppressedViaMapping(diag::kind DiagId, 644 SourceLocation DiagLoc) const { 645 if (!hasSourceManager() || !DiagSuppressionMapping) 646 return false; 647 return DiagSuppressionMapping(DiagId, DiagLoc, getSourceManager()); 648 } 649 650 void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { 651 DiagnosticStorage DiagStorage; 652 DiagStorage.DiagRanges.append(storedDiag.range_begin(), 653 storedDiag.range_end()); 654 655 DiagStorage.FixItHints.append(storedDiag.fixit_begin(), 656 storedDiag.fixit_end()); 657 658 assert(Client && "DiagnosticConsumer not set!"); 659 Level DiagLevel = storedDiag.getLevel(); 660 Diagnostic Info(this, storedDiag.getLocation(), storedDiag.getID(), 661 DiagStorage, storedDiag.getMessage()); 662 Report(DiagLevel, Info); 663 } 664 665 void DiagnosticsEngine::Report(Level DiagLevel, const Diagnostic &Info) { 666 assert(DiagLevel != Ignored && "Cannot emit ignored diagnostics!"); 667 Client->HandleDiagnostic(DiagLevel, Info); 668 if (Client->IncludeInDiagnosticCounts()) { 669 if (DiagLevel == Warning) 670 ++NumWarnings; 671 } 672 } 673 674 /// ProcessDiag - This is the method used to report a diagnostic that is 675 /// finally fully formed. 676 bool DiagnosticsEngine::ProcessDiag(const DiagnosticBuilder &DiagBuilder) { 677 Diagnostic Info(this, DiagBuilder); 678 679 assert(getClient() && "DiagnosticClient not set!"); 680 681 // Figure out the diagnostic level of this message. 682 unsigned DiagID = Info.getID(); 683 Level DiagLevel = getDiagnosticLevel(DiagID, Info.getLocation()); 684 685 // Update counts for DiagnosticErrorTrap even if a fatal error occurred 686 // or diagnostics are suppressed. 687 if (DiagLevel >= Error) { 688 ++TrapNumErrorsOccurred; 689 if (Diags->isUnrecoverable(DiagID)) 690 ++TrapNumUnrecoverableErrorsOccurred; 691 } 692 693 if (SuppressAllDiagnostics) 694 return false; 695 696 if (DiagLevel != Note) { 697 // Record that a fatal error occurred only when we see a second 698 // non-note diagnostic. This allows notes to be attached to the 699 // fatal error, but suppresses any diagnostics that follow those 700 // notes. 701 if (LastDiagLevel == Fatal) 702 FatalErrorOccurred = true; 703 704 LastDiagLevel = DiagLevel; 705 } 706 707 // If a fatal error has already been emitted, silence all subsequent 708 // diagnostics. 709 if (FatalErrorOccurred) { 710 if (DiagLevel >= Error && Client->IncludeInDiagnosticCounts()) 711 ++NumErrors; 712 713 return false; 714 } 715 716 // If the client doesn't care about this message, don't issue it. If this is 717 // a note and the last real diagnostic was ignored, ignore it too. 718 if (DiagLevel == Ignored || (DiagLevel == Note && LastDiagLevel == Ignored)) 719 return false; 720 721 if (DiagLevel >= Error) { 722 if (Diags->isUnrecoverable(DiagID)) 723 UnrecoverableErrorOccurred = true; 724 725 // Warnings which have been upgraded to errors do not prevent compilation. 726 if (Diags->isDefaultMappingAsError(DiagID)) 727 UncompilableErrorOccurred = true; 728 729 ErrorOccurred = true; 730 if (Client->IncludeInDiagnosticCounts()) 731 ++NumErrors; 732 733 // If we've emitted a lot of errors, emit a fatal error instead of it to 734 // stop a flood of bogus errors. 735 if (ErrorLimit && NumErrors > ErrorLimit && DiagLevel == Error) { 736 Report(diag::fatal_too_many_errors); 737 return false; 738 } 739 } 740 741 // Make sure we set FatalErrorOccurred to ensure that the notes from the 742 // diagnostic that caused `fatal_too_many_errors` won't be emitted. 743 if (Info.getID() == diag::fatal_too_many_errors) 744 FatalErrorOccurred = true; 745 746 // Finally, report it. 747 Report(DiagLevel, Info); 748 return true; 749 } 750 751 bool DiagnosticsEngine::EmitDiagnostic(const DiagnosticBuilder &DB, 752 bool Force) { 753 assert(getClient() && "DiagnosticClient not set!"); 754 755 bool Emitted; 756 if (Force) { 757 Diagnostic Info(this, DB); 758 759 // Figure out the diagnostic level of this message. 760 Level DiagLevel = getDiagnosticLevel(Info.getID(), Info.getLocation()); 761 762 // Emit the diagnostic regardless of suppression level. 763 Emitted = DiagLevel != Ignored; 764 if (Emitted) 765 Report(DiagLevel, Info); 766 } else { 767 // Process the diagnostic, sending the accumulated information to the 768 // DiagnosticConsumer. 769 Emitted = ProcessDiag(DB); 770 } 771 772 return Emitted; 773 } 774 775 DiagnosticBuilder::DiagnosticBuilder(DiagnosticsEngine *DiagObj, 776 SourceLocation DiagLoc, unsigned DiagID) 777 : StreamingDiagnostic(DiagObj->DiagAllocator), DiagObj(DiagObj), 778 DiagLoc(DiagLoc), DiagID(DiagID), IsActive(true) { 779 assert(DiagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!"); 780 } 781 782 DiagnosticBuilder::DiagnosticBuilder(const DiagnosticBuilder &D) 783 : StreamingDiagnostic() { 784 DiagLoc = D.DiagLoc; 785 DiagID = D.DiagID; 786 FlagValue = D.FlagValue; 787 DiagObj = D.DiagObj; 788 DiagStorage = D.DiagStorage; 789 D.DiagStorage = nullptr; 790 Allocator = D.Allocator; 791 IsActive = D.IsActive; 792 IsForceEmit = D.IsForceEmit; 793 D.Clear(); 794 } 795 796 Diagnostic::Diagnostic(const DiagnosticsEngine *DO, 797 const DiagnosticBuilder &DiagBuilder) 798 : DiagObj(DO), DiagLoc(DiagBuilder.DiagLoc), DiagID(DiagBuilder.DiagID), 799 FlagValue(DiagBuilder.FlagValue), DiagStorage(*DiagBuilder.getStorage()) { 800 } 801 802 Diagnostic::Diagnostic(const DiagnosticsEngine *DO, SourceLocation DiagLoc, 803 unsigned DiagID, const DiagnosticStorage &DiagStorage, 804 StringRef StoredDiagMessage) 805 : DiagObj(DO), DiagLoc(DiagLoc), DiagID(DiagID), DiagStorage(DiagStorage), 806 StoredDiagMessage(StoredDiagMessage) {} 807 808 DiagnosticConsumer::~DiagnosticConsumer() = default; 809 810 void DiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 811 const Diagnostic &Info) { 812 if (!IncludeInDiagnosticCounts()) 813 return; 814 815 if (DiagLevel == DiagnosticsEngine::Warning) 816 ++NumWarnings; 817 else if (DiagLevel >= DiagnosticsEngine::Error) 818 ++NumErrors; 819 } 820 821 /// ModifierIs - Return true if the specified modifier matches specified string. 822 template <std::size_t StrLen> 823 static bool ModifierIs(const char *Modifier, unsigned ModifierLen, 824 const char (&Str)[StrLen]) { 825 return StrLen - 1 == ModifierLen && memcmp(Modifier, Str, StrLen - 1) == 0; 826 } 827 828 /// ScanForward - Scans forward, looking for the given character, skipping 829 /// nested clauses and escaped characters. 830 static const char *ScanFormat(const char *I, const char *E, char Target) { 831 unsigned Depth = 0; 832 833 for (; I != E; ++I) { 834 if (Depth == 0 && *I == Target) 835 return I; 836 if (Depth != 0 && *I == '}') 837 Depth--; 838 839 if (*I == '%') { 840 I++; 841 if (I == E) 842 break; 843 844 // Escaped characters get implicitly skipped here. 845 846 // Format specifier. 847 if (!isDigit(*I) && !isPunctuation(*I)) { 848 for (I++; I != E && !isDigit(*I) && *I != '{'; I++) 849 ; 850 if (I == E) 851 break; 852 if (*I == '{') 853 Depth++; 854 } 855 } 856 } 857 return E; 858 } 859 860 /// HandleSelectModifier - Handle the integer 'select' modifier. This is used 861 /// like this: %select{foo|bar|baz}2. This means that the integer argument 862 /// "%2" has a value from 0-2. If the value is 0, the diagnostic prints 'foo'. 863 /// If the value is 1, it prints 'bar'. If it has the value 2, it prints 'baz'. 864 /// This is very useful for certain classes of variant diagnostics. 865 static void HandleSelectModifier(const Diagnostic &DInfo, unsigned ValNo, 866 const char *Argument, unsigned ArgumentLen, 867 SmallVectorImpl<char> &OutStr) { 868 const char *ArgumentEnd = Argument + ArgumentLen; 869 870 // Skip over 'ValNo' |'s. 871 while (ValNo) { 872 const char *NextVal = ScanFormat(Argument, ArgumentEnd, '|'); 873 assert(NextVal != ArgumentEnd && 874 "Value for integer select modifier was" 875 " larger than the number of options in the diagnostic string!"); 876 Argument = NextVal + 1; // Skip this string. 877 --ValNo; 878 } 879 880 // Get the end of the value. This is either the } or the |. 881 const char *EndPtr = ScanFormat(Argument, ArgumentEnd, '|'); 882 883 // Recursively format the result of the select clause into the output string. 884 DInfo.FormatDiagnostic(Argument, EndPtr, OutStr); 885 } 886 887 /// HandleIntegerSModifier - Handle the integer 's' modifier. This adds the 888 /// letter 's' to the string if the value is not 1. This is used in cases like 889 /// this: "you idiot, you have %4 parameter%s4!". 890 static void HandleIntegerSModifier(unsigned ValNo, 891 SmallVectorImpl<char> &OutStr) { 892 if (ValNo != 1) 893 OutStr.push_back('s'); 894 } 895 896 /// HandleOrdinalModifier - Handle the integer 'ord' modifier. This 897 /// prints the ordinal form of the given integer, with 1 corresponding 898 /// to the first ordinal. Currently this is hard-coded to use the 899 /// English form. 900 static void HandleOrdinalModifier(unsigned ValNo, 901 SmallVectorImpl<char> &OutStr) { 902 assert(ValNo != 0 && "ValNo must be strictly positive!"); 903 904 llvm::raw_svector_ostream Out(OutStr); 905 906 // We could use text forms for the first N ordinals, but the numeric 907 // forms are actually nicer in diagnostics because they stand out. 908 Out << ValNo << llvm::getOrdinalSuffix(ValNo); 909 } 910 911 // 123 -> "123". 912 // 1234 -> "1.23k". 913 // 123456 -> "123.46k". 914 // 1234567 -> "1.23M". 915 // 1234567890 -> "1.23G". 916 // 1234567890123 -> "1.23T". 917 static void HandleIntegerHumanModifier(int64_t ValNo, 918 SmallVectorImpl<char> &OutStr) { 919 static constexpr std::array<std::pair<int64_t, char>, 4> Units = { 920 {{1'000'000'000'000L, 'T'}, 921 {1'000'000'000L, 'G'}, 922 {1'000'000L, 'M'}, 923 {1'000L, 'k'}}}; 924 925 llvm::raw_svector_ostream Out(OutStr); 926 if (ValNo < 0) { 927 Out << "-"; 928 ValNo = -ValNo; 929 } 930 for (const auto &[UnitSize, UnitSign] : Units) { 931 if (ValNo >= UnitSize) { 932 Out << llvm::format("%0.2f%c", ValNo / static_cast<double>(UnitSize), 933 UnitSign); 934 return; 935 } 936 } 937 Out << ValNo; 938 } 939 940 /// PluralNumber - Parse an unsigned integer and advance Start. 941 static unsigned PluralNumber(const char *&Start, const char *End) { 942 // Programming 101: Parse a decimal number :-) 943 unsigned Val = 0; 944 while (Start != End && *Start >= '0' && *Start <= '9') { 945 Val *= 10; 946 Val += *Start - '0'; 947 ++Start; 948 } 949 return Val; 950 } 951 952 /// TestPluralRange - Test if Val is in the parsed range. Modifies Start. 953 static bool TestPluralRange(unsigned Val, const char *&Start, const char *End) { 954 if (*Start != '[') { 955 unsigned Ref = PluralNumber(Start, End); 956 return Ref == Val; 957 } 958 959 ++Start; 960 unsigned Low = PluralNumber(Start, End); 961 assert(*Start == ',' && "Bad plural expression syntax: expected ,"); 962 ++Start; 963 unsigned High = PluralNumber(Start, End); 964 assert(*Start == ']' && "Bad plural expression syntax: expected )"); 965 ++Start; 966 return Low <= Val && Val <= High; 967 } 968 969 /// EvalPluralExpr - Actual expression evaluator for HandlePluralModifier. 970 static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) { 971 // Empty condition? 972 if (*Start == ':') 973 return true; 974 975 while (true) { 976 char C = *Start; 977 if (C == '%') { 978 // Modulo expression 979 ++Start; 980 unsigned Arg = PluralNumber(Start, End); 981 assert(*Start == '=' && "Bad plural expression syntax: expected ="); 982 ++Start; 983 unsigned ValMod = ValNo % Arg; 984 if (TestPluralRange(ValMod, Start, End)) 985 return true; 986 } else { 987 assert((C == '[' || (C >= '0' && C <= '9')) && 988 "Bad plural expression syntax: unexpected character"); 989 // Range expression 990 if (TestPluralRange(ValNo, Start, End)) 991 return true; 992 } 993 994 // Scan for next or-expr part. 995 Start = std::find(Start, End, ','); 996 if (Start == End) 997 break; 998 ++Start; 999 } 1000 return false; 1001 } 1002 1003 /// HandlePluralModifier - Handle the integer 'plural' modifier. This is used 1004 /// for complex plural forms, or in languages where all plurals are complex. 1005 /// The syntax is: %plural{cond1:form1|cond2:form2|:form3}, where condn are 1006 /// conditions that are tested in order, the form corresponding to the first 1007 /// that applies being emitted. The empty condition is always true, making the 1008 /// last form a default case. 1009 /// Conditions are simple boolean expressions, where n is the number argument. 1010 /// Here are the rules. 1011 /// condition := expression | empty 1012 /// empty := -> always true 1013 /// expression := numeric [',' expression] -> logical or 1014 /// numeric := range -> true if n in range 1015 /// | '%' number '=' range -> true if n % number in range 1016 /// range := number 1017 /// | '[' number ',' number ']' -> ranges are inclusive both ends 1018 /// 1019 /// Here are some examples from the GNU gettext manual written in this form: 1020 /// English: 1021 /// {1:form0|:form1} 1022 /// Latvian: 1023 /// {0:form2|%100=11,%10=0,%10=[2,9]:form1|:form0} 1024 /// Gaeilge: 1025 /// {1:form0|2:form1|:form2} 1026 /// Romanian: 1027 /// {1:form0|0,%100=[1,19]:form1|:form2} 1028 /// Lithuanian: 1029 /// {%10=0,%100=[10,19]:form2|%10=1:form0|:form1} 1030 /// Russian (requires repeated form): 1031 /// {%100=[11,14]:form2|%10=1:form0|%10=[2,4]:form1|:form2} 1032 /// Slovak 1033 /// {1:form0|[2,4]:form1|:form2} 1034 /// Polish (requires repeated form): 1035 /// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2} 1036 static void HandlePluralModifier(const Diagnostic &DInfo, unsigned ValNo, 1037 const char *Argument, unsigned ArgumentLen, 1038 SmallVectorImpl<char> &OutStr) { 1039 const char *ArgumentEnd = Argument + ArgumentLen; 1040 while (true) { 1041 assert(Argument < ArgumentEnd && "Plural expression didn't match."); 1042 const char *ExprEnd = Argument; 1043 while (*ExprEnd != ':') { 1044 assert(ExprEnd != ArgumentEnd && "Plural missing expression end"); 1045 ++ExprEnd; 1046 } 1047 if (EvalPluralExpr(ValNo, Argument, ExprEnd)) { 1048 Argument = ExprEnd + 1; 1049 ExprEnd = ScanFormat(Argument, ArgumentEnd, '|'); 1050 1051 // Recursively format the result of the plural clause into the 1052 // output string. 1053 DInfo.FormatDiagnostic(Argument, ExprEnd, OutStr); 1054 return; 1055 } 1056 Argument = ScanFormat(Argument, ArgumentEnd - 1, '|') + 1; 1057 } 1058 } 1059 1060 /// Returns the friendly description for a token kind that will appear 1061 /// without quotes in diagnostic messages. These strings may be translatable in 1062 /// future. 1063 static const char *getTokenDescForDiagnostic(tok::TokenKind Kind) { 1064 switch (Kind) { 1065 case tok::identifier: 1066 return "identifier"; 1067 default: 1068 return nullptr; 1069 } 1070 } 1071 1072 /// FormatDiagnostic - Format this diagnostic into a string, substituting the 1073 /// formal arguments into the %0 slots. The result is appended onto the Str 1074 /// array. 1075 void Diagnostic::FormatDiagnostic(SmallVectorImpl<char> &OutStr) const { 1076 if (StoredDiagMessage.has_value()) { 1077 OutStr.append(StoredDiagMessage->begin(), StoredDiagMessage->end()); 1078 return; 1079 } 1080 1081 StringRef Diag = getDiags()->getDiagnosticIDs()->getDescription(getID()); 1082 1083 FormatDiagnostic(Diag.begin(), Diag.end(), OutStr); 1084 } 1085 1086 /// EscapeStringForDiagnostic - Append Str to the diagnostic buffer, 1087 /// escaping non-printable characters and ill-formed code unit sequences. 1088 void clang::EscapeStringForDiagnostic(StringRef Str, 1089 SmallVectorImpl<char> &OutStr) { 1090 OutStr.reserve(OutStr.size() + Str.size()); 1091 auto *Begin = reinterpret_cast<const unsigned char *>(Str.data()); 1092 llvm::raw_svector_ostream OutStream(OutStr); 1093 const unsigned char *End = Begin + Str.size(); 1094 while (Begin != End) { 1095 // ASCII case 1096 if (isPrintable(*Begin) || isWhitespace(*Begin)) { 1097 OutStream << *Begin; 1098 ++Begin; 1099 continue; 1100 } 1101 if (llvm::isLegalUTF8Sequence(Begin, End)) { 1102 llvm::UTF32 CodepointValue; 1103 llvm::UTF32 *CpPtr = &CodepointValue; 1104 const unsigned char *CodepointBegin = Begin; 1105 const unsigned char *CodepointEnd = 1106 Begin + llvm::getNumBytesForUTF8(*Begin); 1107 llvm::ConversionResult Res = llvm::ConvertUTF8toUTF32( 1108 &Begin, CodepointEnd, &CpPtr, CpPtr + 1, llvm::strictConversion); 1109 (void)Res; 1110 assert( 1111 llvm::conversionOK == Res && 1112 "the sequence is legal UTF-8 but we couldn't convert it to UTF-32"); 1113 assert(Begin == CodepointEnd && 1114 "we must be further along in the string now"); 1115 if (llvm::sys::unicode::isPrintable(CodepointValue) || 1116 llvm::sys::unicode::isFormatting(CodepointValue)) { 1117 OutStr.append(CodepointBegin, CodepointEnd); 1118 continue; 1119 } 1120 // Unprintable code point. 1121 OutStream << "<U+" << llvm::format_hex_no_prefix(CodepointValue, 4, true) 1122 << ">"; 1123 continue; 1124 } 1125 // Invalid code unit. 1126 OutStream << "<" << llvm::format_hex_no_prefix(*Begin, 2, true) << ">"; 1127 ++Begin; 1128 } 1129 } 1130 1131 void Diagnostic::FormatDiagnostic(const char *DiagStr, const char *DiagEnd, 1132 SmallVectorImpl<char> &OutStr) const { 1133 // When the diagnostic string is only "%0", the entire string is being given 1134 // by an outside source. Remove unprintable characters from this string 1135 // and skip all the other string processing. 1136 if (DiagEnd - DiagStr == 2 && StringRef(DiagStr, DiagEnd - DiagStr) == "%0" && 1137 getArgKind(0) == DiagnosticsEngine::ak_std_string) { 1138 const std::string &S = getArgStdStr(0); 1139 EscapeStringForDiagnostic(S, OutStr); 1140 return; 1141 } 1142 1143 /// FormattedArgs - Keep track of all of the arguments formatted by 1144 /// ConvertArgToString and pass them into subsequent calls to 1145 /// ConvertArgToString, allowing the implementation to avoid redundancies in 1146 /// obvious cases. 1147 SmallVector<DiagnosticsEngine::ArgumentValue, 8> FormattedArgs; 1148 1149 /// QualTypeVals - Pass a vector of arrays so that QualType names can be 1150 /// compared to see if more information is needed to be printed. 1151 SmallVector<intptr_t, 2> QualTypeVals; 1152 SmallString<64> Tree; 1153 1154 for (unsigned i = 0, e = getNumArgs(); i < e; ++i) 1155 if (getArgKind(i) == DiagnosticsEngine::ak_qualtype) 1156 QualTypeVals.push_back(getRawArg(i)); 1157 1158 while (DiagStr != DiagEnd) { 1159 if (DiagStr[0] != '%') { 1160 // Append non-%0 substrings to Str if we have one. 1161 const char *StrEnd = std::find(DiagStr, DiagEnd, '%'); 1162 OutStr.append(DiagStr, StrEnd); 1163 DiagStr = StrEnd; 1164 continue; 1165 } else if (isPunctuation(DiagStr[1])) { 1166 OutStr.push_back(DiagStr[1]); // %% -> %. 1167 DiagStr += 2; 1168 continue; 1169 } 1170 1171 // Skip the %. 1172 ++DiagStr; 1173 1174 // This must be a placeholder for a diagnostic argument. The format for a 1175 // placeholder is one of "%0", "%modifier0", or "%modifier{arguments}0". 1176 // The digit is a number from 0-9 indicating which argument this comes from. 1177 // The modifier is a string of digits from the set [-a-z]+, arguments is a 1178 // brace enclosed string. 1179 const char *Modifier = nullptr, *Argument = nullptr; 1180 unsigned ModifierLen = 0, ArgumentLen = 0; 1181 1182 // Check to see if we have a modifier. If so eat it. 1183 if (!isDigit(DiagStr[0])) { 1184 Modifier = DiagStr; 1185 while (DiagStr[0] == '-' || (DiagStr[0] >= 'a' && DiagStr[0] <= 'z')) 1186 ++DiagStr; 1187 ModifierLen = DiagStr - Modifier; 1188 1189 // If we have an argument, get it next. 1190 if (DiagStr[0] == '{') { 1191 ++DiagStr; // Skip {. 1192 Argument = DiagStr; 1193 1194 DiagStr = ScanFormat(DiagStr, DiagEnd, '}'); 1195 assert(DiagStr != DiagEnd && "Mismatched {}'s in diagnostic string!"); 1196 ArgumentLen = DiagStr - Argument; 1197 ++DiagStr; // Skip }. 1198 } 1199 } 1200 1201 assert(isDigit(*DiagStr) && "Invalid format for argument in diagnostic"); 1202 unsigned ArgNo = *DiagStr++ - '0'; 1203 1204 // Only used for type diffing. 1205 unsigned ArgNo2 = ArgNo; 1206 1207 DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo); 1208 if (ModifierIs(Modifier, ModifierLen, "diff")) { 1209 assert(*DiagStr == ',' && isDigit(*(DiagStr + 1)) && 1210 "Invalid format for diff modifier"); 1211 ++DiagStr; // Comma. 1212 ArgNo2 = *DiagStr++ - '0'; 1213 DiagnosticsEngine::ArgumentKind Kind2 = getArgKind(ArgNo2); 1214 if (Kind == DiagnosticsEngine::ak_qualtype && 1215 Kind2 == DiagnosticsEngine::ak_qualtype) 1216 Kind = DiagnosticsEngine::ak_qualtype_pair; 1217 else { 1218 // %diff only supports QualTypes. For other kinds of arguments, 1219 // use the default printing. For example, if the modifier is: 1220 // "%diff{compare $ to $|other text}1,2" 1221 // treat it as: 1222 // "compare %1 to %2" 1223 const char *ArgumentEnd = Argument + ArgumentLen; 1224 const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|'); 1225 assert(ScanFormat(Pipe + 1, ArgumentEnd, '|') == ArgumentEnd && 1226 "Found too many '|'s in a %diff modifier!"); 1227 const char *FirstDollar = ScanFormat(Argument, Pipe, '$'); 1228 const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$'); 1229 const char ArgStr1[] = {'%', static_cast<char>('0' + ArgNo)}; 1230 const char ArgStr2[] = {'%', static_cast<char>('0' + ArgNo2)}; 1231 FormatDiagnostic(Argument, FirstDollar, OutStr); 1232 FormatDiagnostic(ArgStr1, ArgStr1 + 2, OutStr); 1233 FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr); 1234 FormatDiagnostic(ArgStr2, ArgStr2 + 2, OutStr); 1235 FormatDiagnostic(SecondDollar + 1, Pipe, OutStr); 1236 continue; 1237 } 1238 } 1239 1240 switch (Kind) { 1241 // ---- STRINGS ---- 1242 case DiagnosticsEngine::ak_std_string: 1243 case DiagnosticsEngine::ak_c_string: { 1244 StringRef S = [&]() -> StringRef { 1245 if (Kind == DiagnosticsEngine::ak_std_string) 1246 return getArgStdStr(ArgNo); 1247 const char *SZ = getArgCStr(ArgNo); 1248 // Don't crash if get passed a null pointer by accident. 1249 return SZ ? SZ : "(null)"; 1250 }(); 1251 bool Quoted = false; 1252 if (ModifierIs(Modifier, ModifierLen, "quoted")) { 1253 Quoted = true; 1254 OutStr.push_back('\''); 1255 } else { 1256 assert(ModifierLen == 0 && "unknown modifier for string"); 1257 } 1258 EscapeStringForDiagnostic(S, OutStr); 1259 if (Quoted) 1260 OutStr.push_back('\''); 1261 break; 1262 } 1263 // ---- INTEGERS ---- 1264 case DiagnosticsEngine::ak_sint: { 1265 int64_t Val = getArgSInt(ArgNo); 1266 1267 if (ModifierIs(Modifier, ModifierLen, "select")) { 1268 HandleSelectModifier(*this, (unsigned)Val, Argument, ArgumentLen, 1269 OutStr); 1270 } else if (ModifierIs(Modifier, ModifierLen, "s")) { 1271 HandleIntegerSModifier(Val, OutStr); 1272 } else if (ModifierIs(Modifier, ModifierLen, "plural")) { 1273 HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen, 1274 OutStr); 1275 } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) { 1276 HandleOrdinalModifier((unsigned)Val, OutStr); 1277 } else if (ModifierIs(Modifier, ModifierLen, "human")) { 1278 HandleIntegerHumanModifier(Val, OutStr); 1279 } else { 1280 assert(ModifierLen == 0 && "Unknown integer modifier"); 1281 llvm::raw_svector_ostream(OutStr) << Val; 1282 } 1283 break; 1284 } 1285 case DiagnosticsEngine::ak_uint: { 1286 uint64_t Val = getArgUInt(ArgNo); 1287 1288 if (ModifierIs(Modifier, ModifierLen, "select")) { 1289 HandleSelectModifier(*this, Val, Argument, ArgumentLen, OutStr); 1290 } else if (ModifierIs(Modifier, ModifierLen, "s")) { 1291 HandleIntegerSModifier(Val, OutStr); 1292 } else if (ModifierIs(Modifier, ModifierLen, "plural")) { 1293 HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen, 1294 OutStr); 1295 } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) { 1296 HandleOrdinalModifier(Val, OutStr); 1297 } else if (ModifierIs(Modifier, ModifierLen, "human")) { 1298 HandleIntegerHumanModifier(Val, OutStr); 1299 } else { 1300 assert(ModifierLen == 0 && "Unknown integer modifier"); 1301 llvm::raw_svector_ostream(OutStr) << Val; 1302 } 1303 break; 1304 } 1305 // ---- TOKEN SPELLINGS ---- 1306 case DiagnosticsEngine::ak_tokenkind: { 1307 tok::TokenKind Kind = static_cast<tok::TokenKind>(getRawArg(ArgNo)); 1308 assert(ModifierLen == 0 && "No modifiers for token kinds yet"); 1309 1310 llvm::raw_svector_ostream Out(OutStr); 1311 if (const char *S = tok::getPunctuatorSpelling(Kind)) 1312 // Quoted token spelling for punctuators. 1313 Out << '\'' << S << '\''; 1314 else if ((S = tok::getKeywordSpelling(Kind))) 1315 // Unquoted token spelling for keywords. 1316 Out << S; 1317 else if ((S = getTokenDescForDiagnostic(Kind))) 1318 // Unquoted translatable token name. 1319 Out << S; 1320 else if ((S = tok::getTokenName(Kind))) 1321 // Debug name, shouldn't appear in user-facing diagnostics. 1322 Out << '<' << S << '>'; 1323 else 1324 Out << "(null)"; 1325 break; 1326 } 1327 // ---- NAMES and TYPES ---- 1328 case DiagnosticsEngine::ak_identifierinfo: { 1329 const IdentifierInfo *II = getArgIdentifier(ArgNo); 1330 assert(ModifierLen == 0 && "No modifiers for strings yet"); 1331 1332 // Don't crash if get passed a null pointer by accident. 1333 if (!II) { 1334 const char *S = "(null)"; 1335 OutStr.append(S, S + strlen(S)); 1336 continue; 1337 } 1338 1339 llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\''; 1340 break; 1341 } 1342 case DiagnosticsEngine::ak_addrspace: 1343 case DiagnosticsEngine::ak_qual: 1344 case DiagnosticsEngine::ak_qualtype: 1345 case DiagnosticsEngine::ak_declarationname: 1346 case DiagnosticsEngine::ak_nameddecl: 1347 case DiagnosticsEngine::ak_nestednamespec: 1348 case DiagnosticsEngine::ak_declcontext: 1349 case DiagnosticsEngine::ak_attr: 1350 case DiagnosticsEngine::ak_expr: 1351 case DiagnosticsEngine::ak_attr_info: 1352 getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo), 1353 StringRef(Modifier, ModifierLen), 1354 StringRef(Argument, ArgumentLen), 1355 FormattedArgs, OutStr, QualTypeVals); 1356 break; 1357 case DiagnosticsEngine::ak_qualtype_pair: { 1358 // Create a struct with all the info needed for printing. 1359 TemplateDiffTypes TDT; 1360 TDT.FromType = getRawArg(ArgNo); 1361 TDT.ToType = getRawArg(ArgNo2); 1362 TDT.ElideType = getDiags()->ElideType; 1363 TDT.ShowColors = getDiags()->ShowColors; 1364 TDT.TemplateDiffUsed = false; 1365 intptr_t val = reinterpret_cast<intptr_t>(&TDT); 1366 1367 const char *ArgumentEnd = Argument + ArgumentLen; 1368 const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|'); 1369 1370 // Print the tree. If this diagnostic already has a tree, skip the 1371 // second tree. 1372 if (getDiags()->PrintTemplateTree && Tree.empty()) { 1373 TDT.PrintFromType = true; 1374 TDT.PrintTree = true; 1375 getDiags()->ConvertArgToString(Kind, val, 1376 StringRef(Modifier, ModifierLen), 1377 StringRef(Argument, ArgumentLen), 1378 FormattedArgs, Tree, QualTypeVals); 1379 // If there is no tree information, fall back to regular printing. 1380 if (!Tree.empty()) { 1381 FormatDiagnostic(Pipe + 1, ArgumentEnd, OutStr); 1382 break; 1383 } 1384 } 1385 1386 // Non-tree printing, also the fall-back when tree printing fails. 1387 // The fall-back is triggered when the types compared are not templates. 1388 const char *FirstDollar = ScanFormat(Argument, ArgumentEnd, '$'); 1389 const char *SecondDollar = ScanFormat(FirstDollar + 1, ArgumentEnd, '$'); 1390 1391 // Append before text 1392 FormatDiagnostic(Argument, FirstDollar, OutStr); 1393 1394 // Append first type 1395 TDT.PrintTree = false; 1396 TDT.PrintFromType = true; 1397 getDiags()->ConvertArgToString(Kind, val, 1398 StringRef(Modifier, ModifierLen), 1399 StringRef(Argument, ArgumentLen), 1400 FormattedArgs, OutStr, QualTypeVals); 1401 if (!TDT.TemplateDiffUsed) 1402 FormattedArgs.push_back( 1403 std::make_pair(DiagnosticsEngine::ak_qualtype, TDT.FromType)); 1404 1405 // Append middle text 1406 FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr); 1407 1408 // Append second type 1409 TDT.PrintFromType = false; 1410 getDiags()->ConvertArgToString(Kind, val, 1411 StringRef(Modifier, ModifierLen), 1412 StringRef(Argument, ArgumentLen), 1413 FormattedArgs, OutStr, QualTypeVals); 1414 if (!TDT.TemplateDiffUsed) 1415 FormattedArgs.push_back( 1416 std::make_pair(DiagnosticsEngine::ak_qualtype, TDT.ToType)); 1417 1418 // Append end text 1419 FormatDiagnostic(SecondDollar + 1, Pipe, OutStr); 1420 break; 1421 } 1422 } 1423 1424 // Remember this argument info for subsequent formatting operations. Turn 1425 // std::strings into a null terminated string to make it be the same case as 1426 // all the other ones. 1427 if (Kind == DiagnosticsEngine::ak_qualtype_pair) 1428 continue; 1429 else if (Kind != DiagnosticsEngine::ak_std_string) 1430 FormattedArgs.push_back(std::make_pair(Kind, getRawArg(ArgNo))); 1431 else 1432 FormattedArgs.push_back( 1433 std::make_pair(DiagnosticsEngine::ak_c_string, 1434 (intptr_t)getArgStdStr(ArgNo).c_str())); 1435 } 1436 1437 // Append the type tree to the end of the diagnostics. 1438 OutStr.append(Tree.begin(), Tree.end()); 1439 } 1440 1441 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 1442 StringRef Message) 1443 : ID(ID), Level(Level), Message(Message) {} 1444 1445 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, 1446 const Diagnostic &Info) 1447 : ID(Info.getID()), Level(Level) { 1448 assert( 1449 (Info.getLocation().isInvalid() || Info.hasSourceManager()) && 1450 "Valid source location without setting a source manager for diagnostic"); 1451 if (Info.getLocation().isValid()) 1452 Loc = FullSourceLoc(Info.getLocation(), Info.getSourceManager()); 1453 SmallString<64> Message; 1454 Info.FormatDiagnostic(Message); 1455 this->Message.assign(Message.begin(), Message.end()); 1456 this->Ranges.assign(Info.getRanges().begin(), Info.getRanges().end()); 1457 this->FixIts.assign(Info.getFixItHints().begin(), Info.getFixItHints().end()); 1458 } 1459 1460 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 1461 StringRef Message, FullSourceLoc Loc, 1462 ArrayRef<CharSourceRange> Ranges, 1463 ArrayRef<FixItHint> FixIts) 1464 : ID(ID), Level(Level), Loc(Loc), Message(Message), 1465 Ranges(Ranges.begin(), Ranges.end()), 1466 FixIts(FixIts.begin(), FixIts.end()) {} 1467 1468 llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS, 1469 const StoredDiagnostic &SD) { 1470 if (SD.getLocation().hasManager()) 1471 OS << SD.getLocation().printToString(SD.getLocation().getManager()) << ": "; 1472 OS << SD.getMessage(); 1473 return OS; 1474 } 1475 1476 /// IncludeInDiagnosticCounts - This method (whose default implementation 1477 /// returns true) indicates whether the diagnostics handled by this 1478 /// DiagnosticConsumer should be included in the number of diagnostics 1479 /// reported by DiagnosticsEngine. 1480 bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; } 1481 1482 void IgnoringDiagConsumer::anchor() {} 1483 1484 ForwardingDiagnosticConsumer::~ForwardingDiagnosticConsumer() = default; 1485 1486 void ForwardingDiagnosticConsumer::HandleDiagnostic( 1487 DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) { 1488 Target.HandleDiagnostic(DiagLevel, Info); 1489 } 1490 1491 void ForwardingDiagnosticConsumer::clear() { 1492 DiagnosticConsumer::clear(); 1493 Target.clear(); 1494 } 1495 1496 bool ForwardingDiagnosticConsumer::IncludeInDiagnosticCounts() const { 1497 return Target.IncludeInDiagnosticCounts(); 1498 } 1499 1500 DiagStorageAllocator::DiagStorageAllocator() { 1501 for (unsigned I = 0; I != NumCached; ++I) 1502 FreeList[I] = Cached + I; 1503 NumFreeListEntries = NumCached; 1504 } 1505 1506 DiagStorageAllocator::~DiagStorageAllocator() { 1507 // Don't assert if we are in a CrashRecovery context, as this invariant may 1508 // be invalidated during a crash. 1509 assert((NumFreeListEntries == NumCached || 1510 llvm::CrashRecoveryContext::isRecoveringFromCrash()) && 1511 "A partial is on the lam"); 1512 } 1513 1514 char DiagnosticError::ID; 1515