LLVM 22.0.0git
SourceMgr.cpp
Go to the documentation of this file.
1//===- SourceMgr.cpp - Manager for Simple Source Buffers & Diagnostics ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the SourceMgr class. This class is used as a simple
10// substrate for diagnostics, #include handling, and other low level things for
11// simple parsers.
12//
13//===----------------------------------------------------------------------===//
14
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/STLExtras.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/ADT/Twine.h"
23#include "llvm/Support/Locale.h"
25#include "llvm/Support/Path.h"
26#include "llvm/Support/SMLoc.h"
30#include <algorithm>
31#include <cassert>
32#include <cstddef>
33#include <limits>
34#include <memory>
35#include <string>
36#include <utility>
37
38using namespace llvm;
39
40static const size_t TabStop = 8;
41
42// Out of line to avoid needing definition of vfs::FileSystem in header.
43SourceMgr::SourceMgr() = default;
48SourceMgr::~SourceMgr() = default;
49
53
55 this->FS = std::move(FS);
56}
57
58unsigned SourceMgr::AddIncludeFile(const std::string &Filename,
59 SMLoc IncludeLoc,
60 std::string &IncludedFile) {
62 OpenIncludeFile(Filename, IncludedFile);
63 if (!NewBufOrErr)
64 return 0;
65
66 return AddNewSourceBuffer(std::move(*NewBufOrErr), IncludeLoc);
67}
68
70SourceMgr::OpenIncludeFile(const std::string &Filename,
71 std::string &IncludedFile) {
72 if (!FS)
73 reportFatalInternalError("Opening include file from SourceMgr without VFS");
74
76 FS->getBufferForFile(Filename);
77
78 SmallString<64> Buffer(Filename);
79 // If the file didn't exist directly, see if it's in an include path.
80 for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBufOrErr;
81 ++i) {
82 Buffer = IncludeDirectories[i];
83 sys::path::append(Buffer, Filename);
84 NewBufOrErr = FS->getBufferForFile(Buffer);
85 }
86
87 if (NewBufOrErr)
88 IncludedFile = static_cast<std::string>(Buffer);
89
90 return NewBufOrErr;
91}
92
94 for (unsigned i = 0, e = Buffers.size(); i != e; ++i)
95 if (Loc.getPointer() >= Buffers[i].Buffer->getBufferStart() &&
96 // Use <= here so that a pointer to the null at the end of the buffer
97 // is included as part of the buffer.
98 Loc.getPointer() <= Buffers[i].Buffer->getBufferEnd())
99 return i + 1;
100 return 0;
101}
102
103template <typename T>
104static std::vector<T> &GetOrCreateOffsetCache(void *&OffsetCache,
105 MemoryBuffer *Buffer) {
106 if (OffsetCache)
107 return *static_cast<std::vector<T> *>(OffsetCache);
108
109 // Lazily fill in the offset cache.
110 auto *Offsets = new std::vector<T>();
111 size_t Sz = Buffer->getBufferSize();
112 assert(Sz <= std::numeric_limits<T>::max());
113 StringRef S = Buffer->getBuffer();
114 for (size_t N = 0; N < Sz; ++N) {
115 if (S[N] == '\n')
116 Offsets->push_back(static_cast<T>(N));
117 }
118
119 OffsetCache = Offsets;
120 return *Offsets;
121}
122
123template <typename T>
124unsigned SourceMgr::SrcBuffer::getLineNumberSpecialized(const char *Ptr) const {
125 std::vector<T> &Offsets =
126 GetOrCreateOffsetCache<T>(OffsetCache, Buffer.get());
127
128 const char *BufStart = Buffer->getBufferStart();
129 assert(Ptr >= BufStart && Ptr <= Buffer->getBufferEnd());
130 ptrdiff_t PtrDiff = Ptr - BufStart;
131 assert(PtrDiff >= 0 &&
132 static_cast<size_t>(PtrDiff) <= std::numeric_limits<T>::max());
133 T PtrOffset = static_cast<T>(PtrDiff);
134
135 // llvm::lower_bound gives the number of EOL before PtrOffset. Add 1 to get
136 // the line number.
137 return llvm::lower_bound(Offsets, PtrOffset) - Offsets.begin() + 1;
138}
139
140/// Look up a given \p Ptr in the buffer, determining which line it came
141/// from.
142unsigned SourceMgr::SrcBuffer::getLineNumber(const char *Ptr) const {
143 size_t Sz = Buffer->getBufferSize();
144 if (Sz <= std::numeric_limits<uint8_t>::max())
145 return getLineNumberSpecialized<uint8_t>(Ptr);
146 else if (Sz <= std::numeric_limits<uint16_t>::max())
147 return getLineNumberSpecialized<uint16_t>(Ptr);
148 else if (Sz <= std::numeric_limits<uint32_t>::max())
149 return getLineNumberSpecialized<uint32_t>(Ptr);
150 else
151 return getLineNumberSpecialized<uint64_t>(Ptr);
152}
153
154template <typename T>
155const char *SourceMgr::SrcBuffer::getPointerForLineNumberSpecialized(
156 unsigned LineNo) const {
157 std::vector<T> &Offsets =
158 GetOrCreateOffsetCache<T>(OffsetCache, Buffer.get());
159
160 // We start counting line and column numbers from 1.
161 if (LineNo != 0)
162 --LineNo;
163
164 const char *BufStart = Buffer->getBufferStart();
165
166 // The offset cache contains the location of the \n for the specified line,
167 // we want the start of the line. As such, we look for the previous entry.
168 if (LineNo == 0)
169 return BufStart;
170 if (LineNo > Offsets.size())
171 return nullptr;
172 return BufStart + Offsets[LineNo - 1] + 1;
173}
174
175/// Return a pointer to the first character of the specified line number or
176/// null if the line number is invalid.
177const char *
178SourceMgr::SrcBuffer::getPointerForLineNumber(unsigned LineNo) const {
179 size_t Sz = Buffer->getBufferSize();
180 if (Sz <= std::numeric_limits<uint8_t>::max())
181 return getPointerForLineNumberSpecialized<uint8_t>(LineNo);
182 else if (Sz <= std::numeric_limits<uint16_t>::max())
183 return getPointerForLineNumberSpecialized<uint16_t>(LineNo);
184 else if (Sz <= std::numeric_limits<uint32_t>::max())
185 return getPointerForLineNumberSpecialized<uint32_t>(LineNo);
186 else
187 return getPointerForLineNumberSpecialized<uint64_t>(LineNo);
188}
189
190SourceMgr::SrcBuffer::SrcBuffer(SourceMgr::SrcBuffer &&Other)
191 : Buffer(std::move(Other.Buffer)), OffsetCache(Other.OffsetCache),
192 IncludeLoc(Other.IncludeLoc) {
193 Other.OffsetCache = nullptr;
194}
195
196SourceMgr::SrcBuffer::~SrcBuffer() {
197 if (OffsetCache) {
198 size_t Sz = Buffer->getBufferSize();
199 if (Sz <= std::numeric_limits<uint8_t>::max())
200 delete static_cast<std::vector<uint8_t> *>(OffsetCache);
201 else if (Sz <= std::numeric_limits<uint16_t>::max())
202 delete static_cast<std::vector<uint16_t> *>(OffsetCache);
203 else if (Sz <= std::numeric_limits<uint32_t>::max())
204 delete static_cast<std::vector<uint32_t> *>(OffsetCache);
205 else
206 delete static_cast<std::vector<uint64_t> *>(OffsetCache);
207 OffsetCache = nullptr;
208 }
209}
210
211std::pair<unsigned, unsigned>
212SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
213 if (!BufferID)
214 BufferID = FindBufferContainingLoc(Loc);
215 assert(BufferID && "Invalid location!");
216
217 auto &SB = getBufferInfo(BufferID);
218 const char *Ptr = Loc.getPointer();
219
220 unsigned LineNo = SB.getLineNumber(Ptr);
221 const char *BufStart = SB.Buffer->getBufferStart();
222 size_t NewlineOffs = StringRef(BufStart, Ptr - BufStart).find_last_of("\n\r");
223 if (NewlineOffs == StringRef::npos)
224 NewlineOffs = ~(size_t)0;
225 return {LineNo, Ptr - BufStart - NewlineOffs};
226}
227
228// FIXME: Note that the formatting of source locations is spread between
229// multiple functions, some in SourceMgr and some in SMDiagnostic. A better
230// solution would be a general-purpose source location formatter
231// in one of those two classes, or possibly in SMLoc.
232
233/// Get a string with the source location formatted in the standard
234/// style, but without the line offset. If \p IncludePath is true, the path
235/// is included. If false, only the file name and extension are included.
237 bool IncludePath) const {
238 auto BufferID = FindBufferContainingLoc(Loc);
239 assert(BufferID && "Invalid location!");
240 auto FileSpec = getBufferInfo(BufferID).Buffer->getBufferIdentifier();
241
242 if (IncludePath) {
243 return FileSpec.str() + ":" + std::to_string(FindLineNumber(Loc, BufferID));
244 } else {
245 auto I = FileSpec.find_last_of("/\\");
246 I = (I == FileSpec.size()) ? 0 : (I + 1);
247 return FileSpec.substr(I).str() + ":" +
248 std::to_string(FindLineNumber(Loc, BufferID));
249 }
250}
251
252/// Given a line and column number in a mapped buffer, turn it into an SMLoc.
253/// This will return a null SMLoc if the line/column location is invalid.
254SMLoc SourceMgr::FindLocForLineAndColumn(unsigned BufferID, unsigned LineNo,
255 unsigned ColNo) {
256 auto &SB = getBufferInfo(BufferID);
257 const char *Ptr = SB.getPointerForLineNumber(LineNo);
258 if (!Ptr)
259 return SMLoc();
260
261 // We start counting line and column numbers from 1.
262 if (ColNo != 0)
263 --ColNo;
264
265 // If we have a column number, validate it.
266 if (ColNo) {
267 // Make sure the location is within the current line.
268 if (Ptr + ColNo > SB.Buffer->getBufferEnd())
269 return SMLoc();
270
271 // Make sure there is no newline in the way.
272 if (StringRef(Ptr, ColNo).find_first_of("\n\r") != StringRef::npos)
273 return SMLoc();
274
275 Ptr += ColNo;
276 }
277
279}
280
281void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const {
282 if (IncludeLoc == SMLoc())
283 return; // Top of stack.
284
285 unsigned CurBuf = FindBufferContainingLoc(IncludeLoc);
286 assert(CurBuf && "Invalid or unspecified location!");
287
288 PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
289
290 OS << "Included from " << getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
291 << ":" << FindLineNumber(IncludeLoc, CurBuf) << ":\n";
292}
293
295 const Twine &Msg, ArrayRef<SMRange> Ranges,
296 ArrayRef<SMFixIt> FixIts) const {
297 // First thing to do: find the current buffer containing the specified
298 // location to pull out the source line.
300 std::pair<unsigned, unsigned> LineAndCol;
301 StringRef BufferID = "<unknown>";
302 StringRef LineStr;
303
304 if (Loc.isValid()) {
305 unsigned CurBuf = FindBufferContainingLoc(Loc);
306 assert(CurBuf && "Invalid or unspecified location!");
307
308 const MemoryBuffer *CurMB = getMemoryBuffer(CurBuf);
309 BufferID = CurMB->getBufferIdentifier();
310
311 // Scan backward to find the start of the line.
312 const char *LineStart = Loc.getPointer();
313 const char *BufStart = CurMB->getBufferStart();
314 while (LineStart != BufStart && LineStart[-1] != '\n' &&
315 LineStart[-1] != '\r')
316 --LineStart;
317
318 // Get the end of the line.
319 const char *LineEnd = Loc.getPointer();
320 const char *BufEnd = CurMB->getBufferEnd();
321 while (LineEnd != BufEnd && LineEnd[0] != '\n' && LineEnd[0] != '\r')
322 ++LineEnd;
323 LineStr = StringRef(LineStart, LineEnd - LineStart);
324
325 // Convert any ranges to column ranges that only intersect the line of the
326 // location.
327 for (SMRange R : Ranges) {
328 if (!R.isValid())
329 continue;
330
331 // If the line doesn't contain any part of the range, then ignore it.
332 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
333 continue;
334
335 // Ignore pieces of the range that go onto other lines.
336 if (R.Start.getPointer() < LineStart)
337 R.Start = SMLoc::getFromPointer(LineStart);
338 if (R.End.getPointer() > LineEnd)
339 R.End = SMLoc::getFromPointer(LineEnd);
340
341 // Translate from SMLoc ranges to column ranges.
342 // FIXME: Handle multibyte characters.
343 ColRanges.push_back(std::make_pair(R.Start.getPointer() - LineStart,
344 R.End.getPointer() - LineStart));
345 }
346
347 LineAndCol = getLineAndColumn(Loc, CurBuf);
348 }
349
350 return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first,
351 LineAndCol.second - 1, Kind, Msg.str(), LineStr,
352 ColRanges, FixIts);
353}
354
356 bool ShowColors) const {
357 // Report the message with the diagnostic handler if present.
358 if (DiagHandler) {
359 DiagHandler(Diagnostic, DiagContext);
360 return;
361 }
362
363 if (Diagnostic.getLoc().isValid()) {
364 unsigned CurBuf = FindBufferContainingLoc(Diagnostic.getLoc());
365 assert(CurBuf && "Invalid or unspecified location!");
366 PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
367 }
368
369 Diagnostic.print(nullptr, OS, ShowColors);
370}
371
373 SourceMgr::DiagKind Kind, const Twine &Msg,
375 bool ShowColors) const {
376 PrintMessage(OS, GetMessage(Loc, Kind, Msg, Ranges, FixIts), ShowColors);
377}
378
380 const Twine &Msg, ArrayRef<SMRange> Ranges,
381 ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
382 PrintMessage(errs(), Loc, Kind, Msg, Ranges, FixIts, ShowColors);
383}
384
385//===----------------------------------------------------------------------===//
386// SMFixIt Implementation
387//===----------------------------------------------------------------------===//
388
389SMFixIt::SMFixIt(SMRange R, const Twine &Replacement)
390 : Range(R), Text(Replacement.str()) {
391 assert(R.isValid());
392}
393
394//===----------------------------------------------------------------------===//
395// SMDiagnostic Implementation
396//===----------------------------------------------------------------------===//
397
399 int Col, SourceMgr::DiagKind Kind, StringRef Msg,
400 StringRef LineStr,
401 ArrayRef<std::pair<unsigned, unsigned>> Ranges,
402 ArrayRef<SMFixIt> Hints)
403 : SM(&sm), Loc(L), Filename(std::string(FN)), LineNo(Line), ColumnNo(Col),
404 Kind(Kind), Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
405 FixIts(Hints) {
406 llvm::sort(FixIts);
407}
408
409static void buildFixItLine(std::string &CaretLine, std::string &FixItLine,
410 ArrayRef<SMFixIt> FixIts,
411 ArrayRef<char> SourceLine) {
412 if (FixIts.empty())
413 return;
414
415 const char *LineStart = SourceLine.begin();
416 const char *LineEnd = SourceLine.end();
417
418 size_t PrevHintEndCol = 0;
419
420 for (const llvm::SMFixIt &Fixit : FixIts) {
421 // If the fixit contains a newline or tab, ignore it.
422 if (Fixit.getText().find_first_of("\n\r\t") != StringRef::npos)
423 continue;
424
425 SMRange R = Fixit.getRange();
426
427 // If the line doesn't contain any part of the range, then ignore it.
428 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
429 continue;
430
431 // Translate from SMLoc to column.
432 // Ignore pieces of the range that go onto other lines.
433 // FIXME: Handle multibyte characters in the source line.
434 unsigned FirstCol;
435 if (R.Start.getPointer() < LineStart)
436 FirstCol = 0;
437 else
438 FirstCol = R.Start.getPointer() - LineStart;
439
440 // If we inserted a long previous hint, push this one forwards, and add
441 // an extra space to show that this is not part of the previous
442 // completion. This is sort of the best we can do when two hints appear
443 // to overlap.
444 //
445 // Note that if this hint is located immediately after the previous
446 // hint, no space will be added, since the location is more important.
447 unsigned HintCol = FirstCol;
448 if (HintCol < PrevHintEndCol)
449 HintCol = PrevHintEndCol + 1;
450
451 // FIXME: This assertion is intended to catch unintended use of multibyte
452 // characters in fixits. If we decide to do this, we'll have to track
453 // separate byte widths for the source and fixit lines.
454 assert((size_t)sys::locale::columnWidth(Fixit.getText()) ==
455 Fixit.getText().size());
456
457 // This relies on one byte per column in our fixit hints.
458 unsigned LastColumnModified = HintCol + Fixit.getText().size();
459 if (LastColumnModified > FixItLine.size())
460 FixItLine.resize(LastColumnModified, ' ');
461
462 llvm::copy(Fixit.getText(), FixItLine.begin() + HintCol);
463
464 PrevHintEndCol = LastColumnModified;
465
466 // For replacements, mark the removal range with '~'.
467 // FIXME: Handle multibyte characters in the source line.
468 unsigned LastCol;
469 if (R.End.getPointer() >= LineEnd)
470 LastCol = LineEnd - LineStart;
471 else
472 LastCol = R.End.getPointer() - LineStart;
473
474 std::fill(&CaretLine[FirstCol], &CaretLine[LastCol], '~');
475 }
476}
477
478static void printSourceLine(raw_ostream &S, StringRef LineContents) {
479 // Print out the source line one character at a time, so we can expand tabs.
480 for (unsigned i = 0, e = LineContents.size(), OutCol = 0; i != e; ++i) {
481 size_t NextTab = LineContents.find('\t', i);
482 // If there were no tabs left, print the rest, we are done.
483 if (NextTab == StringRef::npos) {
484 S << LineContents.drop_front(i);
485 break;
486 }
487
488 // Otherwise, print from i to NextTab.
489 S << LineContents.slice(i, NextTab);
490 OutCol += NextTab - i;
491 i = NextTab;
492
493 // If we have a tab, emit at least one space, then round up to 8 columns.
494 do {
495 S << ' ';
496 ++OutCol;
497 } while ((OutCol % TabStop) != 0);
498 }
499 S << '\n';
500}
501
502static bool isNonASCII(char c) { return c & 0x80; }
503
504void SMDiagnostic::print(const char *ProgName, raw_ostream &OS, bool ShowColors,
505 bool ShowKindLabel, bool ShowLocation) const {
506 ColorMode Mode = ShowColors ? ColorMode::Auto : ColorMode::Disable;
507
508 {
509 WithColor S(OS, raw_ostream::SAVEDCOLOR, true, false, Mode);
510
511 if (ProgName && ProgName[0])
512 S << ProgName << ": ";
513
514 if (ShowLocation && !Filename.empty()) {
515 if (Filename == "-")
516 S << "<stdin>";
517 else
518 S << Filename;
519
520 if (LineNo != -1) {
521 S << ':' << LineNo;
522 if (ColumnNo != -1)
523 S << ':' << (ColumnNo + 1);
524 }
525 S << ": ";
526 }
527 }
528
529 if (ShowKindLabel) {
530 switch (Kind) {
532 WithColor::error(OS, "", !ShowColors);
533 break;
535 WithColor::warning(OS, "", !ShowColors);
536 break;
538 WithColor::note(OS, "", !ShowColors);
539 break;
541 WithColor::remark(OS, "", !ShowColors);
542 break;
543 }
544 }
545
546 WithColor(OS, raw_ostream::SAVEDCOLOR, true, false, Mode) << Message << '\n';
547
548 if (LineNo == -1 || ColumnNo == -1)
549 return;
550
551 // FIXME: If there are multibyte or multi-column characters in the source, all
552 // our ranges will be wrong. To do this properly, we'll need a byte-to-column
553 // map like Clang's TextDiagnostic. For now, we'll just handle tabs by
554 // expanding them later, and bail out rather than show incorrect ranges and
555 // misaligned fixits for any other odd characters.
556 if (any_of(LineContents, isNonASCII)) {
557 printSourceLine(OS, LineContents);
558 return;
559 }
560 size_t NumColumns = LineContents.size();
561
562 // Build the line with the caret and ranges.
563 std::string CaretLine(NumColumns + 1, ' ');
564
565 // Expand any ranges.
566 for (const std::pair<unsigned, unsigned> &R : Ranges)
567 std::fill(&CaretLine[R.first],
568 &CaretLine[std::min((size_t)R.second, CaretLine.size())], '~');
569
570 // Add any fix-its.
571 // FIXME: Find the beginning of the line properly for multibyte characters.
572 std::string FixItInsertionLine;
573 buildFixItLine(CaretLine, FixItInsertionLine, FixIts,
574 ArrayRef(Loc.getPointer() - ColumnNo, LineContents.size()));
575
576 // Finally, plop on the caret.
577 if (unsigned(ColumnNo) <= NumColumns)
578 CaretLine[ColumnNo] = '^';
579 else
580 CaretLine[NumColumns] = '^';
581
582 // ... and remove trailing whitespace so the output doesn't wrap for it. We
583 // know that the line isn't completely empty because it has the caret in it at
584 // least.
585 CaretLine.erase(CaretLine.find_last_not_of(' ') + 1);
586
587 printSourceLine(OS, LineContents);
588
589 {
590 ColorMode Mode = ShowColors ? ColorMode::Auto : ColorMode::Disable;
591 WithColor S(OS, raw_ostream::GREEN, true, false, Mode);
592
593 // Print out the caret line, matching tabs in the source line.
594 for (unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) {
595 if (i >= LineContents.size() || LineContents[i] != '\t') {
596 S << CaretLine[i];
597 ++OutCol;
598 continue;
599 }
600
601 // Okay, we have a tab. Insert the appropriate number of characters.
602 do {
603 S << CaretLine[i];
604 ++OutCol;
605 } while ((OutCol % TabStop) != 0);
606 }
607 S << '\n';
608 }
609
610 // Print out the replacement line, matching tabs in the source line.
611 if (FixItInsertionLine.empty())
612 return;
613
614 for (size_t i = 0, e = FixItInsertionLine.size(), OutCol = 0; i < e; ++i) {
615 if (i >= LineContents.size() || LineContents[i] != '\t') {
616 OS << FixItInsertionLine[i];
617 ++OutCol;
618 continue;
619 }
620
621 // Okay, we have a tab. Insert the appropriate number of characters.
622 do {
623 OS << FixItInsertionLine[i];
624 // FIXME: This is trying not to break up replacements, but then to re-sync
625 // with the tabs between replacements. This will fail, though, if two
626 // fix-it replacements are exactly adjacent, or if a fix-it contains a
627 // space. Really we should be precomputing column widths, which we'll
628 // need anyway for multibyte chars.
629 if (FixItInsertionLine[i] != ' ')
630 ++i;
631 ++OutCol;
632 } while (((OutCol % TabStop) != 0) && i != e);
633 }
634 OS << '\n';
635}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides ErrorOr<T> smart pointer.
#define I(x, y, z)
Definition MD5.cpp:58
#define T
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallString class.
This file defines the SmallVector class.
static const size_t TabStop
Definition SourceMgr.cpp:40
static bool isNonASCII(char c)
static void buildFixItLine(std::string &CaretLine, std::string &FixItLine, ArrayRef< SMFixIt > FixIts, ArrayRef< char > SourceLine)
static void printSourceLine(raw_ostream &S, StringRef LineContents)
static std::vector< T > & GetOrCreateOffsetCache(void *&OffsetCache, MemoryBuffer *Buffer)
Defines the virtual file system interface vfs::FileSystem.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
iterator end() const
Definition ArrayRef.h:136
iterator begin() const
Definition ArrayRef.h:135
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:142
Represents either an error or a value T.
Definition ErrorOr.h:56
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
This interface provides simple read-only access to a block of memory, and provides simple methods for...
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
size_t getBufferSize() const
StringRef getBuffer() const
const char * getBufferEnd() const
const char * getBufferStart() const
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition SourceMgr.h:297
LLVM_ABI void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true, bool ShowLocation=true) const
SMDiagnostic()=default
SMLoc getLoc() const
Definition SourceMgr.h:323
Represents a single fixit, a replacement of one range of text with another.
Definition SourceMgr.h:272
LLVM_ABI SMFixIt(SMRange R, const Twine &Replacement)
Represents a location in source code.
Definition SMLoc.h:23
static SMLoc getFromPointer(const char *Ptr)
Definition SMLoc.h:36
constexpr bool isValid() const
Definition SMLoc.h:29
Represents a range in source code.
Definition SMLoc.h:48
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
Definition SourceMgr.h:37
LLVM_ABI ErrorOr< std::unique_ptr< MemoryBuffer > > OpenIncludeFile(const std::string &Filename, std::string &IncludedFile)
Search for a file with the specified name in the current directory or in one of the IncludeDirs,...
Definition SourceMgr.cpp:70
SourceMgr & operator=(const SourceMgr &)=delete
LLVM_ABI 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.
void setVirtualFileSystem(IntrusiveRefCntPtr< vfs::FileSystem > FS)
Definition SourceMgr.cpp:54
const MemoryBuffer * getMemoryBuffer(unsigned i) const
Definition SourceMgr.h:141
LLVM_ABI void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
LLVM_ABI void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const
Prints the names of included files and the line of the file they were included from.
SourceMgr()
Create new source manager without support for include files.
LLVM_ABI unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
Definition SourceMgr.cpp:93
IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
Definition SourceMgr.cpp:50
LLVM_ABI SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}) const
Return an SMDiagnostic at the specified location with the specified string.
LLVM_ABI 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:58
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const
Find the line number for the specified location in the specified file.
Definition SourceMgr.h:212
LLVM_ABI std::string getFormattedLocationNoOffset(SMLoc Loc, bool IncludePath=false) const
Get a string with the SMLoc filename and line number formatted in the standard style.
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
Definition SourceMgr.h:160
LLVM_ABI SMLoc FindLocForLineAndColumn(unsigned BufferID, unsigned LineNo, unsigned ColNo)
Given a line and column number in a mapped buffer, turn it into an SMLoc.
const SrcBuffer & getBufferInfo(unsigned i) const
Definition SourceMgr.h:136
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition StringRef.h:611
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition StringRef.h:686
constexpr size_t size() const
size - Get the string size.
Definition StringRef.h:146
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:401
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition StringRef.h:293
static constexpr size_t npos
Definition StringRef.h:57
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
Definition Twine.cpp:17
An RAII object that temporarily switches an output stream to a specific color.
Definition WithColor.h:54
static LLVM_ABI raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
Definition WithColor.cpp:85
static LLVM_ABI raw_ostream & error()
Convenience method for printing "error: " to stderr.
Definition WithColor.cpp:83
static LLVM_ABI raw_ostream & note()
Convenience method for printing "note: " to stderr.
Definition WithColor.cpp:87
static LLVM_ABI raw_ostream & remark()
Convenience method for printing "remark: " to stderr.
Definition WithColor.cpp:89
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
static constexpr Colors SAVEDCOLOR
static constexpr Colors GREEN
Offsets
Offsets in bytes from the start of the input buffer.
LLVM_ABI int columnWidth(StringRef s)
Definition Locale.cpp:9
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition Path.cpp:456
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
Definition Error.cpp:177
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1732
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1622
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Other
Any other memory.
Definition ModRef.h:68
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:1994
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
Definition STLExtras.h:1835
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1867
ColorMode
Definition WithColor.h:40
@ Auto
Determine whether to use color based on the command line argument and the raw_ostream.
Definition WithColor.h:43
@ Disable
Disable colors.
Definition WithColor.h:49
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:867
#define N