LLVM 23.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
71 std::string &IncludedFile,
72 bool RequiresNullTerminator) {
73 auto GetFile = [this, RequiresNullTerminator](StringRef Path) {
74 return FS ? FS->getBufferForFile(Path, /*FileSize=*/-1,
75 RequiresNullTerminator)
76 : MemoryBuffer::getFile(Path, /*IsText=*/false,
77 RequiresNullTerminator);
78 };
79
80 ErrorOr<std::unique_ptr<MemoryBuffer>> NewBufOrErr = GetFile(Filename);
81
83 // If the file didn't exist directly, see if it's in an include path.
84 for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBufOrErr;
85 ++i) {
86 Buffer = IncludeDirectories[i];
88 NewBufOrErr = GetFile(Buffer);
89 }
90
91 if (NewBufOrErr)
92 IncludedFile = static_cast<std::string>(Buffer);
93
94 return NewBufOrErr;
95}
96
98 for (unsigned i = 0, e = Buffers.size(); i != e; ++i)
99 if (Loc.getPointer() >= Buffers[i].Buffer->getBufferStart() &&
100 // Use <= here so that a pointer to the null at the end of the buffer
101 // is included as part of the buffer.
102 Loc.getPointer() <= Buffers[i].Buffer->getBufferEnd())
103 return i + 1;
104 return 0;
105}
106
107template <typename T>
108static std::vector<T> &GetOrCreateOffsetCache(void *&OffsetCache,
109 MemoryBuffer *Buffer) {
110 if (OffsetCache)
111 return *static_cast<std::vector<T> *>(OffsetCache);
112
113 // Lazily fill in the offset cache.
114 auto *Offsets = new std::vector<T>();
115 size_t Sz = Buffer->getBufferSize();
116 assert(Sz <= std::numeric_limits<T>::max());
117 StringRef S = Buffer->getBuffer();
118 for (size_t N = 0; N < Sz; ++N) {
119 if (S[N] == '\n')
120 Offsets->push_back(static_cast<T>(N));
121 }
122
123 OffsetCache = Offsets;
124 return *Offsets;
125}
126
127template <typename T>
128unsigned SourceMgr::SrcBuffer::getLineNumberSpecialized(const char *Ptr) const {
129 std::vector<T> &Offsets =
130 GetOrCreateOffsetCache<T>(OffsetCache, Buffer.get());
131
132 const char *BufStart = Buffer->getBufferStart();
133 assert(Ptr >= BufStart && Ptr <= Buffer->getBufferEnd());
134 ptrdiff_t PtrDiff = Ptr - BufStart;
135 assert(PtrDiff >= 0 &&
136 static_cast<size_t>(PtrDiff) <= std::numeric_limits<T>::max());
137 T PtrOffset = static_cast<T>(PtrDiff);
138
139 // llvm::lower_bound gives the number of EOL before PtrOffset. Add 1 to get
140 // the line number.
141 return llvm::lower_bound(Offsets, PtrOffset) - Offsets.begin() + 1;
142}
143
144/// Look up a given \p Ptr in the buffer, determining which line it came
145/// from.
146unsigned SourceMgr::SrcBuffer::getLineNumber(const char *Ptr) const {
147 size_t Sz = Buffer->getBufferSize();
148 if (Sz <= std::numeric_limits<uint8_t>::max())
149 return getLineNumberSpecialized<uint8_t>(Ptr);
150 else if (Sz <= std::numeric_limits<uint16_t>::max())
151 return getLineNumberSpecialized<uint16_t>(Ptr);
152 else if (Sz <= std::numeric_limits<uint32_t>::max())
153 return getLineNumberSpecialized<uint32_t>(Ptr);
154 else
155 return getLineNumberSpecialized<uint64_t>(Ptr);
156}
157
158template <typename T>
159const char *SourceMgr::SrcBuffer::getPointerForLineNumberSpecialized(
160 unsigned LineNo) const {
161 std::vector<T> &Offsets =
162 GetOrCreateOffsetCache<T>(OffsetCache, Buffer.get());
163
164 // We start counting line and column numbers from 1.
165 if (LineNo != 0)
166 --LineNo;
167
168 const char *BufStart = Buffer->getBufferStart();
169
170 // The offset cache contains the location of the \n for the specified line,
171 // we want the start of the line. As such, we look for the previous entry.
172 if (LineNo == 0)
173 return BufStart;
174 if (LineNo > Offsets.size())
175 return nullptr;
176 return BufStart + Offsets[LineNo - 1] + 1;
177}
178
179/// Return a pointer to the first character of the specified line number or
180/// null if the line number is invalid.
181const char *
182SourceMgr::SrcBuffer::getPointerForLineNumber(unsigned LineNo) const {
183 size_t Sz = Buffer->getBufferSize();
184 if (Sz <= std::numeric_limits<uint8_t>::max())
185 return getPointerForLineNumberSpecialized<uint8_t>(LineNo);
186 else if (Sz <= std::numeric_limits<uint16_t>::max())
187 return getPointerForLineNumberSpecialized<uint16_t>(LineNo);
188 else if (Sz <= std::numeric_limits<uint32_t>::max())
189 return getPointerForLineNumberSpecialized<uint32_t>(LineNo);
190 else
191 return getPointerForLineNumberSpecialized<uint64_t>(LineNo);
192}
193
194SourceMgr::SrcBuffer::SrcBuffer(SourceMgr::SrcBuffer &&Other)
195 : Buffer(std::move(Other.Buffer)), OffsetCache(Other.OffsetCache),
196 IncludeLoc(Other.IncludeLoc) {
197 Other.OffsetCache = nullptr;
198}
199
200SourceMgr::SrcBuffer::~SrcBuffer() {
201 if (OffsetCache) {
202 size_t Sz = Buffer->getBufferSize();
203 if (Sz <= std::numeric_limits<uint8_t>::max())
204 delete static_cast<std::vector<uint8_t> *>(OffsetCache);
205 else if (Sz <= std::numeric_limits<uint16_t>::max())
206 delete static_cast<std::vector<uint16_t> *>(OffsetCache);
207 else if (Sz <= std::numeric_limits<uint32_t>::max())
208 delete static_cast<std::vector<uint32_t> *>(OffsetCache);
209 else
210 delete static_cast<std::vector<uint64_t> *>(OffsetCache);
211 OffsetCache = nullptr;
212 }
213}
214
215std::pair<unsigned, unsigned>
216SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
217 if (!BufferID)
218 BufferID = FindBufferContainingLoc(Loc);
219 assert(BufferID && "Invalid location!");
220
221 auto &SB = getBufferInfo(BufferID);
222 const char *Ptr = Loc.getPointer();
223
224 unsigned LineNo = SB.getLineNumber(Ptr);
225 const char *BufStart = SB.Buffer->getBufferStart();
226 size_t NewlineOffs = StringRef(BufStart, Ptr - BufStart).find_last_of("\n\r");
227 if (NewlineOffs == StringRef::npos)
228 NewlineOffs = ~(size_t)0;
229 return {LineNo, Ptr - BufStart - NewlineOffs};
230}
231
232// FIXME: Note that the formatting of source locations is spread between
233// multiple functions, some in SourceMgr and some in SMDiagnostic. A better
234// solution would be a general-purpose source location formatter
235// in one of those two classes, or possibly in SMLoc.
236
237/// Get a string with the source location formatted in the standard
238/// style, but without the line offset. If \p IncludePath is true, the path
239/// is included. If false, only the file name and extension are included.
241 bool IncludePath) const {
242 auto BufferID = FindBufferContainingLoc(Loc);
243 assert(BufferID && "Invalid location!");
244 auto FileSpec = getBufferInfo(BufferID).Buffer->getBufferIdentifier();
245
246 if (IncludePath) {
247 return FileSpec.str() + ":" + std::to_string(FindLineNumber(Loc, BufferID));
248 } else {
249 auto I = FileSpec.find_last_of("/\\");
250 I = (I == FileSpec.size()) ? 0 : (I + 1);
251 return FileSpec.substr(I).str() + ":" +
252 std::to_string(FindLineNumber(Loc, BufferID));
253 }
254}
255
256/// Given a line and column number in a mapped buffer, turn it into an SMLoc.
257/// This will return a null SMLoc if the line/column location is invalid.
258SMLoc SourceMgr::FindLocForLineAndColumn(unsigned BufferID, unsigned LineNo,
259 unsigned ColNo) {
260 auto &SB = getBufferInfo(BufferID);
261 const char *Ptr = SB.getPointerForLineNumber(LineNo);
262 if (!Ptr)
263 return SMLoc();
264
265 // We start counting line and column numbers from 1.
266 if (ColNo != 0)
267 --ColNo;
268
269 // If we have a column number, validate it.
270 if (ColNo) {
271 // Make sure the location is within the current line.
272 if (Ptr + ColNo > SB.Buffer->getBufferEnd())
273 return SMLoc();
274
275 // Make sure there is no newline in the way.
276 if (StringRef(Ptr, ColNo).find_first_of("\n\r") != StringRef::npos)
277 return SMLoc();
278
279 Ptr += ColNo;
280 }
281
282 return SMLoc::getFromPointer(Ptr);
283}
284
285void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const {
286 if (IncludeLoc == SMLoc())
287 return; // Top of stack.
288
289 unsigned CurBuf = FindBufferContainingLoc(IncludeLoc);
290 assert(CurBuf && "Invalid or unspecified location!");
291
292 PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
293
294 OS << "Included from " << getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
295 << ":" << FindLineNumber(IncludeLoc, CurBuf) << ":\n";
296}
297
299 const Twine &Msg, ArrayRef<SMRange> Ranges,
300 ArrayRef<SMFixIt> FixIts) const {
301 // First thing to do: find the current buffer containing the specified
302 // location to pull out the source line.
304 std::pair<unsigned, unsigned> LineAndCol;
305 StringRef BufferID = "<unknown>";
306 StringRef LineStr;
307
308 if (Loc.isValid()) {
309 unsigned CurBuf = FindBufferContainingLoc(Loc);
310 assert(CurBuf && "Invalid or unspecified location!");
311
312 const MemoryBuffer *CurMB = getMemoryBuffer(CurBuf);
313 BufferID = CurMB->getBufferIdentifier();
314
315 // Scan backward to find the start of the line.
316 const char *LineStart = Loc.getPointer();
317 const char *BufStart = CurMB->getBufferStart();
318 while (LineStart != BufStart && LineStart[-1] != '\n' &&
319 LineStart[-1] != '\r')
320 --LineStart;
321
322 // Get the end of the line.
323 const char *LineEnd = Loc.getPointer();
324 const char *BufEnd = CurMB->getBufferEnd();
325 while (LineEnd != BufEnd && LineEnd[0] != '\n' && LineEnd[0] != '\r')
326 ++LineEnd;
327 LineStr = StringRef(LineStart, LineEnd - LineStart);
328
329 // Convert any ranges to column ranges that only intersect the line of the
330 // location.
331 for (SMRange R : Ranges) {
332 if (!R.isValid())
333 continue;
334
335 // If the line doesn't contain any part of the range, then ignore it.
336 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
337 continue;
338
339 // Ignore pieces of the range that go onto other lines.
340 if (R.Start.getPointer() < LineStart)
341 R.Start = SMLoc::getFromPointer(LineStart);
342 if (R.End.getPointer() > LineEnd)
343 R.End = SMLoc::getFromPointer(LineEnd);
344
345 // Translate from SMLoc ranges to column ranges.
346 // FIXME: Handle multibyte characters.
347 ColRanges.push_back(std::make_pair(R.Start.getPointer() - LineStart,
348 R.End.getPointer() - LineStart));
349 }
350
351 LineAndCol = getLineAndColumn(Loc, CurBuf);
352 }
353
354 return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first,
355 LineAndCol.second - 1, Kind, Msg.str(), LineStr,
356 ColRanges, FixIts);
357}
358
360 bool ShowColors) const {
361 // Report the message with the diagnostic handler if present.
362 if (DiagHandler) {
363 DiagHandler(Diagnostic, DiagContext);
364 return;
365 }
366
367 if (Diagnostic.getLoc().isValid()) {
368 unsigned CurBuf = FindBufferContainingLoc(Diagnostic.getLoc());
369 assert(CurBuf && "Invalid or unspecified location!");
370 PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
371 }
372
373 Diagnostic.print(nullptr, OS, ShowColors);
374}
375
377 SourceMgr::DiagKind Kind, const Twine &Msg,
379 bool ShowColors) const {
380 PrintMessage(OS, GetMessage(Loc, Kind, Msg, Ranges, FixIts), ShowColors);
381}
382
384 const Twine &Msg, ArrayRef<SMRange> Ranges,
385 ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
386 PrintMessage(errs(), Loc, Kind, Msg, Ranges, FixIts, ShowColors);
387}
388
389//===----------------------------------------------------------------------===//
390// SMFixIt Implementation
391//===----------------------------------------------------------------------===//
392
393SMFixIt::SMFixIt(SMRange R, const Twine &Replacement)
394 : Range(R), Text(Replacement.str()) {
395 assert(R.isValid());
396}
397
398//===----------------------------------------------------------------------===//
399// SMDiagnostic Implementation
400//===----------------------------------------------------------------------===//
401
403 int Col, SourceMgr::DiagKind Kind, StringRef Msg,
404 StringRef LineStr,
405 ArrayRef<std::pair<unsigned, unsigned>> Ranges,
406 ArrayRef<SMFixIt> Hints)
407 : SM(&sm), Loc(L), Filename(std::string(FN)), LineNo(Line), ColumnNo(Col),
408 Kind(Kind), Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
409 FixIts(Hints) {
410 llvm::sort(FixIts);
411}
412
413static void buildFixItLine(std::string &CaretLine, std::string &FixItLine,
414 ArrayRef<SMFixIt> FixIts,
415 ArrayRef<char> SourceLine) {
416 if (FixIts.empty())
417 return;
418
419 const char *LineStart = SourceLine.begin();
420 const char *LineEnd = SourceLine.end();
421
422 size_t PrevHintEndCol = 0;
423
424 for (const llvm::SMFixIt &Fixit : FixIts) {
425 // If the fixit contains a newline or tab, ignore it.
426 if (Fixit.getText().find_first_of("\n\r\t") != StringRef::npos)
427 continue;
428
429 SMRange R = Fixit.getRange();
430
431 // If the line doesn't contain any part of the range, then ignore it.
432 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
433 continue;
434
435 // Translate from SMLoc to column.
436 // Ignore pieces of the range that go onto other lines.
437 // FIXME: Handle multibyte characters in the source line.
438 unsigned FirstCol;
439 if (R.Start.getPointer() < LineStart)
440 FirstCol = 0;
441 else
442 FirstCol = R.Start.getPointer() - LineStart;
443
444 // If we inserted a long previous hint, push this one forwards, and add
445 // an extra space to show that this is not part of the previous
446 // completion. This is sort of the best we can do when two hints appear
447 // to overlap.
448 //
449 // Note that if this hint is located immediately after the previous
450 // hint, no space will be added, since the location is more important.
451 unsigned HintCol = FirstCol;
452 if (HintCol < PrevHintEndCol)
453 HintCol = PrevHintEndCol + 1;
454
455 // FIXME: This assertion is intended to catch unintended use of multibyte
456 // characters in fixits. If we decide to do this, we'll have to track
457 // separate byte widths for the source and fixit lines.
458 assert((size_t)sys::locale::columnWidth(Fixit.getText()) ==
459 Fixit.getText().size());
460
461 // This relies on one byte per column in our fixit hints.
462 unsigned LastColumnModified = HintCol + Fixit.getText().size();
463 if (LastColumnModified > FixItLine.size())
464 FixItLine.resize(LastColumnModified, ' ');
465
466 llvm::copy(Fixit.getText(), FixItLine.begin() + HintCol);
467
468 PrevHintEndCol = LastColumnModified;
469
470 // For replacements, mark the removal range with '~'.
471 // FIXME: Handle multibyte characters in the source line.
472 unsigned LastCol;
473 if (R.End.getPointer() >= LineEnd)
474 LastCol = LineEnd - LineStart;
475 else
476 LastCol = R.End.getPointer() - LineStart;
477
478 std::fill(&CaretLine[FirstCol], &CaretLine[LastCol], '~');
479 }
480}
481
482static void printSourceLine(raw_ostream &S, StringRef LineContents) {
483 // Print out the source line one character at a time, so we can expand tabs.
484 for (unsigned i = 0, e = LineContents.size(), OutCol = 0; i != e; ++i) {
485 size_t NextTab = LineContents.find('\t', i);
486 // If there were no tabs left, print the rest, we are done.
487 if (NextTab == StringRef::npos) {
488 S << LineContents.drop_front(i);
489 break;
490 }
491
492 // Otherwise, print from i to NextTab.
493 S << LineContents.slice(i, NextTab);
494 OutCol += NextTab - i;
495 i = NextTab;
496
497 // If we have a tab, emit at least one space, then round up to 8 columns.
498 do {
499 S << ' ';
500 ++OutCol;
501 } while ((OutCol % TabStop) != 0);
502 }
503 S << '\n';
504}
505
506static bool isNonASCII(char c) { return c & 0x80; }
507
508void SMDiagnostic::print(const char *ProgName, raw_ostream &OS, bool ShowColors,
509 bool ShowKindLabel, bool ShowLocation) const {
510 ColorMode Mode = ShowColors ? ColorMode::Auto : ColorMode::Disable;
511
512 {
513 WithColor S(OS, raw_ostream::SAVEDCOLOR, true, false, Mode);
514
515 if (ProgName && ProgName[0])
516 S << ProgName << ": ";
517
518 if (ShowLocation && !Filename.empty()) {
519 if (Filename == "-")
520 S << "<stdin>";
521 else
522 S << Filename;
523
524 if (LineNo != -1) {
525 S << ':' << LineNo;
526 if (ColumnNo != -1)
527 S << ':' << (ColumnNo + 1);
528 }
529 S << ": ";
530 }
531 }
532
533 if (ShowKindLabel) {
534 switch (Kind) {
536 WithColor::error(OS, "", !ShowColors);
537 break;
539 WithColor::warning(OS, "", !ShowColors);
540 break;
542 WithColor::note(OS, "", !ShowColors);
543 break;
545 WithColor::remark(OS, "", !ShowColors);
546 break;
547 }
548 }
549
550 WithColor(OS, raw_ostream::SAVEDCOLOR, true, false, Mode) << Message << '\n';
551
552 if (LineNo == -1 || ColumnNo == -1)
553 return;
554
555 // FIXME: If there are multibyte or multi-column characters in the source, all
556 // our ranges will be wrong. To do this properly, we'll need a byte-to-column
557 // map like Clang's TextDiagnostic. For now, we'll just handle tabs by
558 // expanding them later, and bail out rather than show incorrect ranges and
559 // misaligned fixits for any other odd characters.
560 if (any_of(LineContents, isNonASCII)) {
561 printSourceLine(OS, LineContents);
562 return;
563 }
564 size_t NumColumns = LineContents.size();
565
566 // Build the line with the caret and ranges.
567 std::string CaretLine(NumColumns + 1, ' ');
568
569 // Expand any ranges.
570 for (const std::pair<unsigned, unsigned> &R : Ranges)
571 std::fill(&CaretLine[R.first],
572 &CaretLine[std::min((size_t)R.second, CaretLine.size())], '~');
573
574 // Add any fix-its.
575 // FIXME: Find the beginning of the line properly for multibyte characters.
576 std::string FixItInsertionLine;
577 buildFixItLine(CaretLine, FixItInsertionLine, FixIts,
578 ArrayRef(Loc.getPointer() - ColumnNo, LineContents.size()));
579
580 // Finally, plop on the caret.
581 if (unsigned(ColumnNo) <= NumColumns)
582 CaretLine[ColumnNo] = '^';
583 else
584 CaretLine[NumColumns] = '^';
585
586 // ... and remove trailing whitespace so the output doesn't wrap for it. We
587 // know that the line isn't completely empty because it has the caret in it at
588 // least.
589 CaretLine.erase(CaretLine.find_last_not_of(' ') + 1);
590
591 printSourceLine(OS, LineContents);
592
593 {
594 ColorMode Mode = ShowColors ? ColorMode::Auto : ColorMode::Disable;
595 WithColor S(OS, raw_ostream::GREEN, true, false, Mode);
596
597 // Print out the caret line, matching tabs in the source line.
598 for (unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) {
599 if (i >= LineContents.size() || LineContents[i] != '\t') {
600 S << CaretLine[i];
601 ++OutCol;
602 continue;
603 }
604
605 // Okay, we have a tab. Insert the appropriate number of characters.
606 do {
607 S << CaretLine[i];
608 ++OutCol;
609 } while ((OutCol % TabStop) != 0);
610 }
611 S << '\n';
612 }
613
614 // Print out the replacement line, matching tabs in the source line.
615 if (FixItInsertionLine.empty())
616 return;
617
618 for (size_t i = 0, e = FixItInsertionLine.size(), OutCol = 0; i < e; ++i) {
619 if (i >= LineContents.size() || LineContents[i] != '\t') {
620 OS << FixItInsertionLine[i];
621 ++OutCol;
622 continue;
623 }
624
625 // Okay, we have a tab. Insert the appropriate number of characters.
626 do {
627 OS << FixItInsertionLine[i];
628 // FIXME: This is trying not to break up replacements, but then to re-sync
629 // with the tabs between replacements. This will fail, though, if two
630 // fix-it replacements are exactly adjacent, or if a fix-it contains a
631 // space. Really we should be precomputing column widths, which we'll
632 // need anyway for multibyte chars.
633 if (FixItInsertionLine[i] != ' ')
634 ++i;
635 ++OutCol;
636 } while (((OutCol % TabStop) != 0) && i != e);
637 }
638 OS << '\n';
639}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides ErrorOr<T> smart pointer.
#define I(x, y, z)
Definition MD5.cpp:57
#define T
static constexpr StringLiteral Filename
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
iterator begin() const
Definition ArrayRef.h:129
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
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
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
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:298
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:324
Represents a single fixit, a replacement of one range of text with another.
Definition SourceMgr.h:273
LLVM_ABI SMFixIt(SMRange R, const Twine &Replacement)
Represents a location in source code.
Definition SMLoc.h:22
static SMLoc getFromPointer(const char *Ptr)
Definition SMLoc.h:35
constexpr bool isValid() const
Definition SMLoc.h:28
Represents a range in source code.
Definition SMLoc.h:47
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
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.
LLVM_ABI 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.
LLVM_ABI 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:97
LLVM_ABI IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
Definition SourceMgr.cpp:50
LLVM_ABI ErrorOr< std::unique_ptr< MemoryBuffer > > OpenIncludeFile(const std::string &Filename, std::string &IncludedFile, bool RequiresNullTerminator=true)
Search for a file with the specified name in the current directory or in one of the IncludeDirs,...
Definition SourceMgr.cpp:70
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:213
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.
LLVM_ABI ~SourceMgr()
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
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
static constexpr size_t npos
Definition StringRef.h:58
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition StringRef.h:629
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition StringRef.h:714
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
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:421
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition StringRef.h:290
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 GREEN
static constexpr Colors SAVEDCOLOR
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:457
This is an optimization pass for GlobalISel generic memory operations.
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:1745
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1635
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:2051
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
Definition STLExtras.h:1884
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:1916
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:874
#define N