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