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