55 this->FS = std::move(FS);
60 std::string &IncludedFile) {
71 std::string &IncludedFile,
72 bool RequiresNullTerminator) {
73 auto GetFile = [
this, RequiresNullTerminator](
StringRef Path) {
74 return FS ? FS->getBufferForFile(Path, -1,
75 RequiresNullTerminator)
77 RequiresNullTerminator);
84 for (
unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBufOrErr;
86 Buffer = IncludeDirectories[i];
88 NewBufOrErr = GetFile(Buffer);
92 IncludedFile =
static_cast<std::string
>(Buffer);
98 for (
unsigned i = 0, e = Buffers.size(); i != e; ++i)
99 if (
Loc.getPointer() >= Buffers[i].Buffer->getBufferStart() &&
102 Loc.getPointer() <= Buffers[i].Buffer->getBufferEnd())
111 return *
static_cast<std::vector<T> *
>(OffsetCache);
114 auto *Offsets =
new std::vector<T>();
116 assert(Sz <= std::numeric_limits<T>::max());
118 for (
size_t N = 0;
N < Sz; ++
N) {
120 Offsets->push_back(
static_cast<T>(
N));
123 OffsetCache = Offsets;
128std::pair<unsigned, unsigned>
129SourceMgr::SrcBuffer::getLineAndColumnSpecialized(
const char *Ptr)
const {
133 const char *BufStart = Buffer->getBufferStart();
134 assert(Ptr >= BufStart && Ptr <= Buffer->getBufferEnd());
135 ptrdiff_t PtrDiff = Ptr - BufStart;
137 static_cast<size_t>(PtrDiff) <= std::numeric_limits<T>::max());
138 T PtrOffset =
static_cast<T>(PtrDiff);
143 unsigned LineNo =
I -
Offsets.begin() + 1;
147 T LineStartOffs = (
I ==
Offsets.begin()) ? 0 : (
I[-1] + 1);
148 unsigned ColNo = PtrOffset - LineStartOffs + 1;
149 return {LineNo, ColNo};
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);
167const char *SourceMgr::SrcBuffer::getPointerForLineNumberSpecialized(
168 unsigned LineNo)
const {
176 const char *BufStart = Buffer->getBufferStart();
184 return BufStart +
Offsets[LineNo - 1] + 1;
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);
199 return getPointerForLineNumberSpecialized<uint64_t>(LineNo);
202SourceMgr::SrcBuffer::SrcBuffer(SourceMgr::SrcBuffer &&
Other)
203 : Buffer(std::
move(
Other.Buffer)), OffsetCache(
Other.OffsetCache),
204 IncludeLoc(
Other.IncludeLoc) {
205 Other.OffsetCache =
nullptr;
208SourceMgr::SrcBuffer::~SrcBuffer() {
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);
218 delete static_cast<std::vector<uint64_t> *
>(OffsetCache);
219 OffsetCache =
nullptr;
223std::pair<unsigned, unsigned>
227 assert(BufferID &&
"Invalid location!");
230 const char *Ptr =
Loc.getPointer();
232 return SB.getLineAndColumn(Ptr);
244 bool IncludePath)
const {
246 assert(BufferID &&
"Invalid location!");
247 auto FileSpec =
getBufferInfo(BufferID).Buffer->getBufferIdentifier();
252 auto I = FileSpec.find_last_of(
"/\\");
253 I = (
I == FileSpec.size()) ? 0 : (
I + 1);
254 return FileSpec.substr(
I).str() +
":" +
264 const char *Ptr = SB.getPointerForLineNumber(LineNo);
275 if (Ptr + ColNo > SB.Buffer->getBufferEnd())
289 if (IncludeLoc ==
SMLoc())
293 assert(CurBuf &&
"Invalid or unspecified location!");
297 OS <<
"Included from " <<
getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
319 std::pair<unsigned, unsigned> LineAndCol;
325 assert(CurBuf &&
"Invalid or unspecified location!");
331 const char *LineStart =
Loc.getPointer();
333 while (LineStart != BufStart && LineStart[-1] !=
'\n' &&
334 LineStart[-1] !=
'\r')
338 const char *LineEnd =
Loc.getPointer();
340 while (LineEnd != BufEnd && LineEnd[0] !=
'\n' && LineEnd[0] !=
'\r')
342 LineStr =
StringRef(LineStart, LineEnd - LineStart);
351 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
355 if (R.Start.getPointer() < LineStart)
357 if (R.End.getPointer() > LineEnd)
362 ColRanges.
push_back(std::make_pair(R.Start.getPointer() - LineStart,
363 R.End.getPointer() - LineStart));
370 LineAndCol.second - 1, Kind,
Msg.str(), LineStr,
375 bool ShowColors)
const {
378 DiagHandler(Diagnostic, DiagContext);
384 assert(CurBuf &&
"Invalid or unspecified location!");
388 Diagnostic.
print(
nullptr, OS, ShowColors);
394 bool ShowColors)
const {
409 : Range(R), Text(Replacement.str()) {
420 ArrayRef<std::pair<unsigned, unsigned>> Ranges,
422 : SM(&sm), Loc(L), Filename(
std::string(FN)), LineNo(Line), ColumnNo(Col),
423 Kind(Kind), Message(
Msg), LineContents(LineStr), Ranges(Ranges.vec()),
434 const char *LineStart = SourceLine.
begin();
435 const char *LineEnd = SourceLine.
end();
437 size_t PrevHintEndCol = 0;
447 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
454 if (R.Start.getPointer() < LineStart)
457 FirstCol = R.Start.getPointer() - LineStart;
466 unsigned HintCol = FirstCol;
467 if (HintCol < PrevHintEndCol)
468 HintCol = PrevHintEndCol + 1;
474 Fixit.getText().size());
477 unsigned LastColumnModified = HintCol + Fixit.getText().size();
478 if (LastColumnModified > FixItLine.size())
479 FixItLine.resize(LastColumnModified,
' ');
481 llvm::copy(Fixit.getText(), FixItLine.begin() + HintCol);
483 PrevHintEndCol = LastColumnModified;
488 if (R.End.getPointer() >= LineEnd)
489 LastCol = LineEnd - LineStart;
491 LastCol = R.End.getPointer() - LineStart;
493 std::fill(&CaretLine[FirstCol], &CaretLine[LastCol],
'~');
499 for (
unsigned i = 0, e = LineContents.
size(), OutCol = 0; i != e; ++i) {
500 size_t NextTab = LineContents.
find(
'\t', i);
508 S << LineContents.
slice(i, NextTab);
509 OutCol += NextTab - i;
516 }
while ((OutCol %
TabStop) != 0);
524 bool ShowKindLabel,
bool ShowLocation)
const {
530 if (ProgName && ProgName[0])
531 S << ProgName <<
": ";
533 if (ShowLocation && !Filename.empty()) {
542 S <<
':' << (ColumnNo + 1);
567 if (LineNo == -1 || ColumnNo == -1)
579 size_t NumColumns = LineContents.size();
582 std::string CaretLine(NumColumns + 1,
' ');
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())],
'~');
591 std::string FixItInsertionLine;
593 ArrayRef(Loc.getPointer() - ColumnNo, LineContents.size()));
596 if (
unsigned(ColumnNo) <= NumColumns)
597 CaretLine[ColumnNo] =
'^';
599 CaretLine[NumColumns] =
'^';
604 CaretLine.erase(CaretLine.find_last_not_of(
' ') + 1);
613 for (
unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) {
614 if (i >= LineContents.size() || LineContents[i] !=
'\t') {
624 }
while ((OutCol %
TabStop) != 0);
630 if (FixItInsertionLine.empty())
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];
642 OS << FixItInsertionLine[i];
648 if (FixItInsertionLine[i] !=
' ')
651 }
while (((OutCol %
TabStop) != 0) && i != e);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides ErrorOr<T> smart pointer.
static constexpr StringLiteral Filename
This file defines the SmallString class.
This file defines the SmallVector class.
static const size_t TabStop
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),...
bool empty() const
Check if the array is empty.
Represents either an error or a value T.
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...
LLVM_ABI void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true, bool ShowLocation=true) const
Represents a single fixit, a replacement of one range of text with another.
LLVM_ABI SMFixIt(SMRange R, const Twine &Replacement)
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr bool isValid() const
Represents a range in source code.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
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.
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
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)
const MemoryBuffer * getMemoryBuffer(unsigned i) const
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
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.
LLVM_ABI IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
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,...
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.
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const
Find the line number for the specified location in the specified file.
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.
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
Represent a constant reference to a string, i.e.
static constexpr size_t npos
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
Get the string size.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
An RAII object that temporarily switches an output stream to a specific color.
static LLVM_ABI raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
static LLVM_ABI raw_ostream & error()
Convenience method for printing "error: " to stderr.
static LLVM_ABI raw_ostream & note()
Convenience method for printing "note: " to stderr.
static LLVM_ABI raw_ostream & remark()
Convenience method for printing "remark: " to stderr.
This class implements an extremely fast bulk output stream that can only output to a stream.
static constexpr Colors GREEN
static constexpr Colors SAVEDCOLOR
LLVM_ABI int columnWidth(StringRef s)
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
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.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI 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...
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
@ Auto
Determine whether to use color based on the command line argument and the raw_ostream.
Implement std::hash so that hash_code can be used in STL containers.