43 std::string &IncludedFile) {
54 std::string &IncludedFile) {
60 for (
unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBufOrErr;
62 Buffer = IncludeDirectories[i];
68 IncludedFile =
static_cast<std::string
>(Buffer);
74 for (
unsigned i = 0, e = Buffers.size(); i != e; ++i)
75 if (Loc.
getPointer() >= Buffers[i].Buffer->getBufferStart() &&
78 Loc.
getPointer() <= Buffers[i].Buffer->getBufferEnd())
87 return *
static_cast<std::vector<T> *
>(OffsetCache);
90 auto *Offsets =
new std::vector<T>();
92 assert(Sz <= std::numeric_limits<T>::max());
94 for (
size_t N = 0;
N < Sz; ++
N) {
96 Offsets->push_back(
static_cast<T>(
N));
99 OffsetCache = Offsets;
104unsigned SourceMgr::SrcBuffer::getLineNumberSpecialized(
const char *
Ptr)
const {
106 GetOrCreateOffsetCache<T>(OffsetCache, Buffer.get());
108 const char *BufStart = Buffer->getBufferStart();
109 assert(
Ptr >= BufStart && Ptr <= Buffer->getBufferEnd());
112 static_cast<size_t>(PtrDiff) <= std::numeric_limits<T>::max());
113 T PtrOffset =
static_cast<T>(PtrDiff);
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);
131 return getLineNumberSpecialized<uint64_t>(
Ptr);
135const char *SourceMgr::SrcBuffer::getPointerForLineNumberSpecialized(
136 unsigned LineNo)
const {
138 GetOrCreateOffsetCache<T>(OffsetCache, Buffer.get());
144 const char *BufStart = Buffer->getBufferStart();
152 return BufStart +
Offsets[LineNo - 1] + 1;
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);
167 return getPointerForLineNumberSpecialized<uint64_t>(LineNo);
170SourceMgr::SrcBuffer::SrcBuffer(SourceMgr::SrcBuffer &&
Other)
172 IncludeLoc(
Other.IncludeLoc) {
173 Other.OffsetCache =
nullptr;
176SourceMgr::SrcBuffer::~SrcBuffer() {
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);
186 delete static_cast<std::vector<uint64_t> *
>(OffsetCache);
187 OffsetCache =
nullptr;
191std::pair<unsigned, unsigned>
195 assert(BufferID &&
"Invalid location!");
200 unsigned LineNo = SB.getLineNumber(
Ptr);
201 const char *BufStart = SB.Buffer->getBufferStart();
204 NewlineOffs = ~(size_t)0;
205 return std::make_pair(LineNo,
Ptr - BufStart - NewlineOffs);
217 bool IncludePath)
const {
219 assert(BufferID &&
"Invalid location!");
220 auto FileSpec =
getBufferInfo(BufferID).Buffer->getBufferIdentifier();
223 return FileSpec.str() +
":" + std::to_string(
FindLineNumber(Loc, BufferID));
225 auto I = FileSpec.find_last_of(
"/\\");
226 I = (
I == FileSpec.size()) ? 0 : (
I + 1);
227 return FileSpec.substr(
I).str() +
":" +
237 const char *
Ptr = SB.getPointerForLineNumber(LineNo);
248 if (
Ptr + ColNo > SB.Buffer->getBufferEnd())
262 if (IncludeLoc ==
SMLoc())
266 assert(CurBuf &&
"Invalid or unspecified location!");
270 OS <<
"Included from " <<
getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
280 std::pair<unsigned, unsigned> LineAndCol;
286 assert(CurBuf &&
"Invalid or unspecified location!");
294 while (LineStart != BufStart && LineStart[-1] !=
'\n' &&
295 LineStart[-1] !=
'\r')
301 while (LineEnd != BufEnd && LineEnd[0] !=
'\n' && LineEnd[0] !=
'\r')
303 LineStr =
StringRef(LineStart, LineEnd - LineStart);
312 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
316 if (R.Start.getPointer() < LineStart)
318 if (R.End.getPointer() > LineEnd)
323 ColRanges.
push_back(std::make_pair(R.Start.getPointer() - LineStart,
324 R.End.getPointer() - LineStart));
330 return SMDiagnostic(*
this, Loc, BufferID, LineAndCol.first,
331 LineAndCol.second - 1, Kind, Msg.
str(), LineStr,
336 bool ShowColors)
const {
339 DiagHandler(Diagnostic, DiagContext);
345 assert(CurBuf &&
"Invalid or unspecified location!");
349 Diagnostic.
print(
nullptr,
OS, ShowColors);
355 bool ShowColors)
const {
370 :
Range(R), Text(Replacement.str()) {
381 ArrayRef<std::pair<unsigned, unsigned>> Ranges,
383 : SM(&sm), Loc(L), Filename(
std::
string(FN)), LineNo(Line), ColumnNo(Col),
384 Kind(Kind), Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
395 const char *LineStart = SourceLine.
begin();
396 const char *LineEnd = SourceLine.
end();
398 size_t PrevHintEndCol = 0;
408 if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
415 if (R.Start.getPointer() < LineStart)
418 FirstCol = R.Start.getPointer() - LineStart;
427 unsigned HintCol = FirstCol;
428 if (HintCol < PrevHintEndCol)
429 HintCol = PrevHintEndCol + 1;
435 Fixit.getText().size());
438 unsigned LastColumnModified = HintCol + Fixit.getText().size();
439 if (LastColumnModified > FixItLine.size())
440 FixItLine.resize(LastColumnModified,
' ');
442 llvm::copy(Fixit.getText(), FixItLine.begin() + HintCol);
444 PrevHintEndCol = LastColumnModified;
449 if (R.End.getPointer() >= LineEnd)
450 LastCol = LineEnd - LineStart;
452 LastCol = R.End.getPointer() - LineStart;
454 std::fill(&CaretLine[FirstCol], &CaretLine[LastCol],
'~');
460 for (
unsigned i = 0, e = LineContents.
size(), OutCol = 0; i != e; ++i) {
461 size_t NextTab = LineContents.
find(
'\t', i);
469 S << LineContents.
slice(i, NextTab);
470 OutCol += NextTab - i;
477 }
while ((OutCol %
TabStop) != 0);
485 bool ShowKindLabel,
bool ShowLocation)
const {
491 if (ProgName && ProgName[0])
492 S << ProgName <<
": ";
494 if (ShowLocation && !Filename.empty()) {
503 S <<
':' << (ColumnNo + 1);
528 if (LineNo == -1 || ColumnNo == -1)
540 size_t NumColumns = LineContents.size();
543 std::string CaretLine(NumColumns + 1,
' ');
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())],
'~');
552 std::string FixItInsertionLine;
557 if (
unsigned(ColumnNo) <= NumColumns)
558 CaretLine[ColumnNo] =
'^';
560 CaretLine[NumColumns] =
'^';
565 CaretLine.erase(CaretLine.find_last_not_of(
' ') + 1);
574 for (
unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) {
575 if (i >= LineContents.size() || LineContents[i] !=
'\t') {
585 }
while ((OutCol %
TabStop) != 0);
591 if (FixItInsertionLine.empty())
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];
603 OS << FixItInsertionLine[i];
609 if (FixItInsertionLine[i] !=
' ')
612 }
while (((OutCol %
TabStop) != 0) && i != e);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
std::optional< std::vector< StOtherPiece > > Other
Provides ErrorOr<T> smart pointer.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
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)
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.
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 const char * getPointer() const
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,...
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
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.
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.
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...
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.