LLVM 24.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 raw_ostream &OS) const {
303 if (!Loc.isValid())
304 return;
305 unsigned DiagCurBuffer = FindBufferContainingLoc(Loc);
306 if (DiagCurBuffer && DiagCurBuffer != getMainFileID()) {
307 SMLoc ParentIncludeLoc = getParentIncludeLoc(DiagCurBuffer);
308 // Ignore macro instantiation buffers to avoid redundant include stacks.
309 PrintIncludeStack(ParentIncludeLoc, OS);
310 }
311}
312
314 const Twine &Msg, ArrayRef<SMRange> Ranges,
315 ArrayRef<SMFixIt> FixIts) const {
316 // First thing to do: find the current buffer containing the specified
317 // location to pull out the source line.
319 std::pair<unsigned, unsigned> LineAndCol;
320 StringRef BufferID = "<unknown>";
321 StringRef LineStr;
322
323 if (Loc.isValid()) {
324 unsigned CurBuf = FindBufferContainingLoc(Loc);
325 assert(CurBuf && "Invalid or unspecified location!");
326
327 const MemoryBuffer *CurMB = getMemoryBuffer(CurBuf);
328 BufferID = CurMB->getBufferIdentifier();
329
330 // Scan backward to find the start of the line.
331 const char *LineStart = Loc.getPointer();
332 const char *BufStart = CurMB->getBufferStart();
333 while (LineStart != BufStart && LineStart[-1] != '\n' &&
334 LineStart[-1] != '\r')
335 --LineStart;
336
337 // Get the end of the line.
338 const char *LineEnd = Loc.getPointer();
339 const char *BufEnd = CurMB->getBufferEnd();
340 while (LineEnd != BufEnd && LineEnd[0] != '\n' && LineEnd[0] != '\r')
341 ++LineEnd;
342 LineStr = StringRef(LineStart, LineEnd - LineStart);
343
344 // Convert any ranges to column ranges that only intersect the line of the
345 // location.
346 for (SMRange R : Ranges) {
347 if (!R.isValid())
348 continue;
349
350 // If the line doesn't contain any part of the range, then ignore it.
351 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
352 continue;
353
354 // Ignore pieces of the range that go onto other lines.
355 if (R.Start.getPointer() < LineStart)
356 R.Start = SMLoc::getFromPointer(LineStart);
357 if (R.End.getPointer() > LineEnd)
358 R.End = SMLoc::getFromPointer(LineEnd);
359
360 // Translate from SMLoc ranges to column ranges.
361 // FIXME: Handle multibyte characters.
362 ColRanges.push_back(std::make_pair(R.Start.getPointer() - LineStart,
363 R.End.getPointer() - LineStart));
364 }
365
366 LineAndCol = getLineAndColumn(Loc, CurBuf);
367 }
368
369 return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first,
370 LineAndCol.second - 1, Kind, Msg.str(), LineStr,
371 ColRanges, FixIts);
372}
373
375 bool ShowColors) const {
376 // Report the message with the diagnostic handler if present.
377 if (DiagHandler) {
378 DiagHandler(Diagnostic, DiagContext);
379 return;
380 }
381
382 if (Diagnostic.getLoc().isValid()) {
383 unsigned CurBuf = FindBufferContainingLoc(Diagnostic.getLoc());
384 assert(CurBuf && "Invalid or unspecified location!");
385 PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
386 }
387
388 Diagnostic.print(nullptr, OS, ShowColors);
389}
390
392 SourceMgr::DiagKind Kind, const Twine &Msg,
394 bool ShowColors) const {
395 PrintMessage(OS, GetMessage(Loc, Kind, Msg, Ranges, FixIts), ShowColors);
396}
397
399 const Twine &Msg, ArrayRef<SMRange> Ranges,
400 ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
401 PrintMessage(errs(), Loc, Kind, Msg, Ranges, FixIts, ShowColors);
402}
403
404//===----------------------------------------------------------------------===//
405// SMFixIt Implementation
406//===----------------------------------------------------------------------===//
407
408SMFixIt::SMFixIt(SMRange R, const Twine &Replacement)
409 : Range(R), Text(Replacement.str()) {
410 assert(R.isValid());
411}
412
413//===----------------------------------------------------------------------===//
414// SMDiagnostic Implementation
415//===----------------------------------------------------------------------===//
416
418 int Col, SourceMgr::DiagKind Kind, StringRef Msg,
419 StringRef LineStr,
420 ArrayRef<std::pair<unsigned, unsigned>> Ranges,
421 ArrayRef<SMFixIt> Hints)
422 : SM(&sm), Loc(L), Filename(std::string(FN)), LineNo(Line), ColumnNo(Col),
423 Kind(Kind), Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
424 FixIts(Hints) {
425 llvm::sort(FixIts);
426}
427
428static void buildFixItLine(std::string &CaretLine, std::string &FixItLine,
429 ArrayRef<SMFixIt> FixIts,
430 ArrayRef<char> SourceLine) {
431 if (FixIts.empty())
432 return;
433
434 const char *LineStart = SourceLine.begin();
435 const char *LineEnd = SourceLine.end();
436
437 size_t PrevHintEndCol = 0;
438
439 for (const llvm::SMFixIt &Fixit : FixIts) {
440 // If the fixit contains a newline or tab, ignore it.
441 if (Fixit.getText().find_first_of("\n\r\t") != StringRef::npos)
442 continue;
443
444 SMRange R = Fixit.getRange();
445
446 // If the line doesn't contain any part of the range, then ignore it.
447 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
448 continue;
449
450 // Translate from SMLoc to column.
451 // Ignore pieces of the range that go onto other lines.
452 // FIXME: Handle multibyte characters in the source line.
453 unsigned FirstCol;
454 if (R.Start.getPointer() < LineStart)
455 FirstCol = 0;
456 else
457 FirstCol = R.Start.getPointer() - LineStart;
458
459 // If we inserted a long previous hint, push this one forwards, and add
460 // an extra space to show that this is not part of the previous
461 // completion. This is sort of the best we can do when two hints appear
462 // to overlap.
463 //
464 // Note that if this hint is located immediately after the previous
465 // hint, no space will be added, since the location is more important.
466 unsigned HintCol = FirstCol;
467 if (HintCol < PrevHintEndCol)
468 HintCol = PrevHintEndCol + 1;
469
470 // FIXME: This assertion is intended to catch unintended use of multibyte
471 // characters in fixits. If we decide to do this, we'll have to track
472 // separate byte widths for the source and fixit lines.
473 assert((size_t)sys::locale::columnWidth(Fixit.getText()) ==
474 Fixit.getText().size());
475
476 // This relies on one byte per column in our fixit hints.
477 unsigned LastColumnModified = HintCol + Fixit.getText().size();
478 if (LastColumnModified > FixItLine.size())
479 FixItLine.resize(LastColumnModified, ' ');
480
481 llvm::copy(Fixit.getText(), FixItLine.begin() + HintCol);
482
483 PrevHintEndCol = LastColumnModified;
484
485 // For replacements, mark the removal range with '~'.
486 // FIXME: Handle multibyte characters in the source line.
487 unsigned LastCol;
488 if (R.End.getPointer() >= LineEnd)
489 LastCol = LineEnd - LineStart;
490 else
491 LastCol = R.End.getPointer() - LineStart;
492
493 std::fill(&CaretLine[FirstCol], &CaretLine[LastCol], '~');
494 }
495}
496
497static void printSourceLine(raw_ostream &S, StringRef LineContents) {
498 // Print out the source line one character at a time, so we can expand tabs.
499 for (unsigned i = 0, e = LineContents.size(), OutCol = 0; i != e; ++i) {
500 size_t NextTab = LineContents.find('\t', i);
501 // If there were no tabs left, print the rest, we are done.
502 if (NextTab == StringRef::npos) {
503 S << LineContents.drop_front(i);
504 break;
505 }
506
507 // Otherwise, print from i to NextTab.
508 S << LineContents.slice(i, NextTab);
509 OutCol += NextTab - i;
510 i = NextTab;
511
512 // If we have a tab, emit at least one space, then round up to 8 columns.
513 do {
514 S << ' ';
515 ++OutCol;
516 } while ((OutCol % TabStop) != 0);
517 }
518 S << '\n';
519}
520
521static bool isNonASCII(char c) { return c & 0x80; }
522
523void SMDiagnostic::print(const char *ProgName, raw_ostream &OS, bool ShowColors,
524 bool ShowKindLabel, bool ShowLocation) const {
525 ColorMode Mode = ShowColors ? ColorMode::Auto : ColorMode::Disable;
526
527 {
528 WithColor S(OS, raw_ostream::SAVEDCOLOR, true, false, Mode);
529
530 if (ProgName && ProgName[0])
531 S << ProgName << ": ";
532
533 if (ShowLocation && !Filename.empty()) {
534 if (Filename == "-")
535 S << "<stdin>";
536 else
537 S << Filename;
538
539 if (LineNo != -1) {
540 S << ':' << LineNo;
541 if (ColumnNo != -1)
542 S << ':' << (ColumnNo + 1);
543 }
544 S << ": ";
545 }
546 }
547
548 if (ShowKindLabel) {
549 switch (Kind) {
551 WithColor::error(OS, "", !ShowColors);
552 break;
554 WithColor::warning(OS, "", !ShowColors);
555 break;
557 WithColor::note(OS, "", !ShowColors);
558 break;
560 WithColor::remark(OS, "", !ShowColors);
561 break;
562 }
563 }
564
565 WithColor(OS, raw_ostream::SAVEDCOLOR, true, false, Mode) << Message << '\n';
566
567 if (LineNo == -1 || ColumnNo == -1)
568 return;
569
570 // FIXME: If there are multibyte or multi-column characters in the source, all
571 // our ranges will be wrong. To do this properly, we'll need a byte-to-column
572 // map like Clang's TextDiagnostic. For now, we'll just handle tabs by
573 // expanding them later, and bail out rather than show incorrect ranges and
574 // misaligned fixits for any other odd characters.
575 if (any_of(LineContents, isNonASCII)) {
576 printSourceLine(OS, LineContents);
577 return;
578 }
579 size_t NumColumns = LineContents.size();
580
581 // Build the line with the caret and ranges.
582 std::string CaretLine(NumColumns + 1, ' ');
583
584 // Expand any ranges.
585 for (const std::pair<unsigned, unsigned> &R : Ranges)
586 std::fill(&CaretLine[R.first],
587 &CaretLine[std::min((size_t)R.second, CaretLine.size())], '~');
588
589 // Add any fix-its.
590 // FIXME: Find the beginning of the line properly for multibyte characters.
591 std::string FixItInsertionLine;
592 buildFixItLine(CaretLine, FixItInsertionLine, FixIts,
593 ArrayRef(Loc.getPointer() - ColumnNo, LineContents.size()));
594
595 // Finally, plop on the caret.
596 if (unsigned(ColumnNo) <= NumColumns)
597 CaretLine[ColumnNo] = '^';
598 else
599 CaretLine[NumColumns] = '^';
600
601 // ... and remove trailing whitespace so the output doesn't wrap for it. We
602 // know that the line isn't completely empty because it has the caret in it at
603 // least.
604 CaretLine.erase(CaretLine.find_last_not_of(' ') + 1);
605
606 printSourceLine(OS, LineContents);
607
608 {
609 ColorMode Mode = ShowColors ? ColorMode::Auto : ColorMode::Disable;
610 WithColor S(OS, raw_ostream::GREEN, true, false, Mode);
611
612 // Print out the caret line, matching tabs in the source line.
613 for (unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) {
614 if (i >= LineContents.size() || LineContents[i] != '\t') {
615 S << CaretLine[i];
616 ++OutCol;
617 continue;
618 }
619
620 // Okay, we have a tab. Insert the appropriate number of characters.
621 do {
622 S << CaretLine[i];
623 ++OutCol;
624 } while ((OutCol % TabStop) != 0);
625 }
626 S << '\n';
627 }
628
629 // Print out the replacement line, matching tabs in the source line.
630 if (FixItInsertionLine.empty())
631 return;
632
633 for (size_t i = 0, e = FixItInsertionLine.size(), OutCol = 0; i < e; ++i) {
634 if (i >= LineContents.size() || LineContents[i] != '\t') {
635 OS << FixItInsertionLine[i];
636 ++OutCol;
637 continue;
638 }
639
640 // Okay, we have a tab. Insert the appropriate number of characters.
641 do {
642 OS << FixItInsertionLine[i];
643 // FIXME: This is trying not to break up replacements, but then to re-sync
644 // with the tabs between replacements. This will fail, though, if two
645 // fix-it replacements are exactly adjacent, or if a fix-it contains a
646 // space. Really we should be precomputing column widths, which we'll
647 // need anyway for multibyte chars.
648 if (FixItInsertionLine[i] != ' ')
649 ++i;
650 ++OutCol;
651 } while (((OutCol % TabStop) != 0) && i != e);
652 }
653 OS << '\n';
654}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI
Definition Compiler.h:215
Provides ErrorOr<T> smart pointer.
#define I(x, y, z)
Definition MD5.cpp:57
#define T
static constexpr StringLiteral Filename
const char * Msg
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:308
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:334
Represents a single fixit, a replacement of one range of text with another.
Definition SourceMgr.h:283
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
LLVM_ABI void printIncludeStackForDiagnostic(SMLoc Loc, raw_ostream &OS) const
Prints the include stack of a buffer unless it is a macro instantiation buffer.
unsigned getMainFileID() const
Definition SourceMgr.h:151
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.
SMLoc getParentIncludeLoc(unsigned i) const
Definition SourceMgr.h:156
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:635
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition StringRef.h:720
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
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:86
static LLVM_ABI raw_ostream & error()
Convenience method for printing "error: " to stderr.
Definition WithColor.cpp:84
static LLVM_ABI raw_ostream & note()
Convenience method for printing "note: " to stderr.
Definition WithColor.cpp:88
static LLVM_ABI raw_ostream & remark()
Convenience method for printing "remark: " to stderr.
Definition WithColor.cpp:90
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:467
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:1746
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
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:2052
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
Definition STLExtras.h:1885
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:1917
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:878
#define N