LLVM  4.0.0
SourceMgr.cpp
Go to the documentation of this file.
1 //===- SourceMgr.cpp - Manager for Simple Source Buffers & Diagnostics ----===//
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 SourceMgr class. This class is used as a simple
11 // substrate for diagnostics, #include handling, and other low level things for
12 // simple parsers.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "llvm/Support/SourceMgr.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/Support/Locale.h"
21 #include "llvm/Support/Path.h"
23 using namespace llvm;
24 
25 static const size_t TabStop = 8;
26 
27 namespace {
28  struct LineNoCacheTy {
29  const char *LastQuery;
30  unsigned LastQueryBufferID;
31  unsigned LineNoOfQuery;
32  };
33 }
34 
35 static LineNoCacheTy *getCache(void *Ptr) {
36  return (LineNoCacheTy*)Ptr;
37 }
38 
39 
41  // Delete the line # cache if allocated.
42  if (LineNoCacheTy *Cache = getCache(LineNoCache))
43  delete Cache;
44 }
45 
46 unsigned SourceMgr::AddIncludeFile(const std::string &Filename,
47  SMLoc IncludeLoc,
48  std::string &IncludedFile) {
49  IncludedFile = Filename;
51  MemoryBuffer::getFile(IncludedFile);
52 
53  // If the file didn't exist directly, see if it's in an include path.
54  for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBufOrErr;
55  ++i) {
56  IncludedFile =
57  IncludeDirectories[i] + sys::path::get_separator().data() + Filename;
58  NewBufOrErr = MemoryBuffer::getFile(IncludedFile);
59  }
60 
61  if (!NewBufOrErr)
62  return 0;
63 
64  return AddNewSourceBuffer(std::move(*NewBufOrErr), IncludeLoc);
65 }
66 
68  for (unsigned i = 0, e = Buffers.size(); i != e; ++i)
69  if (Loc.getPointer() >= Buffers[i].Buffer->getBufferStart() &&
70  // Use <= here so that a pointer to the null at the end of the buffer
71  // is included as part of the buffer.
72  Loc.getPointer() <= Buffers[i].Buffer->getBufferEnd())
73  return i + 1;
74  return 0;
75 }
76 
77 std::pair<unsigned, unsigned>
78 SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
79  if (!BufferID)
80  BufferID = FindBufferContainingLoc(Loc);
81  assert(BufferID && "Invalid Location!");
82 
83  const MemoryBuffer *Buff = getMemoryBuffer(BufferID);
84 
85  // Count the number of \n's between the start of the file and the specified
86  // location.
87  unsigned LineNo = 1;
88 
89  const char *BufStart = Buff->getBufferStart();
90  const char *Ptr = BufStart;
91 
92  // If we have a line number cache, and if the query is to a later point in the
93  // same file, start searching from the last query location. This optimizes
94  // for the case when multiple diagnostics come out of one file in order.
95  if (LineNoCacheTy *Cache = getCache(LineNoCache))
96  if (Cache->LastQueryBufferID == BufferID &&
97  Cache->LastQuery <= Loc.getPointer()) {
98  Ptr = Cache->LastQuery;
99  LineNo = Cache->LineNoOfQuery;
100  }
101 
102  // Scan for the location being queried, keeping track of the number of lines
103  // we see.
104  for (; SMLoc::getFromPointer(Ptr) != Loc; ++Ptr)
105  if (*Ptr == '\n') ++LineNo;
106 
107  // Allocate the line number cache if it doesn't exist.
108  if (!LineNoCache)
109  LineNoCache = new LineNoCacheTy();
110 
111  // Update the line # cache.
112  LineNoCacheTy &Cache = *getCache(LineNoCache);
113  Cache.LastQueryBufferID = BufferID;
114  Cache.LastQuery = Ptr;
115  Cache.LineNoOfQuery = LineNo;
116 
117  size_t NewlineOffs = StringRef(BufStart, Ptr-BufStart).find_last_of("\n\r");
118  if (NewlineOffs == StringRef::npos) NewlineOffs = ~(size_t)0;
119  return std::make_pair(LineNo, Ptr-BufStart-NewlineOffs);
120 }
121 
122 void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const {
123  if (IncludeLoc == SMLoc()) return; // Top of stack.
124 
125  unsigned CurBuf = FindBufferContainingLoc(IncludeLoc);
126  assert(CurBuf && "Invalid or unspecified location!");
127 
128  PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
129 
130  OS << "Included from "
131  << getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
132  << ":" << FindLineNumber(IncludeLoc, CurBuf) << ":\n";
133 }
134 
135 
137  const Twine &Msg,
138  ArrayRef<SMRange> Ranges,
139  ArrayRef<SMFixIt> FixIts) const {
140 
141  // First thing to do: find the current buffer containing the specified
142  // location to pull out the source line.
144  std::pair<unsigned, unsigned> LineAndCol;
145  StringRef BufferID = "<unknown>";
146  std::string LineStr;
147 
148  if (Loc.isValid()) {
149  unsigned CurBuf = FindBufferContainingLoc(Loc);
150  assert(CurBuf && "Invalid or unspecified location!");
151 
152  const MemoryBuffer *CurMB = getMemoryBuffer(CurBuf);
153  BufferID = CurMB->getBufferIdentifier();
154 
155  // Scan backward to find the start of the line.
156  const char *LineStart = Loc.getPointer();
157  const char *BufStart = CurMB->getBufferStart();
158  while (LineStart != BufStart && LineStart[-1] != '\n' &&
159  LineStart[-1] != '\r')
160  --LineStart;
161 
162  // Get the end of the line.
163  const char *LineEnd = Loc.getPointer();
164  const char *BufEnd = CurMB->getBufferEnd();
165  while (LineEnd != BufEnd && LineEnd[0] != '\n' && LineEnd[0] != '\r')
166  ++LineEnd;
167  LineStr = std::string(LineStart, LineEnd);
168 
169  // Convert any ranges to column ranges that only intersect the line of the
170  // location.
171  for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {
172  SMRange R = Ranges[i];
173  if (!R.isValid()) continue;
174 
175  // If the line doesn't contain any part of the range, then ignore it.
176  if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
177  continue;
178 
179  // Ignore pieces of the range that go onto other lines.
180  if (R.Start.getPointer() < LineStart)
181  R.Start = SMLoc::getFromPointer(LineStart);
182  if (R.End.getPointer() > LineEnd)
183  R.End = SMLoc::getFromPointer(LineEnd);
184 
185  // Translate from SMLoc ranges to column ranges.
186  // FIXME: Handle multibyte characters.
187  ColRanges.push_back(std::make_pair(R.Start.getPointer()-LineStart,
188  R.End.getPointer()-LineStart));
189  }
190 
191  LineAndCol = getLineAndColumn(Loc, CurBuf);
192  }
193 
194  return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first,
195  LineAndCol.second-1, Kind, Msg.str(),
196  LineStr, ColRanges, FixIts);
197 }
198 
200  bool ShowColors) const {
201  // Report the message with the diagnostic handler if present.
202  if (DiagHandler) {
203  DiagHandler(Diagnostic, DiagContext);
204  return;
205  }
206 
207  if (Diagnostic.getLoc().isValid()) {
208  unsigned CurBuf = FindBufferContainingLoc(Diagnostic.getLoc());
209  assert(CurBuf && "Invalid or unspecified location!");
210  PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
211  }
212 
213  Diagnostic.print(nullptr, OS, ShowColors);
214 }
215 
218  const Twine &Msg, ArrayRef<SMRange> Ranges,
219  ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
220  PrintMessage(OS, GetMessage(Loc, Kind, Msg, Ranges, FixIts), ShowColors);
221 }
222 
224  const Twine &Msg, ArrayRef<SMRange> Ranges,
225  ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
226  PrintMessage(llvm::errs(), Loc, Kind, Msg, Ranges, FixIts, ShowColors);
227 }
228 
229 //===----------------------------------------------------------------------===//
230 // SMDiagnostic Implementation
231 //===----------------------------------------------------------------------===//
232 
234  int Line, int Col, SourceMgr::DiagKind Kind,
235  StringRef Msg, StringRef LineStr,
236  ArrayRef<std::pair<unsigned,unsigned> > Ranges,
237  ArrayRef<SMFixIt> Hints)
238  : SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Kind(Kind),
239  Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
240  FixIts(Hints.begin(), Hints.end()) {
241  std::sort(FixIts.begin(), FixIts.end());
242 }
243 
244 static void buildFixItLine(std::string &CaretLine, std::string &FixItLine,
245  ArrayRef<SMFixIt> FixIts, ArrayRef<char> SourceLine){
246  if (FixIts.empty())
247  return;
248 
249  const char *LineStart = SourceLine.begin();
250  const char *LineEnd = SourceLine.end();
251 
252  size_t PrevHintEndCol = 0;
253 
254  for (ArrayRef<SMFixIt>::iterator I = FixIts.begin(), E = FixIts.end();
255  I != E; ++I) {
256  // If the fixit contains a newline or tab, ignore it.
257  if (I->getText().find_first_of("\n\r\t") != StringRef::npos)
258  continue;
259 
260  SMRange R = I->getRange();
261 
262  // If the line doesn't contain any part of the range, then ignore it.
263  if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
264  continue;
265 
266  // Translate from SMLoc to column.
267  // Ignore pieces of the range that go onto other lines.
268  // FIXME: Handle multibyte characters in the source line.
269  unsigned FirstCol;
270  if (R.Start.getPointer() < LineStart)
271  FirstCol = 0;
272  else
273  FirstCol = R.Start.getPointer() - LineStart;
274 
275  // If we inserted a long previous hint, push this one forwards, and add
276  // an extra space to show that this is not part of the previous
277  // completion. This is sort of the best we can do when two hints appear
278  // to overlap.
279  //
280  // Note that if this hint is located immediately after the previous
281  // hint, no space will be added, since the location is more important.
282  unsigned HintCol = FirstCol;
283  if (HintCol < PrevHintEndCol)
284  HintCol = PrevHintEndCol + 1;
285 
286  // FIXME: This assertion is intended to catch unintended use of multibyte
287  // characters in fixits. If we decide to do this, we'll have to track
288  // separate byte widths for the source and fixit lines.
289  assert((size_t)llvm::sys::locale::columnWidth(I->getText()) ==
290  I->getText().size());
291 
292  // This relies on one byte per column in our fixit hints.
293  unsigned LastColumnModified = HintCol + I->getText().size();
294  if (LastColumnModified > FixItLine.size())
295  FixItLine.resize(LastColumnModified, ' ');
296 
297  std::copy(I->getText().begin(), I->getText().end(),
298  FixItLine.begin() + HintCol);
299 
300  PrevHintEndCol = LastColumnModified;
301 
302  // For replacements, mark the removal range with '~'.
303  // FIXME: Handle multibyte characters in the source line.
304  unsigned LastCol;
305  if (R.End.getPointer() >= LineEnd)
306  LastCol = LineEnd - LineStart;
307  else
308  LastCol = R.End.getPointer() - LineStart;
309 
310  std::fill(&CaretLine[FirstCol], &CaretLine[LastCol], '~');
311  }
312 }
313 
314 static void printSourceLine(raw_ostream &S, StringRef LineContents) {
315  // Print out the source line one character at a time, so we can expand tabs.
316  for (unsigned i = 0, e = LineContents.size(), OutCol = 0; i != e; ++i) {
317  if (LineContents[i] != '\t') {
318  S << LineContents[i];
319  ++OutCol;
320  continue;
321  }
322 
323  // If we have a tab, emit at least one space, then round up to 8 columns.
324  do {
325  S << ' ';
326  ++OutCol;
327  } while ((OutCol % TabStop) != 0);
328  }
329  S << '\n';
330 }
331 
332 static bool isNonASCII(char c) {
333  return c & 0x80;
334 }
335 
336 void SMDiagnostic::print(const char *ProgName, raw_ostream &S, bool ShowColors,
337  bool ShowKindLabel) const {
338  // Display colors only if OS supports colors.
339  ShowColors &= S.has_colors();
340 
341  if (ShowColors)
343 
344  if (ProgName && ProgName[0])
345  S << ProgName << ": ";
346 
347  if (!Filename.empty()) {
348  if (Filename == "-")
349  S << "<stdin>";
350  else
351  S << Filename;
352 
353  if (LineNo != -1) {
354  S << ':' << LineNo;
355  if (ColumnNo != -1)
356  S << ':' << (ColumnNo+1);
357  }
358  S << ": ";
359  }
360 
361  if (ShowKindLabel) {
362  switch (Kind) {
363  case SourceMgr::DK_Error:
364  if (ShowColors)
365  S.changeColor(raw_ostream::RED, true);
366  S << "error: ";
367  break;
369  if (ShowColors)
371  S << "warning: ";
372  break;
373  case SourceMgr::DK_Note:
374  if (ShowColors)
376  S << "note: ";
377  break;
378  }
379 
380  if (ShowColors) {
381  S.resetColor();
383  }
384  }
385 
386  S << Message << '\n';
387 
388  if (ShowColors)
389  S.resetColor();
390 
391  if (LineNo == -1 || ColumnNo == -1)
392  return;
393 
394  // FIXME: If there are multibyte or multi-column characters in the source, all
395  // our ranges will be wrong. To do this properly, we'll need a byte-to-column
396  // map like Clang's TextDiagnostic. For now, we'll just handle tabs by
397  // expanding them later, and bail out rather than show incorrect ranges and
398  // misaligned fixits for any other odd characters.
399  if (find_if(LineContents, isNonASCII) != LineContents.end()) {
400  printSourceLine(S, LineContents);
401  return;
402  }
403  size_t NumColumns = LineContents.size();
404 
405  // Build the line with the caret and ranges.
406  std::string CaretLine(NumColumns+1, ' ');
407 
408  // Expand any ranges.
409  for (unsigned r = 0, e = Ranges.size(); r != e; ++r) {
410  std::pair<unsigned, unsigned> R = Ranges[r];
411  std::fill(&CaretLine[R.first],
412  &CaretLine[std::min((size_t)R.second, CaretLine.size())],
413  '~');
414  }
415 
416  // Add any fix-its.
417  // FIXME: Find the beginning of the line properly for multibyte characters.
418  std::string FixItInsertionLine;
419  buildFixItLine(CaretLine, FixItInsertionLine, FixIts,
420  makeArrayRef(Loc.getPointer() - ColumnNo,
421  LineContents.size()));
422 
423  // Finally, plop on the caret.
424  if (unsigned(ColumnNo) <= NumColumns)
425  CaretLine[ColumnNo] = '^';
426  else
427  CaretLine[NumColumns] = '^';
428 
429  // ... and remove trailing whitespace so the output doesn't wrap for it. We
430  // know that the line isn't completely empty because it has the caret in it at
431  // least.
432  CaretLine.erase(CaretLine.find_last_not_of(' ')+1);
433 
434  printSourceLine(S, LineContents);
435 
436  if (ShowColors)
438 
439  // Print out the caret line, matching tabs in the source line.
440  for (unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) {
441  if (i >= LineContents.size() || LineContents[i] != '\t') {
442  S << CaretLine[i];
443  ++OutCol;
444  continue;
445  }
446 
447  // Okay, we have a tab. Insert the appropriate number of characters.
448  do {
449  S << CaretLine[i];
450  ++OutCol;
451  } while ((OutCol % TabStop) != 0);
452  }
453  S << '\n';
454 
455  if (ShowColors)
456  S.resetColor();
457 
458  // Print out the replacement line, matching tabs in the source line.
459  if (FixItInsertionLine.empty())
460  return;
461 
462  for (size_t i = 0, e = FixItInsertionLine.size(), OutCol = 0; i < e; ++i) {
463  if (i >= LineContents.size() || LineContents[i] != '\t') {
464  S << FixItInsertionLine[i];
465  ++OutCol;
466  continue;
467  }
468 
469  // Okay, we have a tab. Insert the appropriate number of characters.
470  do {
471  S << FixItInsertionLine[i];
472  // FIXME: This is trying not to break up replacements, but then to re-sync
473  // with the tabs between replacements. This will fail, though, if two
474  // fix-it replacements are exactly adjacent, or if a fix-it contains a
475  // space. Really we should be precomputing column widths, which we'll
476  // need anyway for multibyte chars.
477  if (FixItInsertionLine[i] != ' ')
478  ++i;
479  ++OutCol;
480  } while (((OutCol % TabStop) != 0) && i != e);
481  }
482  S << '\n';
483 }
MachineLoop * L
void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true) const
Definition: SourceMgr.cpp:336
Represents a range in source code.
Definition: SMLoc.h:49
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:241
Represents either an error or a value T.
Definition: ErrorOr.h:68
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const
Prints the names of included files and the line of the file they were included from.
Definition: SourceMgr.cpp:122
const char * getPointer() const
Definition: SMLoc.h:35
const char * getBufferStart() const
Definition: MemoryBuffer.h:55
size_t i
std::pair< unsigned, unsigned > getLineAndColumn(SMLoc Loc, unsigned BufferID=0) const
Find the line and column number for the specified location in the specified file. ...
Definition: SourceMgr.cpp:78
iterator end() const
Definition: ArrayRef.h:130
virtual bool has_colors() const
This function determines if this stream is displayed and supports colors.
Definition: raw_ostream.h:270
virtual raw_ostream & changeColor(enum Colors Color, bool Bold=false, bool BG=false)
Changes the foreground color of text that will be output from this point forward. ...
Definition: raw_ostream.h:248
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:233
SMLoc Start
Definition: SMLoc.h:51
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:440
SMLoc getLoc() const
Definition: SourceMgr.h:255
bool isValid() const
Definition: SMLoc.h:30
static const size_t TabStop
Definition: SourceMgr.cpp:25
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
Definition: SourceMgr.h:118
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:141
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
int columnWidth(StringRef s)
Definition: Locale.cpp:10
LLVM_NODISCARD size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
Definition: StringRef.h:418
iterator begin() const
Definition: ArrayRef.h:129
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:136
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling...
Definition: SourceMgr.h:35
const SrcBuffer & getBufferInfo(unsigned i) const
Definition: SourceMgr.h:92
static LineNoCacheTy * getCache(void *Ptr)
Definition: SourceMgr.cpp:35
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
static void printSourceLine(raw_ostream &S, StringRef LineContents)
Definition: SourceMgr.cpp:314
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:40
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const
Find the line number for the specified location in the specified file.
Definition: SourceMgr.h:143
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
Definition: MemoryBuffer.h:65
StringRef get_separator()
Return the preferred separator for this platform.
Definition: Path.cpp:626
SMLoc End
Definition: SMLoc.h:51
static bool isNonASCII(char c)
Definition: SourceMgr.cpp:332
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:37
unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, std::string &IncludedFile)
Search for a file with the specified name in the current directory or in one of the IncludeDirs...
Definition: SourceMgr.cpp:46
const MemoryBuffer * getMemoryBuffer(unsigned i) const
Definition: SourceMgr.h:97
static const size_t npos
Definition: StringRef.h:51
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatileSize=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
#define I(x, y, z)
Definition: MD5.cpp:54
bool isValid() const
Definition: SMLoc.h:60
static void buildFixItLine(std::string &CaretLine, std::string &FixItLine, ArrayRef< SMFixIt > FixIts, ArrayRef< char > SourceLine)
Definition: SourceMgr.cpp:244
const char * getBufferEnd() const
Definition: MemoryBuffer.h:56
unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
Definition: SourceMgr.cpp:67
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual raw_ostream & resetColor()
Resets the colors to terminal defaults.
Definition: raw_ostream.h:259
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:125
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges=None, ArrayRef< SMFixIt > FixIts=None) const
Return an SMDiagnostic at the specified location with the specified string.
Definition: SourceMgr.cpp:136
int * Ptr
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges=None, ArrayRef< SMFixIt > FixIts=None, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
Definition: SourceMgr.cpp:216
Represents a location in source code.
Definition: SMLoc.h:24
auto find_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:764
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:228