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);
std::optional< std::vector< StOtherPiece > > Other
Provides ErrorOr<T> smart pointer.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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...
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.
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.
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,...
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
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.
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const
Prints the names of included files and the line of the file they were included from.
unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
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.
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.
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.
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...
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 raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
static raw_ostream & error()
Convenience method for printing "error: " to stderr.
static raw_ostream & note()
Convenience method for printing "note: " to stderr.
static 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
int columnWidth(StringRef s)
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)
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.