LLVM 22.0.0git
SourceMgr.cpp
Go to the documentation of this file.
1//===- SourceMgr.cpp - Manager for Simple Source Buffers & Diagnostics ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the SourceMgr class. This class is used as a simple
10// substrate for diagnostics, #include handling, and other low level things for
11// simple parsers.
12//
13//===----------------------------------------------------------------------===//
14
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/STLExtras.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/ADT/Twine.h"
23#include "llvm/Support/Locale.h"
25#include "llvm/Support/Path.h"
26#include "llvm/Support/SMLoc.h"
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 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) {
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, bool ShowLocation) 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 (ShowLocation && !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}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides ErrorOr<T> smart pointer.
#define I(x, y, z)
Definition MD5.cpp:58
#define T
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallString class.
This file defines the SmallVector class.
static const size_t TabStop
Definition SourceMgr.cpp:39
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)
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:136
iterator begin() const
Definition ArrayRef.h:135
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:142
Represents either an error or a value T.
Definition ErrorOr.h:56
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:282
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:308
Represents a single fixit, a replacement of one range of text with another.
Definition SourceMgr.h:257
LLVM_ABI SMFixIt(SMRange R, const Twine &Replacement)
Represents a location in source code.
Definition SMLoc.h:23
static SMLoc getFromPointer(const char *Ptr)
Definition SMLoc.h:36
constexpr bool isValid() const
Definition SMLoc.h:29
Represents a range in source code.
Definition SMLoc.h:48
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
Definition SourceMgr.h:32
LLVM_ABI ErrorOr< std::unique_ptr< MemoryBuffer > > OpenIncludeFile(const std::string &Filename, std::string &IncludedFile)
Search for a file with the specified name in the current directory or in one of the IncludeDirs,...
Definition SourceMgr.cpp:53
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.
const MemoryBuffer * getMemoryBuffer(unsigned i) const
Definition SourceMgr.h:126
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 unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
Definition SourceMgr.cpp:73
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:41
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const
Find the line number for the specified location in the specified file.
Definition SourceMgr.h:197
LLVM_ABI std::string getFormattedLocationNoOffset(SMLoc Loc, bool IncludePath=false) const
Get a string with the SMLoc filename and line number formatted in the standard style.
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
Definition SourceMgr.h:145
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:121
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition StringRef.h:619
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition StringRef.h:694
constexpr size_t size() const
size - Get the string size.
Definition StringRef.h:154
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:409
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition StringRef.h:301
static constexpr size_t npos
Definition StringRef.h:57
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
Definition Twine.cpp:17
An RAII object that temporarily switches an output stream to a specific color.
Definition WithColor.h:54
static LLVM_ABI raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
Definition WithColor.cpp:85
static LLVM_ABI raw_ostream & error()
Convenience method for printing "error: " to stderr.
Definition WithColor.cpp:83
static LLVM_ABI raw_ostream & note()
Convenience method for printing "note: " to stderr.
Definition WithColor.cpp:87
static LLVM_ABI raw_ostream & remark()
Convenience method for printing "remark: " to stderr.
Definition WithColor.cpp:89
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
static constexpr Colors SAVEDCOLOR
static constexpr Colors GREEN
Offsets
Offsets in bytes from the start of the input buffer.
LLVM_ABI int columnWidth(StringRef s)
Definition Locale.cpp:9
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition Path.cpp:456
This is an optimization pass for GlobalISel generic memory operations.
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:1712
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1624
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:1974
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
Definition STLExtras.h:1815
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:1847
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:851
#define N