55 this->FS = std::move(FS);
60 std::string &IncludedFile) {
71 std::string &IncludedFile) {
76 FS->getBufferForFile(Filename);
80 for (
unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBufOrErr;
82 Buffer = IncludeDirectories[i];
84 NewBufOrErr = FS->getBufferForFile(Buffer);
88 IncludedFile =
static_cast<std::string
>(Buffer);
94 for (
unsigned i = 0, e = Buffers.size(); i != e; ++i)
95 if (
Loc.getPointer() >= Buffers[i].Buffer->getBufferStart() &&
98 Loc.getPointer() <= Buffers[i].Buffer->getBufferEnd())
107 return *
static_cast<std::vector<T> *
>(OffsetCache);
110 auto *Offsets =
new std::vector<T>();
112 assert(Sz <= std::numeric_limits<T>::max());
114 for (
size_t N = 0;
N < Sz; ++
N) {
116 Offsets->push_back(
static_cast<T>(
N));
119 OffsetCache = Offsets;
124unsigned SourceMgr::SrcBuffer::getLineNumberSpecialized(
const char *
Ptr)
const {
128 const char *BufStart = Buffer->getBufferStart();
130 ptrdiff_t PtrDiff =
Ptr - BufStart;
132 static_cast<size_t>(PtrDiff) <= std::numeric_limits<T>::max());
133 T PtrOffset =
static_cast<T>(PtrDiff);
142unsigned SourceMgr::SrcBuffer::getLineNumber(
const char *
Ptr)
const {
143 size_t Sz = Buffer->getBufferSize();
144 if (Sz <= std::numeric_limits<uint8_t>::max())
145 return getLineNumberSpecialized<uint8_t>(
Ptr);
146 else if (Sz <= std::numeric_limits<uint16_t>::max())
147 return getLineNumberSpecialized<uint16_t>(
Ptr);
148 else if (Sz <= std::numeric_limits<uint32_t>::max())
149 return getLineNumberSpecialized<uint32_t>(
Ptr);
151 return getLineNumberSpecialized<uint64_t>(
Ptr);
155const char *SourceMgr::SrcBuffer::getPointerForLineNumberSpecialized(
156 unsigned LineNo)
const {
164 const char *BufStart = Buffer->getBufferStart();
172 return BufStart +
Offsets[LineNo - 1] + 1;
178SourceMgr::SrcBuffer::getPointerForLineNumber(
unsigned LineNo)
const {
179 size_t Sz = Buffer->getBufferSize();
180 if (Sz <= std::numeric_limits<uint8_t>::max())
181 return getPointerForLineNumberSpecialized<uint8_t>(LineNo);
182 else if (Sz <= std::numeric_limits<uint16_t>::max())
183 return getPointerForLineNumberSpecialized<uint16_t>(LineNo);
184 else if (Sz <= std::numeric_limits<uint32_t>::max())
185 return getPointerForLineNumberSpecialized<uint32_t>(LineNo);
187 return getPointerForLineNumberSpecialized<uint64_t>(LineNo);
190SourceMgr::SrcBuffer::SrcBuffer(SourceMgr::SrcBuffer &&
Other)
191 : Buffer(std::
move(
Other.Buffer)), OffsetCache(
Other.OffsetCache),
192 IncludeLoc(
Other.IncludeLoc) {
193 Other.OffsetCache =
nullptr;
196SourceMgr::SrcBuffer::~SrcBuffer() {
198 size_t Sz = Buffer->getBufferSize();
199 if (Sz <= std::numeric_limits<uint8_t>::max())
200 delete static_cast<std::vector<uint8_t> *
>(OffsetCache);
201 else if (Sz <= std::numeric_limits<uint16_t>::max())
202 delete static_cast<std::vector<uint16_t> *
>(OffsetCache);
203 else if (Sz <= std::numeric_limits<uint32_t>::max())
204 delete static_cast<std::vector<uint32_t> *
>(OffsetCache);
206 delete static_cast<std::vector<uint64_t> *
>(OffsetCache);
207 OffsetCache =
nullptr;
211std::pair<unsigned, unsigned>
215 assert(BufferID &&
"Invalid location!");
218 const char *
Ptr =
Loc.getPointer();
220 unsigned LineNo = SB.getLineNumber(
Ptr);
221 const char *BufStart = SB.Buffer->getBufferStart();
224 NewlineOffs = ~(size_t)0;
225 return {LineNo,
Ptr - BufStart - NewlineOffs};
237 bool IncludePath)
const {
239 assert(BufferID &&
"Invalid location!");
240 auto FileSpec =
getBufferInfo(BufferID).Buffer->getBufferIdentifier();
245 auto I = FileSpec.find_last_of(
"/\\");
246 I = (
I == FileSpec.size()) ? 0 : (
I + 1);
247 return FileSpec.substr(
I).str() +
":" +
257 const char *
Ptr = SB.getPointerForLineNumber(LineNo);
268 if (
Ptr + ColNo > SB.Buffer->getBufferEnd())
282 if (IncludeLoc ==
SMLoc())
286 assert(CurBuf &&
"Invalid or unspecified location!");
290 OS <<
"Included from " <<
getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
300 std::pair<unsigned, unsigned> LineAndCol;
306 assert(CurBuf &&
"Invalid or unspecified location!");
312 const char *LineStart =
Loc.getPointer();
314 while (LineStart != BufStart && LineStart[-1] !=
'\n' &&
315 LineStart[-1] !=
'\r')
319 const char *LineEnd =
Loc.getPointer();
321 while (LineEnd != BufEnd && LineEnd[0] !=
'\n' && LineEnd[0] !=
'\r')
323 LineStr =
StringRef(LineStart, LineEnd - LineStart);
332 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
336 if (R.Start.getPointer() < LineStart)
338 if (R.End.getPointer() > LineEnd)
343 ColRanges.
push_back(std::make_pair(R.Start.getPointer() - LineStart,
344 R.End.getPointer() - LineStart));
351 LineAndCol.second - 1, Kind, Msg.
str(), LineStr,
356 bool ShowColors)
const {
359 DiagHandler(Diagnostic, DiagContext);
365 assert(CurBuf &&
"Invalid or unspecified location!");
369 Diagnostic.
print(
nullptr, OS, ShowColors);
375 bool ShowColors)
const {
390 : Range(R), Text(Replacement.str()) {
401 ArrayRef<std::pair<unsigned, unsigned>> Ranges,
403 : SM(&sm), Loc(L), Filename(
std::string(FN)), LineNo(Line), ColumnNo(Col),
404 Kind(Kind), Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
415 const char *LineStart = SourceLine.
begin();
416 const char *LineEnd = SourceLine.
end();
418 size_t PrevHintEndCol = 0;
428 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
435 if (R.Start.getPointer() < LineStart)
438 FirstCol = R.Start.getPointer() - LineStart;
447 unsigned HintCol = FirstCol;
448 if (HintCol < PrevHintEndCol)
449 HintCol = PrevHintEndCol + 1;
455 Fixit.getText().size());
458 unsigned LastColumnModified = HintCol + Fixit.getText().size();
459 if (LastColumnModified > FixItLine.size())
460 FixItLine.resize(LastColumnModified,
' ');
462 llvm::copy(Fixit.getText(), FixItLine.begin() + HintCol);
464 PrevHintEndCol = LastColumnModified;
469 if (R.End.getPointer() >= LineEnd)
470 LastCol = LineEnd - LineStart;
472 LastCol = R.End.getPointer() - LineStart;
474 std::fill(&CaretLine[FirstCol], &CaretLine[LastCol],
'~');
480 for (
unsigned i = 0, e = LineContents.
size(), OutCol = 0; i != e; ++i) {
481 size_t NextTab = LineContents.
find(
'\t', i);
489 S << LineContents.
slice(i, NextTab);
490 OutCol += NextTab - i;
497 }
while ((OutCol %
TabStop) != 0);
505 bool ShowKindLabel,
bool ShowLocation)
const {
511 if (ProgName && ProgName[0])
512 S << ProgName <<
": ";
514 if (ShowLocation && !Filename.empty()) {
523 S <<
':' << (ColumnNo + 1);
548 if (LineNo == -1 || ColumnNo == -1)
560 size_t NumColumns = LineContents.size();
563 std::string CaretLine(NumColumns + 1,
' ');
566 for (
const std::pair<unsigned, unsigned> &R : Ranges)
567 std::fill(&CaretLine[R.first],
568 &CaretLine[std::min((
size_t)R.second, CaretLine.size())],
'~');
572 std::string FixItInsertionLine;
574 ArrayRef(Loc.getPointer() - ColumnNo, LineContents.size()));
577 if (
unsigned(ColumnNo) <= NumColumns)
578 CaretLine[ColumnNo] =
'^';
580 CaretLine[NumColumns] =
'^';
585 CaretLine.erase(CaretLine.find_last_not_of(
' ') + 1);
594 for (
unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) {
595 if (i >= LineContents.size() || LineContents[i] !=
'\t') {
605 }
while ((OutCol %
TabStop) != 0);
611 if (FixItInsertionLine.empty())
614 for (
size_t i = 0, e = FixItInsertionLine.size(), OutCol = 0; i < e; ++i) {
615 if (i >= LineContents.size() || LineContents[i] !=
'\t') {
616 OS << FixItInsertionLine[i];
623 OS << FixItInsertionLine[i];
629 if (FixItInsertionLine[i] !=
' ')
632 }
while (((OutCol %
TabStop) != 0) && i != e);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides ErrorOr<T> smart pointer.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - 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
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 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,...
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.
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.
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.
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.
IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
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
StringRef - Represent a constant reference to a string, i.e.
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
size - Get the string size.
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.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static constexpr size_t npos
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
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 SAVEDCOLOR
static constexpr Colors GREEN
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.
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
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.