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