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