29 struct LineNoCacheTy {
30 int LastQueryBufferID;
31 const char *LastQuery;
32 unsigned LineNoOfQuery;
37 return (LineNoCacheTy*)Ptr;
43 if (LineNoCacheTy *Cache =
getCache(LineNoCache))
46 while (!Buffers.empty()) {
47 delete Buffers.back().Buffer;
57 std::string &IncludedFile) {
59 IncludedFile = Filename;
63 for (
unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBuf; ++i) {
64 IncludedFile = IncludeDirectories[i] +
"/" + Filename;
68 if (!NewBuf)
return ~0U;
77 for (
unsigned i = 0, e = Buffers.size(); i != e; ++i)
78 if (Loc.
getPointer() >= Buffers[i].Buffer->getBufferStart() &&
81 Loc.
getPointer() <= Buffers[i].Buffer->getBufferEnd())
88 std::pair<unsigned, unsigned>
91 assert(BufferID != -1 &&
"Invalid Location!");
100 const char *Ptr = BufStart;
105 if (LineNoCacheTy *Cache =
getCache(LineNoCache))
106 if (Cache->LastQueryBufferID == BufferID &&
108 Ptr = Cache->LastQuery;
109 LineNo = Cache->LineNoOfQuery;
115 if (*Ptr ==
'\n') ++LineNo;
118 if (LineNoCache == 0)
119 LineNoCache =
new LineNoCacheTy();
122 LineNoCacheTy &Cache = *
getCache(LineNoCache);
123 Cache.LastQueryBufferID = BufferID;
124 Cache.LastQuery = Ptr;
125 Cache.LineNoOfQuery = LineNo;
129 return std::make_pair(LineNo, Ptr-BufStart-NewlineOffs);
133 if (IncludeLoc ==
SMLoc())
return;
136 assert(CurBuf != -1 &&
"Invalid or unspecified location!");
140 OS <<
"Included from "
159 std::pair<unsigned, unsigned> LineAndCol;
160 const char *BufferID =
"<unknown>";
165 assert(CurBuf != -1 &&
"Invalid or unspecified location!");
173 while (LineStart != BufStart && LineStart[-1] !=
'\n' &&
174 LineStart[-1] !=
'\r')
180 while (LineEnd != BufEnd && LineEnd[0] !=
'\n' && LineEnd[0] !=
'\r')
182 LineStr = std::string(LineStart, LineEnd);
186 for (
unsigned i = 0, e = Ranges.
size(); i != e; ++i) {
209 return SMDiagnostic(*
this, Loc, BufferID, LineAndCol.first,
210 LineAndCol.second-1, Kind, Msg.
str(),
211 LineStr, ColRanges, FixIts);
222 DiagHandler(Diagnostic, DiagContext);
226 if (Loc !=
SMLoc()) {
228 assert(CurBuf != -1 &&
"Invalid or unspecified location!");
232 Diagnostic.
print(0, OS, ShowColors);
248 ArrayRef<std::pair<unsigned,unsigned> > Ranges,
250 : SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Kind(Kind),
251 Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
252 FixIts(Hints.
begin(), Hints.
end()) {
253 std::sort(FixIts.begin(), FixIts.end());
261 const char *LineStart = SourceLine.
begin();
262 const char *LineEnd = SourceLine.
end();
264 size_t PrevHintEndCol = 0;
294 unsigned HintCol = FirstCol;
295 if (HintCol < PrevHintEndCol)
296 HintCol = PrevHintEndCol + 1;
302 I->getText().size());
305 unsigned LastColumnModified = HintCol +
I->getText().size();
306 if (LastColumnModified > FixItLine.size())
307 FixItLine.resize(LastColumnModified,
' ');
309 std::copy(
I->getText().begin(),
I->getText().end(),
310 FixItLine.begin() + HintCol);
312 PrevHintEndCol = LastColumnModified;
318 LastCol = LineEnd - LineStart;
322 std::fill(&CaretLine[FirstCol], &CaretLine[LastCol],
'~');
328 for (
unsigned i = 0, e = LineContents.
size(), OutCol = 0; i != e; ++i) {
329 if (LineContents[i] !=
'\t') {
330 S << LineContents[i];
339 }
while ((OutCol %
TabStop) != 0);
349 bool ShowColors)
const {
356 if (ProgName && ProgName[0])
357 S << ProgName <<
": ";
359 if (!Filename.empty()) {
368 S <<
':' << (ColumnNo+1);
396 S << Message <<
'\n';
401 if (LineNo == -1 || ColumnNo == -1)
409 if (std::find_if(LineContents.begin(), LineContents.end(),
isNonASCII) !=
410 LineContents.end()) {
414 size_t NumColumns = LineContents.size();
417 std::string CaretLine(NumColumns+1,
' ');
420 for (
unsigned r = 0, e = Ranges.size(); r != e; ++r) {
421 std::pair<unsigned, unsigned> R = Ranges[r];
422 std::fill(&CaretLine[R.first],
423 &CaretLine[std::min((
size_t)R.second, CaretLine.size())],
429 std::string FixItInsertionLine;
432 LineContents.size()));
435 if (
unsigned(ColumnNo) <= NumColumns)
436 CaretLine[ColumnNo] =
'^';
438 CaretLine[NumColumns] =
'^';
443 CaretLine.erase(CaretLine.find_last_not_of(
' ')+1);
451 for (
unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) {
452 if (i >= LineContents.size() || LineContents[i] !=
'\t') {
462 }
while ((OutCol %
TabStop) != 0);
470 if (FixItInsertionLine.empty())
473 for (
size_t i = 0, e = FixItInsertionLine.size(), OutCol = 0; i < e; ++i) {
474 if (i >= LineContents.size() || LineContents[i] !=
'\t') {
475 S << FixItInsertionLine[i];
482 S << FixItInsertionLine[i];
488 if (FixItInsertionLine[i] !=
' ')
491 }
while (((OutCol %
TabStop) != 0) && i != e);
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const
const char * getPointer() const
size_t size() const
size - Get the string size.
const char * getBufferStart() const
virtual bool has_colors() const
This function determines if this stream is displayed and supports colors.
virtual raw_ostream & changeColor(enum Colors Color, bool Bold=false, bool BG=false)
const_iterator begin(StringRef path)
Get begin iterator over path.
virtual const char * getBufferIdentifier() const
std::string str() const
str - Return the twine contents as a std::string.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
size_t AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, std::string &IncludedFile)
static const size_t TabStop
size_t size() const
size - Get the array size.
int columnWidth(StringRef s)
bool empty() const
empty - Check if the array is empty.
const SrcBuffer & getBufferInfo(unsigned i) const
static LineNoCacheTy * getCache(void *Ptr)
static error_code getFile(Twine Filename, OwningPtr< MemoryBuffer > &result, int64_t FileSize=-1, bool RequiresNullTerminator=true)
size_t find_last_of(char C, size_t From=npos) const
static void printSourceLine(raw_ostream &S, StringRef LineContents)
unsigned FindLineNumber(SMLoc Loc, int BufferID=-1) const
void print(const char *ProgName, raw_ostream &S, bool ShowColors=true) const
static bool isNonASCII(char c)
static SMLoc getFromPointer(const char *Ptr)
static void buildFixItLine(std::string &CaretLine, std::string &FixItLine, ArrayRef< SMFixIt > FixIts, ArrayRef< char > SourceLine)
int FindBufferContainingLoc(SMLoc Loc) const
const char * getBufferEnd() const
virtual raw_ostream & resetColor()
std::pair< unsigned, unsigned > getLineAndColumn(SMLoc Loc, int BufferID=-1) const
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges=None, ArrayRef< SMFixIt > FixIts=None) const
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges=None, ArrayRef< SMFixIt > FixIts=None, bool ShowColors=true) const
Represents a location in source code.
size_t AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc)