1 //===--- Diagnostic.cpp - C Language Family Diagnostic Handling -----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the Diagnostic-related interfaces. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Basic/CharInfo.h" 15 #include "clang/Basic/Diagnostic.h" 16 #include "clang/Basic/DiagnosticOptions.h" 17 #include "clang/Basic/IdentifierTable.h" 18 #include "clang/Basic/PartialDiagnostic.h" 19 #include "llvm/ADT/SmallString.h" 20 #include "llvm/ADT/StringExtras.h" 21 #include "llvm/Support/CrashRecoveryContext.h" 22 #include "llvm/Support/raw_ostream.h" 23 24 using namespace clang; 25 26 static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, 27 StringRef Modifier, StringRef Argument, 28 ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, 29 SmallVectorImpl<char> &Output, 30 void *Cookie, 31 ArrayRef<intptr_t> QualTypeVals) { 32 StringRef Str = "<can't format argument>"; 33 Output.append(Str.begin(), Str.end()); 34 } 35 36 DiagnosticsEngine::DiagnosticsEngine( 37 const IntrusiveRefCntPtr<DiagnosticIDs> &diags, DiagnosticOptions *DiagOpts, 38 DiagnosticConsumer *client, bool ShouldOwnClient) 39 : Diags(diags), DiagOpts(DiagOpts), Client(nullptr), SourceMgr(nullptr) { 40 setClient(client, ShouldOwnClient); 41 ArgToStringFn = DummyArgToStringFn; 42 ArgToStringCookie = nullptr; 43 44 AllExtensionsSilenced = 0; 45 IgnoreAllWarnings = false; 46 WarningsAsErrors = false; 47 EnableAllWarnings = false; 48 ErrorsAsFatal = false; 49 SuppressSystemWarnings = false; 50 SuppressAllDiagnostics = false; 51 ElideType = true; 52 PrintTemplateTree = false; 53 ShowColors = false; 54 ShowOverloads = Ovl_All; 55 ExtBehavior = diag::Severity::Ignored; 56 57 ErrorLimit = 0; 58 TemplateBacktraceLimit = 0; 59 ConstexprBacktraceLimit = 0; 60 61 Reset(); 62 } 63 64 DiagnosticsEngine::~DiagnosticsEngine() { 65 // If we own the diagnostic client, destroy it first so that it can access the 66 // engine from its destructor. 67 setClient(nullptr); 68 } 69 70 void DiagnosticsEngine::setClient(DiagnosticConsumer *client, 71 bool ShouldOwnClient) { 72 Owner.reset(ShouldOwnClient ? client : nullptr); 73 Client = client; 74 } 75 76 void DiagnosticsEngine::pushMappings(SourceLocation Loc) { 77 DiagStateOnPushStack.push_back(GetCurDiagState()); 78 } 79 80 bool DiagnosticsEngine::popMappings(SourceLocation Loc) { 81 if (DiagStateOnPushStack.empty()) 82 return false; 83 84 if (DiagStateOnPushStack.back() != GetCurDiagState()) { 85 // State changed at some point between push/pop. 86 PushDiagStatePoint(DiagStateOnPushStack.back(), Loc); 87 } 88 DiagStateOnPushStack.pop_back(); 89 return true; 90 } 91 92 void DiagnosticsEngine::Reset() { 93 ErrorOccurred = false; 94 UncompilableErrorOccurred = false; 95 FatalErrorOccurred = false; 96 UnrecoverableErrorOccurred = false; 97 98 NumWarnings = 0; 99 NumErrors = 0; 100 TrapNumErrorsOccurred = 0; 101 TrapNumUnrecoverableErrorsOccurred = 0; 102 103 CurDiagID = ~0U; 104 LastDiagLevel = DiagnosticIDs::Ignored; 105 DelayedDiagID = 0; 106 107 // Clear state related to #pragma diagnostic. 108 DiagStates.clear(); 109 DiagStatePoints.clear(); 110 DiagStateOnPushStack.clear(); 111 112 // Create a DiagState and DiagStatePoint representing diagnostic changes 113 // through command-line. 114 DiagStates.push_back(DiagState()); 115 DiagStatePoints.push_back(DiagStatePoint(&DiagStates.back(), FullSourceLoc())); 116 } 117 118 void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1, 119 StringRef Arg2) { 120 if (DelayedDiagID) 121 return; 122 123 DelayedDiagID = DiagID; 124 DelayedDiagArg1 = Arg1.str(); 125 DelayedDiagArg2 = Arg2.str(); 126 } 127 128 void DiagnosticsEngine::ReportDelayed() { 129 Report(DelayedDiagID) << DelayedDiagArg1 << DelayedDiagArg2; 130 DelayedDiagID = 0; 131 DelayedDiagArg1.clear(); 132 DelayedDiagArg2.clear(); 133 } 134 135 DiagnosticsEngine::DiagStatePointsTy::iterator 136 DiagnosticsEngine::GetDiagStatePointForLoc(SourceLocation L) const { 137 assert(!DiagStatePoints.empty()); 138 assert(DiagStatePoints.front().Loc.isInvalid() && 139 "Should have created a DiagStatePoint for command-line"); 140 141 if (!SourceMgr) 142 return DiagStatePoints.end() - 1; 143 144 FullSourceLoc Loc(L, *SourceMgr); 145 if (Loc.isInvalid()) 146 return DiagStatePoints.end() - 1; 147 148 DiagStatePointsTy::iterator Pos = DiagStatePoints.end(); 149 FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc; 150 if (LastStateChangePos.isValid() && 151 Loc.isBeforeInTranslationUnitThan(LastStateChangePos)) 152 Pos = std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(), 153 DiagStatePoint(nullptr, Loc)); 154 --Pos; 155 return Pos; 156 } 157 158 void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map, 159 SourceLocation L) { 160 assert(Diag < diag::DIAG_UPPER_LIMIT && 161 "Can only map builtin diagnostics"); 162 assert((Diags->isBuiltinWarningOrExtension(Diag) || 163 (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) && 164 "Cannot map errors into warnings!"); 165 assert(!DiagStatePoints.empty()); 166 assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location"); 167 168 FullSourceLoc Loc = SourceMgr? FullSourceLoc(L, *SourceMgr) : FullSourceLoc(); 169 FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc; 170 // Don't allow a mapping to a warning override an error/fatal mapping. 171 if (Map == diag::Severity::Warning) { 172 DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag); 173 if (Info.getSeverity() == diag::Severity::Error || 174 Info.getSeverity() == diag::Severity::Fatal) 175 Map = Info.getSeverity(); 176 } 177 DiagnosticMapping Mapping = makeUserMapping(Map, L); 178 179 // Common case; setting all the diagnostics of a group in one place. 180 if (Loc.isInvalid() || Loc == LastStateChangePos) { 181 GetCurDiagState()->setMapping(Diag, Mapping); 182 return; 183 } 184 185 // Another common case; modifying diagnostic state in a source location 186 // after the previous one. 187 if ((Loc.isValid() && LastStateChangePos.isInvalid()) || 188 LastStateChangePos.isBeforeInTranslationUnitThan(Loc)) { 189 // A diagnostic pragma occurred, create a new DiagState initialized with 190 // the current one and a new DiagStatePoint to record at which location 191 // the new state became active. 192 DiagStates.push_back(*GetCurDiagState()); 193 PushDiagStatePoint(&DiagStates.back(), Loc); 194 GetCurDiagState()->setMapping(Diag, Mapping); 195 return; 196 } 197 198 // We allow setting the diagnostic state in random source order for 199 // completeness but it should not be actually happening in normal practice. 200 201 DiagStatePointsTy::iterator Pos = GetDiagStatePointForLoc(Loc); 202 assert(Pos != DiagStatePoints.end()); 203 204 // Update all diagnostic states that are active after the given location. 205 for (DiagStatePointsTy::iterator 206 I = Pos+1, E = DiagStatePoints.end(); I != E; ++I) { 207 GetCurDiagState()->setMapping(Diag, Mapping); 208 } 209 210 // If the location corresponds to an existing point, just update its state. 211 if (Pos->Loc == Loc) { 212 GetCurDiagState()->setMapping(Diag, Mapping); 213 return; 214 } 215 216 // Create a new state/point and fit it into the vector of DiagStatePoints 217 // so that the vector is always ordered according to location. 218 assert(Pos->Loc.isBeforeInTranslationUnitThan(Loc)); 219 DiagStates.push_back(*Pos->State); 220 DiagState *NewState = &DiagStates.back(); 221 GetCurDiagState()->setMapping(Diag, Mapping); 222 DiagStatePoints.insert(Pos+1, DiagStatePoint(NewState, 223 FullSourceLoc(Loc, *SourceMgr))); 224 } 225 226 bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor, 227 StringRef Group, diag::Severity Map, 228 SourceLocation Loc) { 229 // Get the diagnostics in this group. 230 SmallVector<diag::kind, 256> GroupDiags; 231 if (Diags->getDiagnosticsInGroup(Flavor, Group, GroupDiags)) 232 return true; 233 234 // Set the mapping. 235 for (diag::kind Diag : GroupDiags) 236 setSeverity(Diag, Map, Loc); 237 238 return false; 239 } 240 241 bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group, 242 bool Enabled) { 243 // If we are enabling this feature, just set the diagnostic mappings to map to 244 // errors. 245 if (Enabled) 246 return setSeverityForGroup(diag::Flavor::WarningOrError, Group, 247 diag::Severity::Error); 248 249 // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and 250 // potentially downgrade anything already mapped to be a warning. 251 252 // Get the diagnostics in this group. 253 SmallVector<diag::kind, 8> GroupDiags; 254 if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group, 255 GroupDiags)) 256 return true; 257 258 // Perform the mapping change. 259 for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) { 260 DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(GroupDiags[i]); 261 262 if (Info.getSeverity() == diag::Severity::Error || 263 Info.getSeverity() == diag::Severity::Fatal) 264 Info.setSeverity(diag::Severity::Warning); 265 266 Info.setNoWarningAsError(true); 267 } 268 269 return false; 270 } 271 272 bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group, 273 bool Enabled) { 274 // If we are enabling this feature, just set the diagnostic mappings to map to 275 // fatal errors. 276 if (Enabled) 277 return setSeverityForGroup(diag::Flavor::WarningOrError, Group, 278 diag::Severity::Fatal); 279 280 // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and 281 // potentially downgrade anything already mapped to be an error. 282 283 // Get the diagnostics in this group. 284 SmallVector<diag::kind, 8> GroupDiags; 285 if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group, 286 GroupDiags)) 287 return true; 288 289 // Perform the mapping change. 290 for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) { 291 DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(GroupDiags[i]); 292 293 if (Info.getSeverity() == diag::Severity::Fatal) 294 Info.setSeverity(diag::Severity::Error); 295 296 Info.setNoErrorAsFatal(true); 297 } 298 299 return false; 300 } 301 302 void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor, 303 diag::Severity Map, 304 SourceLocation Loc) { 305 // Get all the diagnostics. 306 SmallVector<diag::kind, 64> AllDiags; 307 Diags->getAllDiagnostics(Flavor, AllDiags); 308 309 // Set the mapping. 310 for (unsigned i = 0, e = AllDiags.size(); i != e; ++i) 311 if (Diags->isBuiltinWarningOrExtension(AllDiags[i])) 312 setSeverity(AllDiags[i], Map, Loc); 313 } 314 315 void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { 316 assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!"); 317 318 CurDiagLoc = storedDiag.getLocation(); 319 CurDiagID = storedDiag.getID(); 320 NumDiagArgs = 0; 321 322 DiagRanges.clear(); 323 DiagRanges.reserve(storedDiag.range_size()); 324 for (StoredDiagnostic::range_iterator 325 RI = storedDiag.range_begin(), 326 RE = storedDiag.range_end(); RI != RE; ++RI) 327 DiagRanges.push_back(*RI); 328 329 DiagFixItHints.clear(); 330 DiagFixItHints.reserve(storedDiag.fixit_size()); 331 for (StoredDiagnostic::fixit_iterator 332 FI = storedDiag.fixit_begin(), 333 FE = storedDiag.fixit_end(); FI != FE; ++FI) 334 DiagFixItHints.push_back(*FI); 335 336 assert(Client && "DiagnosticConsumer not set!"); 337 Level DiagLevel = storedDiag.getLevel(); 338 Diagnostic Info(this, storedDiag.getMessage()); 339 Client->HandleDiagnostic(DiagLevel, Info); 340 if (Client->IncludeInDiagnosticCounts()) { 341 if (DiagLevel == DiagnosticsEngine::Warning) 342 ++NumWarnings; 343 } 344 345 CurDiagID = ~0U; 346 } 347 348 bool DiagnosticsEngine::EmitCurrentDiagnostic(bool Force) { 349 assert(getClient() && "DiagnosticClient not set!"); 350 351 bool Emitted; 352 if (Force) { 353 Diagnostic Info(this); 354 355 // Figure out the diagnostic level of this message. 356 DiagnosticIDs::Level DiagLevel 357 = Diags->getDiagnosticLevel(Info.getID(), Info.getLocation(), *this); 358 359 Emitted = (DiagLevel != DiagnosticIDs::Ignored); 360 if (Emitted) { 361 // Emit the diagnostic regardless of suppression level. 362 Diags->EmitDiag(*this, DiagLevel); 363 } 364 } else { 365 // Process the diagnostic, sending the accumulated information to the 366 // DiagnosticConsumer. 367 Emitted = ProcessDiag(); 368 } 369 370 // Clear out the current diagnostic object. 371 unsigned DiagID = CurDiagID; 372 Clear(); 373 374 // If there was a delayed diagnostic, emit it now. 375 if (!Force && DelayedDiagID && DelayedDiagID != DiagID) 376 ReportDelayed(); 377 378 return Emitted; 379 } 380 381 382 DiagnosticConsumer::~DiagnosticConsumer() {} 383 384 void DiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 385 const Diagnostic &Info) { 386 if (!IncludeInDiagnosticCounts()) 387 return; 388 389 if (DiagLevel == DiagnosticsEngine::Warning) 390 ++NumWarnings; 391 else if (DiagLevel >= DiagnosticsEngine::Error) 392 ++NumErrors; 393 } 394 395 /// ModifierIs - Return true if the specified modifier matches specified string. 396 template <std::size_t StrLen> 397 static bool ModifierIs(const char *Modifier, unsigned ModifierLen, 398 const char (&Str)[StrLen]) { 399 return StrLen-1 == ModifierLen && !memcmp(Modifier, Str, StrLen-1); 400 } 401 402 /// ScanForward - Scans forward, looking for the given character, skipping 403 /// nested clauses and escaped characters. 404 static const char *ScanFormat(const char *I, const char *E, char Target) { 405 unsigned Depth = 0; 406 407 for ( ; I != E; ++I) { 408 if (Depth == 0 && *I == Target) return I; 409 if (Depth != 0 && *I == '}') Depth--; 410 411 if (*I == '%') { 412 I++; 413 if (I == E) break; 414 415 // Escaped characters get implicitly skipped here. 416 417 // Format specifier. 418 if (!isDigit(*I) && !isPunctuation(*I)) { 419 for (I++; I != E && !isDigit(*I) && *I != '{'; I++) ; 420 if (I == E) break; 421 if (*I == '{') 422 Depth++; 423 } 424 } 425 } 426 return E; 427 } 428 429 /// HandleSelectModifier - Handle the integer 'select' modifier. This is used 430 /// like this: %select{foo|bar|baz}2. This means that the integer argument 431 /// "%2" has a value from 0-2. If the value is 0, the diagnostic prints 'foo'. 432 /// If the value is 1, it prints 'bar'. If it has the value 2, it prints 'baz'. 433 /// This is very useful for certain classes of variant diagnostics. 434 static void HandleSelectModifier(const Diagnostic &DInfo, unsigned ValNo, 435 const char *Argument, unsigned ArgumentLen, 436 SmallVectorImpl<char> &OutStr) { 437 const char *ArgumentEnd = Argument+ArgumentLen; 438 439 // Skip over 'ValNo' |'s. 440 while (ValNo) { 441 const char *NextVal = ScanFormat(Argument, ArgumentEnd, '|'); 442 assert(NextVal != ArgumentEnd && "Value for integer select modifier was" 443 " larger than the number of options in the diagnostic string!"); 444 Argument = NextVal+1; // Skip this string. 445 --ValNo; 446 } 447 448 // Get the end of the value. This is either the } or the |. 449 const char *EndPtr = ScanFormat(Argument, ArgumentEnd, '|'); 450 451 // Recursively format the result of the select clause into the output string. 452 DInfo.FormatDiagnostic(Argument, EndPtr, OutStr); 453 } 454 455 /// HandleIntegerSModifier - Handle the integer 's' modifier. This adds the 456 /// letter 's' to the string if the value is not 1. This is used in cases like 457 /// this: "you idiot, you have %4 parameter%s4!". 458 static void HandleIntegerSModifier(unsigned ValNo, 459 SmallVectorImpl<char> &OutStr) { 460 if (ValNo != 1) 461 OutStr.push_back('s'); 462 } 463 464 /// HandleOrdinalModifier - Handle the integer 'ord' modifier. This 465 /// prints the ordinal form of the given integer, with 1 corresponding 466 /// to the first ordinal. Currently this is hard-coded to use the 467 /// English form. 468 static void HandleOrdinalModifier(unsigned ValNo, 469 SmallVectorImpl<char> &OutStr) { 470 assert(ValNo != 0 && "ValNo must be strictly positive!"); 471 472 llvm::raw_svector_ostream Out(OutStr); 473 474 // We could use text forms for the first N ordinals, but the numeric 475 // forms are actually nicer in diagnostics because they stand out. 476 Out << ValNo << llvm::getOrdinalSuffix(ValNo); 477 } 478 479 480 /// PluralNumber - Parse an unsigned integer and advance Start. 481 static unsigned PluralNumber(const char *&Start, const char *End) { 482 // Programming 101: Parse a decimal number :-) 483 unsigned Val = 0; 484 while (Start != End && *Start >= '0' && *Start <= '9') { 485 Val *= 10; 486 Val += *Start - '0'; 487 ++Start; 488 } 489 return Val; 490 } 491 492 /// TestPluralRange - Test if Val is in the parsed range. Modifies Start. 493 static bool TestPluralRange(unsigned Val, const char *&Start, const char *End) { 494 if (*Start != '[') { 495 unsigned Ref = PluralNumber(Start, End); 496 return Ref == Val; 497 } 498 499 ++Start; 500 unsigned Low = PluralNumber(Start, End); 501 assert(*Start == ',' && "Bad plural expression syntax: expected ,"); 502 ++Start; 503 unsigned High = PluralNumber(Start, End); 504 assert(*Start == ']' && "Bad plural expression syntax: expected )"); 505 ++Start; 506 return Low <= Val && Val <= High; 507 } 508 509 /// EvalPluralExpr - Actual expression evaluator for HandlePluralModifier. 510 static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) { 511 // Empty condition? 512 if (*Start == ':') 513 return true; 514 515 while (1) { 516 char C = *Start; 517 if (C == '%') { 518 // Modulo expression 519 ++Start; 520 unsigned Arg = PluralNumber(Start, End); 521 assert(*Start == '=' && "Bad plural expression syntax: expected ="); 522 ++Start; 523 unsigned ValMod = ValNo % Arg; 524 if (TestPluralRange(ValMod, Start, End)) 525 return true; 526 } else { 527 assert((C == '[' || (C >= '0' && C <= '9')) && 528 "Bad plural expression syntax: unexpected character"); 529 // Range expression 530 if (TestPluralRange(ValNo, Start, End)) 531 return true; 532 } 533 534 // Scan for next or-expr part. 535 Start = std::find(Start, End, ','); 536 if (Start == End) 537 break; 538 ++Start; 539 } 540 return false; 541 } 542 543 /// HandlePluralModifier - Handle the integer 'plural' modifier. This is used 544 /// for complex plural forms, or in languages where all plurals are complex. 545 /// The syntax is: %plural{cond1:form1|cond2:form2|:form3}, where condn are 546 /// conditions that are tested in order, the form corresponding to the first 547 /// that applies being emitted. The empty condition is always true, making the 548 /// last form a default case. 549 /// Conditions are simple boolean expressions, where n is the number argument. 550 /// Here are the rules. 551 /// condition := expression | empty 552 /// empty := -> always true 553 /// expression := numeric [',' expression] -> logical or 554 /// numeric := range -> true if n in range 555 /// | '%' number '=' range -> true if n % number in range 556 /// range := number 557 /// | '[' number ',' number ']' -> ranges are inclusive both ends 558 /// 559 /// Here are some examples from the GNU gettext manual written in this form: 560 /// English: 561 /// {1:form0|:form1} 562 /// Latvian: 563 /// {0:form2|%100=11,%10=0,%10=[2,9]:form1|:form0} 564 /// Gaeilge: 565 /// {1:form0|2:form1|:form2} 566 /// Romanian: 567 /// {1:form0|0,%100=[1,19]:form1|:form2} 568 /// Lithuanian: 569 /// {%10=0,%100=[10,19]:form2|%10=1:form0|:form1} 570 /// Russian (requires repeated form): 571 /// {%100=[11,14]:form2|%10=1:form0|%10=[2,4]:form1|:form2} 572 /// Slovak 573 /// {1:form0|[2,4]:form1|:form2} 574 /// Polish (requires repeated form): 575 /// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2} 576 static void HandlePluralModifier(const Diagnostic &DInfo, unsigned ValNo, 577 const char *Argument, unsigned ArgumentLen, 578 SmallVectorImpl<char> &OutStr) { 579 const char *ArgumentEnd = Argument + ArgumentLen; 580 while (1) { 581 assert(Argument < ArgumentEnd && "Plural expression didn't match."); 582 const char *ExprEnd = Argument; 583 while (*ExprEnd != ':') { 584 assert(ExprEnd != ArgumentEnd && "Plural missing expression end"); 585 ++ExprEnd; 586 } 587 if (EvalPluralExpr(ValNo, Argument, ExprEnd)) { 588 Argument = ExprEnd + 1; 589 ExprEnd = ScanFormat(Argument, ArgumentEnd, '|'); 590 591 // Recursively format the result of the plural clause into the 592 // output string. 593 DInfo.FormatDiagnostic(Argument, ExprEnd, OutStr); 594 return; 595 } 596 Argument = ScanFormat(Argument, ArgumentEnd - 1, '|') + 1; 597 } 598 } 599 600 /// \brief Returns the friendly description for a token kind that will appear 601 /// without quotes in diagnostic messages. These strings may be translatable in 602 /// future. 603 static const char *getTokenDescForDiagnostic(tok::TokenKind Kind) { 604 switch (Kind) { 605 case tok::identifier: 606 return "identifier"; 607 default: 608 return nullptr; 609 } 610 } 611 612 /// FormatDiagnostic - Format this diagnostic into a string, substituting the 613 /// formal arguments into the %0 slots. The result is appended onto the Str 614 /// array. 615 void Diagnostic:: 616 FormatDiagnostic(SmallVectorImpl<char> &OutStr) const { 617 if (!StoredDiagMessage.empty()) { 618 OutStr.append(StoredDiagMessage.begin(), StoredDiagMessage.end()); 619 return; 620 } 621 622 StringRef Diag = 623 getDiags()->getDiagnosticIDs()->getDescription(getID()); 624 625 FormatDiagnostic(Diag.begin(), Diag.end(), OutStr); 626 } 627 628 void Diagnostic:: 629 FormatDiagnostic(const char *DiagStr, const char *DiagEnd, 630 SmallVectorImpl<char> &OutStr) const { 631 632 /// FormattedArgs - Keep track of all of the arguments formatted by 633 /// ConvertArgToString and pass them into subsequent calls to 634 /// ConvertArgToString, allowing the implementation to avoid redundancies in 635 /// obvious cases. 636 SmallVector<DiagnosticsEngine::ArgumentValue, 8> FormattedArgs; 637 638 /// QualTypeVals - Pass a vector of arrays so that QualType names can be 639 /// compared to see if more information is needed to be printed. 640 SmallVector<intptr_t, 2> QualTypeVals; 641 SmallVector<char, 64> Tree; 642 643 for (unsigned i = 0, e = getNumArgs(); i < e; ++i) 644 if (getArgKind(i) == DiagnosticsEngine::ak_qualtype) 645 QualTypeVals.push_back(getRawArg(i)); 646 647 while (DiagStr != DiagEnd) { 648 if (DiagStr[0] != '%') { 649 // Append non-%0 substrings to Str if we have one. 650 const char *StrEnd = std::find(DiagStr, DiagEnd, '%'); 651 OutStr.append(DiagStr, StrEnd); 652 DiagStr = StrEnd; 653 continue; 654 } else if (isPunctuation(DiagStr[1])) { 655 OutStr.push_back(DiagStr[1]); // %% -> %. 656 DiagStr += 2; 657 continue; 658 } 659 660 // Skip the %. 661 ++DiagStr; 662 663 // This must be a placeholder for a diagnostic argument. The format for a 664 // placeholder is one of "%0", "%modifier0", or "%modifier{arguments}0". 665 // The digit is a number from 0-9 indicating which argument this comes from. 666 // The modifier is a string of digits from the set [-a-z]+, arguments is a 667 // brace enclosed string. 668 const char *Modifier = nullptr, *Argument = nullptr; 669 unsigned ModifierLen = 0, ArgumentLen = 0; 670 671 // Check to see if we have a modifier. If so eat it. 672 if (!isDigit(DiagStr[0])) { 673 Modifier = DiagStr; 674 while (DiagStr[0] == '-' || 675 (DiagStr[0] >= 'a' && DiagStr[0] <= 'z')) 676 ++DiagStr; 677 ModifierLen = DiagStr-Modifier; 678 679 // If we have an argument, get it next. 680 if (DiagStr[0] == '{') { 681 ++DiagStr; // Skip {. 682 Argument = DiagStr; 683 684 DiagStr = ScanFormat(DiagStr, DiagEnd, '}'); 685 assert(DiagStr != DiagEnd && "Mismatched {}'s in diagnostic string!"); 686 ArgumentLen = DiagStr-Argument; 687 ++DiagStr; // Skip }. 688 } 689 } 690 691 assert(isDigit(*DiagStr) && "Invalid format for argument in diagnostic"); 692 unsigned ArgNo = *DiagStr++ - '0'; 693 694 // Only used for type diffing. 695 unsigned ArgNo2 = ArgNo; 696 697 DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo); 698 if (ModifierIs(Modifier, ModifierLen, "diff")) { 699 assert(*DiagStr == ',' && isDigit(*(DiagStr + 1)) && 700 "Invalid format for diff modifier"); 701 ++DiagStr; // Comma. 702 ArgNo2 = *DiagStr++ - '0'; 703 DiagnosticsEngine::ArgumentKind Kind2 = getArgKind(ArgNo2); 704 if (Kind == DiagnosticsEngine::ak_qualtype && 705 Kind2 == DiagnosticsEngine::ak_qualtype) 706 Kind = DiagnosticsEngine::ak_qualtype_pair; 707 else { 708 // %diff only supports QualTypes. For other kinds of arguments, 709 // use the default printing. For example, if the modifier is: 710 // "%diff{compare $ to $|other text}1,2" 711 // treat it as: 712 // "compare %1 to %2" 713 const char *Pipe = ScanFormat(Argument, Argument + ArgumentLen, '|'); 714 const char *FirstDollar = ScanFormat(Argument, Pipe, '$'); 715 const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$'); 716 const char ArgStr1[] = { '%', static_cast<char>('0' + ArgNo) }; 717 const char ArgStr2[] = { '%', static_cast<char>('0' + ArgNo2) }; 718 FormatDiagnostic(Argument, FirstDollar, OutStr); 719 FormatDiagnostic(ArgStr1, ArgStr1 + 2, OutStr); 720 FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr); 721 FormatDiagnostic(ArgStr2, ArgStr2 + 2, OutStr); 722 FormatDiagnostic(SecondDollar + 1, Pipe, OutStr); 723 continue; 724 } 725 } 726 727 switch (Kind) { 728 // ---- STRINGS ---- 729 case DiagnosticsEngine::ak_std_string: { 730 const std::string &S = getArgStdStr(ArgNo); 731 assert(ModifierLen == 0 && "No modifiers for strings yet"); 732 OutStr.append(S.begin(), S.end()); 733 break; 734 } 735 case DiagnosticsEngine::ak_c_string: { 736 const char *S = getArgCStr(ArgNo); 737 assert(ModifierLen == 0 && "No modifiers for strings yet"); 738 739 // Don't crash if get passed a null pointer by accident. 740 if (!S) 741 S = "(null)"; 742 743 OutStr.append(S, S + strlen(S)); 744 break; 745 } 746 // ---- INTEGERS ---- 747 case DiagnosticsEngine::ak_sint: { 748 int Val = getArgSInt(ArgNo); 749 750 if (ModifierIs(Modifier, ModifierLen, "select")) { 751 HandleSelectModifier(*this, (unsigned)Val, Argument, ArgumentLen, 752 OutStr); 753 } else if (ModifierIs(Modifier, ModifierLen, "s")) { 754 HandleIntegerSModifier(Val, OutStr); 755 } else if (ModifierIs(Modifier, ModifierLen, "plural")) { 756 HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen, 757 OutStr); 758 } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) { 759 HandleOrdinalModifier((unsigned)Val, OutStr); 760 } else { 761 assert(ModifierLen == 0 && "Unknown integer modifier"); 762 llvm::raw_svector_ostream(OutStr) << Val; 763 } 764 break; 765 } 766 case DiagnosticsEngine::ak_uint: { 767 unsigned Val = getArgUInt(ArgNo); 768 769 if (ModifierIs(Modifier, ModifierLen, "select")) { 770 HandleSelectModifier(*this, Val, Argument, ArgumentLen, OutStr); 771 } else if (ModifierIs(Modifier, ModifierLen, "s")) { 772 HandleIntegerSModifier(Val, OutStr); 773 } else if (ModifierIs(Modifier, ModifierLen, "plural")) { 774 HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen, 775 OutStr); 776 } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) { 777 HandleOrdinalModifier(Val, OutStr); 778 } else { 779 assert(ModifierLen == 0 && "Unknown integer modifier"); 780 llvm::raw_svector_ostream(OutStr) << Val; 781 } 782 break; 783 } 784 // ---- TOKEN SPELLINGS ---- 785 case DiagnosticsEngine::ak_tokenkind: { 786 tok::TokenKind Kind = static_cast<tok::TokenKind>(getRawArg(ArgNo)); 787 assert(ModifierLen == 0 && "No modifiers for token kinds yet"); 788 789 llvm::raw_svector_ostream Out(OutStr); 790 if (const char *S = tok::getPunctuatorSpelling(Kind)) 791 // Quoted token spelling for punctuators. 792 Out << '\'' << S << '\''; 793 else if (const char *S = tok::getKeywordSpelling(Kind)) 794 // Unquoted token spelling for keywords. 795 Out << S; 796 else if (const char *S = getTokenDescForDiagnostic(Kind)) 797 // Unquoted translatable token name. 798 Out << S; 799 else if (const char *S = tok::getTokenName(Kind)) 800 // Debug name, shouldn't appear in user-facing diagnostics. 801 Out << '<' << S << '>'; 802 else 803 Out << "(null)"; 804 break; 805 } 806 // ---- NAMES and TYPES ---- 807 case DiagnosticsEngine::ak_identifierinfo: { 808 const IdentifierInfo *II = getArgIdentifier(ArgNo); 809 assert(ModifierLen == 0 && "No modifiers for strings yet"); 810 811 // Don't crash if get passed a null pointer by accident. 812 if (!II) { 813 const char *S = "(null)"; 814 OutStr.append(S, S + strlen(S)); 815 continue; 816 } 817 818 llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\''; 819 break; 820 } 821 case DiagnosticsEngine::ak_qualtype: 822 case DiagnosticsEngine::ak_declarationname: 823 case DiagnosticsEngine::ak_nameddecl: 824 case DiagnosticsEngine::ak_nestednamespec: 825 case DiagnosticsEngine::ak_declcontext: 826 case DiagnosticsEngine::ak_attr: 827 getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo), 828 StringRef(Modifier, ModifierLen), 829 StringRef(Argument, ArgumentLen), 830 FormattedArgs, 831 OutStr, QualTypeVals); 832 break; 833 case DiagnosticsEngine::ak_qualtype_pair: 834 // Create a struct with all the info needed for printing. 835 TemplateDiffTypes TDT; 836 TDT.FromType = getRawArg(ArgNo); 837 TDT.ToType = getRawArg(ArgNo2); 838 TDT.ElideType = getDiags()->ElideType; 839 TDT.ShowColors = getDiags()->ShowColors; 840 TDT.TemplateDiffUsed = false; 841 intptr_t val = reinterpret_cast<intptr_t>(&TDT); 842 843 const char *ArgumentEnd = Argument + ArgumentLen; 844 const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|'); 845 846 // Print the tree. If this diagnostic already has a tree, skip the 847 // second tree. 848 if (getDiags()->PrintTemplateTree && Tree.empty()) { 849 TDT.PrintFromType = true; 850 TDT.PrintTree = true; 851 getDiags()->ConvertArgToString(Kind, val, 852 StringRef(Modifier, ModifierLen), 853 StringRef(Argument, ArgumentLen), 854 FormattedArgs, 855 Tree, QualTypeVals); 856 // If there is no tree information, fall back to regular printing. 857 if (!Tree.empty()) { 858 FormatDiagnostic(Pipe + 1, ArgumentEnd, OutStr); 859 break; 860 } 861 } 862 863 // Non-tree printing, also the fall-back when tree printing fails. 864 // The fall-back is triggered when the types compared are not templates. 865 const char *FirstDollar = ScanFormat(Argument, ArgumentEnd, '$'); 866 const char *SecondDollar = ScanFormat(FirstDollar + 1, ArgumentEnd, '$'); 867 868 // Append before text 869 FormatDiagnostic(Argument, FirstDollar, OutStr); 870 871 // Append first type 872 TDT.PrintTree = false; 873 TDT.PrintFromType = true; 874 getDiags()->ConvertArgToString(Kind, val, 875 StringRef(Modifier, ModifierLen), 876 StringRef(Argument, ArgumentLen), 877 FormattedArgs, 878 OutStr, QualTypeVals); 879 if (!TDT.TemplateDiffUsed) 880 FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype, 881 TDT.FromType)); 882 883 // Append middle text 884 FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr); 885 886 // Append second type 887 TDT.PrintFromType = false; 888 getDiags()->ConvertArgToString(Kind, val, 889 StringRef(Modifier, ModifierLen), 890 StringRef(Argument, ArgumentLen), 891 FormattedArgs, 892 OutStr, QualTypeVals); 893 if (!TDT.TemplateDiffUsed) 894 FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype, 895 TDT.ToType)); 896 897 // Append end text 898 FormatDiagnostic(SecondDollar + 1, Pipe, OutStr); 899 break; 900 } 901 902 // Remember this argument info for subsequent formatting operations. Turn 903 // std::strings into a null terminated string to make it be the same case as 904 // all the other ones. 905 if (Kind == DiagnosticsEngine::ak_qualtype_pair) 906 continue; 907 else if (Kind != DiagnosticsEngine::ak_std_string) 908 FormattedArgs.push_back(std::make_pair(Kind, getRawArg(ArgNo))); 909 else 910 FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_c_string, 911 (intptr_t)getArgStdStr(ArgNo).c_str())); 912 913 } 914 915 // Append the type tree to the end of the diagnostics. 916 OutStr.append(Tree.begin(), Tree.end()); 917 } 918 919 StoredDiagnostic::StoredDiagnostic() { } 920 921 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 922 StringRef Message) 923 : ID(ID), Level(Level), Loc(), Message(Message) { } 924 925 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, 926 const Diagnostic &Info) 927 : ID(Info.getID()), Level(Level) 928 { 929 assert((Info.getLocation().isInvalid() || Info.hasSourceManager()) && 930 "Valid source location without setting a source manager for diagnostic"); 931 if (Info.getLocation().isValid()) 932 Loc = FullSourceLoc(Info.getLocation(), Info.getSourceManager()); 933 SmallString<64> Message; 934 Info.FormatDiagnostic(Message); 935 this->Message.assign(Message.begin(), Message.end()); 936 937 Ranges.reserve(Info.getNumRanges()); 938 for (unsigned I = 0, N = Info.getNumRanges(); I != N; ++I) 939 Ranges.push_back(Info.getRange(I)); 940 941 FixIts.reserve(Info.getNumFixItHints()); 942 for (unsigned I = 0, N = Info.getNumFixItHints(); I != N; ++I) 943 FixIts.push_back(Info.getFixItHint(I)); 944 } 945 946 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 947 StringRef Message, FullSourceLoc Loc, 948 ArrayRef<CharSourceRange> Ranges, 949 ArrayRef<FixItHint> FixIts) 950 : ID(ID), Level(Level), Loc(Loc), Message(Message), 951 Ranges(Ranges.begin(), Ranges.end()), FixIts(FixIts.begin(), FixIts.end()) 952 { 953 } 954 955 StoredDiagnostic::~StoredDiagnostic() { } 956 957 /// IncludeInDiagnosticCounts - This method (whose default implementation 958 /// returns true) indicates whether the diagnostics handled by this 959 /// DiagnosticConsumer should be included in the number of diagnostics 960 /// reported by DiagnosticsEngine. 961 bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; } 962 963 void IgnoringDiagConsumer::anchor() { } 964 965 ForwardingDiagnosticConsumer::~ForwardingDiagnosticConsumer() {} 966 967 void ForwardingDiagnosticConsumer::HandleDiagnostic( 968 DiagnosticsEngine::Level DiagLevel, 969 const Diagnostic &Info) { 970 Target.HandleDiagnostic(DiagLevel, Info); 971 } 972 973 void ForwardingDiagnosticConsumer::clear() { 974 DiagnosticConsumer::clear(); 975 Target.clear(); 976 } 977 978 bool ForwardingDiagnosticConsumer::IncludeInDiagnosticCounts() const { 979 return Target.IncludeInDiagnosticCounts(); 980 } 981 982 PartialDiagnostic::StorageAllocator::StorageAllocator() { 983 for (unsigned I = 0; I != NumCached; ++I) 984 FreeList[I] = Cached + I; 985 NumFreeListEntries = NumCached; 986 } 987 988 PartialDiagnostic::StorageAllocator::~StorageAllocator() { 989 // Don't assert if we are in a CrashRecovery context, as this invariant may 990 // be invalidated during a crash. 991 assert((NumFreeListEntries == NumCached || 992 llvm::CrashRecoveryContext::isRecoveringFromCrash()) && 993 "A partial is on the lamb"); 994 } 995