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