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