16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/Support/ConvertUTF.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/Locale.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include "llvm/Support/raw_ostream.h"
25 using namespace clang;
39 static const enum raw_ostream::Colors
errorColor = raw_ostream::RED;
40 static const enum raw_ostream::Colors
fatalColor = raw_ostream::RED;
43 raw_ostream::SAVEDCOLOR;
47 bool &Normal,
bool Bold) {
50 OS << Str.slice(0, Pos);
51 if (Pos == StringRef::npos)
54 Str = Str.substr(Pos + 1);
72 if (SourceLine[--i]==
'\t')
98 static std::pair<SmallString<16>,
bool>
101 assert(i &&
"i must not be null");
102 assert(*i<SourceLine.size() &&
"must point to a valid index");
104 if (SourceLine[*i]==
'\t') {
106 "Invalid -ftabstop value");
108 unsigned NumSpaces = TabStop - col%TabStop;
109 assert(0 < NumSpaces && NumSpaces <= TabStop
110 &&
"Invalid computation of space amt");
114 expandedTab.assign(NumSpaces,
' ');
115 return std::make_pair(expandedTab,
true);
119 begin =
reinterpret_cast<unsigned char const *
>(&*(SourceLine.begin() + *i));
120 end = begin + (SourceLine.size() - *i);
122 if (isLegalUTF8Sequence(begin, end)) {
125 unsigned char const *original_begin =
begin;
126 unsigned char const *cp_end = begin+getNumBytesForUTF8(SourceLine[*i]);
128 ConversionResult res = ConvertUTF8toUTF32(&begin, cp_end, &cptr, cptr+1,
131 assert(conversionOK==res);
132 assert(0 < begin-original_begin
133 &&
"we must be further along in the string now");
134 *i += begin-original_begin;
136 if (!llvm::sys::locale::isPrint(c)) {
140 expandedCP.insert(expandedCP.begin()+3, llvm::hexdigit(c%16));
143 while (expandedCP.size() < 8)
144 expandedCP.insert(expandedCP.begin()+3, llvm::hexdigit(0));
145 return std::make_pair(expandedCP,
false);
155 unsigned char byte = SourceLine[*i];
156 expandedByte[1] = llvm::hexdigit(byte / 16);
157 expandedByte[2] = llvm::hexdigit(byte % 16);
159 return std::make_pair(expandedByte,
false);
162 static void expandTabs(std::string &SourceLine,
unsigned TabStop) {
163 size_t i = SourceLine.size();
166 if (SourceLine[i]!=
'\t')
169 std::pair<SmallString<16>,
bool> res
171 SourceLine.replace(i, 1, res.first.c_str());
201 if (SourceLine.empty()) {
206 out.resize(SourceLine.size()+1, -1);
210 while (i<SourceLine.size()) {
212 std::pair<SmallString<16>,
bool> res
216 out.back() = columns;
235 if (SourceLine.empty()) {
242 while (i<SourceLine.size()) {
243 out.resize(columns+1, -1);
245 std::pair<SmallString<16>,
bool> res
249 out.resize(columns+1, -1);
254 struct SourceColumnMap {
255 SourceColumnMap(StringRef SourceLine,
unsigned TabStop)
256 : m_SourceLine(SourceLine) {
261 assert(m_byteToColumn.size()==SourceLine.size()+1);
262 assert(0 < m_byteToColumn.size() && 0 < m_columnToByte.size());
263 assert(m_byteToColumn.size()
264 ==
static_cast<unsigned>(m_columnToByte.back()+1));
265 assert(static_cast<unsigned>(m_byteToColumn.back()+1)
266 == m_columnToByte.size());
268 int columns()
const {
return m_byteToColumn.back(); }
269 int bytes()
const {
return m_columnToByte.back(); }
274 assert(0<=n && n<static_cast<int>(m_byteToColumn.size()));
275 return m_byteToColumn[n];
279 int byteToContainingColumn(
int N)
const {
280 assert(0 <= N && N < static_cast<int>(m_byteToColumn.size()));
281 while (m_byteToColumn[N] == -1)
283 return m_byteToColumn[N];
290 assert(0<=n && n<static_cast<int>(m_columnToByte.size()));
291 return m_columnToByte[n];
295 int startOfNextColumn(
int N)
const {
296 assert(0 <= N && N < static_cast<int>(m_byteToColumn.size() - 1));
302 int startOfPreviousColumn(
int N)
const {
303 assert(0 < N && N < static_cast<int>(m_byteToColumn.size()));
308 StringRef getSourceLine()
const {
313 const std::string m_SourceLine;
322 std::string &CaretLine,
323 std::string &FixItInsertionLine,
325 const SourceColumnMap &map) {
326 unsigned CaretColumns = CaretLine.size();
328 unsigned MaxColumns = std::max(static_cast<unsigned>(map.columns()),
329 std::max(CaretColumns, FixItColumns));
331 if (MaxColumns <= Columns)
335 assert(CaretLine.end() ==
336 std::find_if(CaretLine.begin(), CaretLine.end(),
337 [](
char c) {
return c <
' ' ||
'~' < c; }));
341 unsigned CaretStart = 0, CaretEnd = CaretLine.size();
342 for (; CaretStart != CaretEnd; ++CaretStart)
346 for (; CaretEnd != CaretStart; --CaretEnd)
355 if (!FixItInsertionLine.empty()) {
356 unsigned FixItStart = 0, FixItEnd = FixItInsertionLine.size();
357 for (; FixItStart != FixItEnd; ++FixItStart)
361 for (; FixItEnd != FixItStart; --FixItEnd)
368 unsigned FixItStartCol = FixItStart;
372 CaretStart = std::min(FixItStartCol, CaretStart);
373 CaretEnd = std::max(FixItEndCol, CaretEnd);
379 while (static_cast<int>(CaretEnd) < map.columns() &&
380 -1 == map.columnToByte(CaretEnd))
383 assert((static_cast<int>(CaretStart) > map.columns() ||
384 -1!=map.columnToByte(CaretStart)) &&
385 "CaretStart must not point to a column in the middle of a source"
387 assert((static_cast<int>(CaretEnd) > map.columns() ||
388 -1!=map.columnToByte(CaretEnd)) &&
389 "CaretEnd must not point to a column in the middle of a source line"
397 unsigned SourceStart = map.columnToByte(std::min<unsigned>(CaretStart,
399 unsigned SourceEnd = map.columnToByte(std::min<unsigned>(CaretEnd,
402 unsigned CaretColumnsOutsideSource = CaretEnd-CaretStart
403 - (map.byteToColumn(SourceEnd)-map.byteToColumn(SourceStart));
405 char const *front_ellipse =
" ...";
406 char const *front_space =
" ";
407 char const *back_ellipse =
"...";
408 unsigned ellipses_space = strlen(front_ellipse) + strlen(back_ellipse);
410 unsigned TargetColumns = Columns;
413 if (TargetColumns > ellipses_space+CaretColumnsOutsideSource)
414 TargetColumns -= ellipses_space+CaretColumnsOutsideSource;
416 while (SourceStart>0 || SourceEnd<SourceLine.size()) {
417 bool ExpandedRegion =
false;
420 unsigned NewStart = map.startOfPreviousColumn(SourceStart);
426 NewStart = map.startOfPreviousColumn(NewStart);
430 unsigned Prev = map.startOfPreviousColumn(NewStart);
436 assert(map.byteToColumn(NewStart) != -1);
437 unsigned NewColumns = map.byteToColumn(SourceEnd) -
438 map.byteToColumn(NewStart);
439 if (NewColumns <= TargetColumns) {
440 SourceStart = NewStart;
441 ExpandedRegion =
true;
445 if (SourceEnd<SourceLine.size()) {
446 unsigned NewEnd = map.startOfNextColumn(SourceEnd);
451 while (NewEnd < SourceLine.size() &&
isWhitespace(SourceLine[NewEnd]))
452 NewEnd = map.startOfNextColumn(NewEnd);
455 while (NewEnd < SourceLine.size() &&
isWhitespace(SourceLine[NewEnd]))
456 NewEnd = map.startOfNextColumn(NewEnd);
458 assert(map.byteToColumn(NewEnd) != -1);
459 unsigned NewColumns = map.byteToColumn(NewEnd) -
460 map.byteToColumn(SourceStart);
461 if (NewColumns <= TargetColumns) {
463 ExpandedRegion =
true;
471 CaretStart = map.byteToColumn(SourceStart);
472 CaretEnd = map.byteToColumn(SourceEnd) + CaretColumnsOutsideSource;
478 assert(CaretStart!=(
unsigned)-1 && CaretEnd!=(
unsigned)-1 &&
479 SourceStart!=(
unsigned)-1 && SourceEnd!=(
unsigned)-1);
480 assert(SourceStart <= SourceEnd);
481 assert(CaretStart <= CaretEnd);
483 unsigned BackColumnsRemoved
484 = map.byteToColumn(SourceLine.size())-map.byteToColumn(SourceEnd);
485 unsigned FrontColumnsRemoved = CaretStart;
486 unsigned ColumnsKept = CaretEnd-CaretStart;
489 assert(FrontColumnsRemoved+ColumnsKept+BackColumnsRemoved > Columns);
493 if (BackColumnsRemoved > strlen(back_ellipse))
494 SourceLine.replace(SourceEnd, std::string::npos, back_ellipse);
497 if (FrontColumnsRemoved+ColumnsKept <= Columns)
501 if (FrontColumnsRemoved > strlen(front_ellipse)) {
502 SourceLine.replace(0, SourceStart, front_ellipse);
503 CaretLine.replace(0, CaretStart, front_space);
504 if (!FixItInsertionLine.empty())
505 FixItInsertionLine.replace(0, CaretStart, front_space);
529 case '\'':
return '\'';
530 case '`':
return '\'';
531 case '"':
return '"';
532 case '(':
return ')';
533 case '[':
return ']';
534 case '{':
return '}';
549 assert(Start < Str.size() &&
"Invalid start position!");
550 unsigned End = Start + 1;
553 if (End == Str.size())
569 PunctuationEndStack.push_back(EndPunct);
570 while (End < Length && !PunctuationEndStack.empty()) {
571 if (Str[End] == PunctuationEndStack.back())
572 PunctuationEndStack.pop_back();
574 PunctuationEndStack.push_back(SubEndPunct);
583 unsigned PunctWordLength = End - Start;
585 Column + PunctWordLength <= Columns ||
588 PunctWordLength < Columns/3)
595 return findEndOfWord(Start + 1, Str, Length, Column + 1, Columns);
618 const unsigned Length = std::min(Str.find(
'\n'), Str.size());
619 bool TextNormal =
true;
623 IndentStr.assign(Indentation,
' ');
624 bool Wrapped =
false;
625 for (
unsigned WordStart = 0, WordEnd; WordStart <
Length;
626 WordStart = WordEnd) {
629 if (WordStart == Length)
636 unsigned WordLength = WordEnd - WordStart;
637 if (
Column + WordLength < Columns) {
652 OS.write(&IndentStr[0], Indentation);
655 Column = Indentation + WordLength;
662 assert(TextNormal &&
"Text highlighted at end of diagnostic message.");
682 uint64_t StartOfLocationInfo = OS.tell();
695 Message, OS.tell() - StartOfLocationInfo,
703 bool CLFallbackMode) {
708 llvm_unreachable(
"Invalid diagnostic type");
719 llvm_unreachable(
"Invalid diagnostic type");
744 unsigned CurrentColumn,
745 unsigned Columns,
bool ShowColors) {
747 if (ShowColors && !IsSupplemental) {
759 assert(Normal &&
"Formatting should have returned to normal");
791 unsigned LineNo = PLoc.
getLine();
812 if (
LangOpts.MSCompatibilityVersion &&
825 if (
DiagOpts->ShowSourceRanges && !Ranges.empty()) {
828 bool PrintedRange =
false;
834 if (!RI->isValid())
continue;
852 if (BInfo.first != CaretFileID || EInfo.first != CaretFileID)
857 unsigned TokSize = 0;
858 if (RI->isTokenRange())
861 OS <<
'{' << SM.
getLineNumber(BInfo.first, BInfo.second) <<
':'
879 OS <<
"In file included from " << PLoc.
getFilename() <<
':'
882 OS <<
"In included file:\n";
886 StringRef ModuleName,
889 OS <<
"In module '" << ModuleName <<
"' imported from "
892 OS <<
"In module '" << ModuleName <<
"':\n";
897 StringRef ModuleName,
900 OS <<
"While building module '" << ModuleName <<
"' imported from "
903 OS <<
"While building module '" << ModuleName <<
"':\n";
908 unsigned LineNo,
FileID FID,
909 const SourceColumnMap &map,
910 std::string &CaretLine,
919 if (StartLineNo > LineNo || SM.
getFileID(Begin) != FID)
923 if (EndLineNo < LineNo || SM.
getFileID(End) != FID)
927 unsigned StartColNo = 0;
928 if (StartLineNo == LineNo) {
930 if (StartColNo) --StartColNo;
934 unsigned EndColNo = map.getSourceLine().size();
935 if (EndLineNo == LineNo) {
945 EndColNo = CaretLine.size();
949 assert(StartColNo <= EndColNo &&
"Invalid range!");
954 while (StartColNo < map.getSourceLine().size() &&
955 (map.getSourceLine()[StartColNo] ==
' ' ||
956 map.getSourceLine()[StartColNo] ==
'\t'))
957 StartColNo = map.startOfNextColumn(StartColNo);
960 if (EndColNo > map.getSourceLine().size())
961 EndColNo = map.getSourceLine().size();
963 (map.getSourceLine()[EndColNo-1] ==
' ' ||
964 map.getSourceLine()[EndColNo-1] ==
'\t'))
965 EndColNo = map.startOfPreviousColumn(EndColNo);
970 assert(StartColNo <= EndColNo &&
"Trying to highlight whitespace??");
973 assert(StartColNo <= map.getSourceLine().size() &&
"Invalid range!");
974 assert(EndColNo <= map.getSourceLine().size() &&
"Invalid range!");
977 StartColNo = map.byteToContainingColumn(StartColNo);
978 EndColNo = map.byteToContainingColumn(EndColNo);
980 assert(StartColNo <= EndColNo &&
"Invalid range!");
981 if (CaretLine.size() < EndColNo)
982 CaretLine.resize(EndColNo,
' ');
983 std::fill(CaretLine.begin()+StartColNo,CaretLine.begin()+EndColNo,
'~');
987 const SourceColumnMap &map,
991 std::string FixItInsertionLine;
992 if (Hints.empty() || !DiagOpts->ShowFixits)
993 return FixItInsertionLine;
994 unsigned PrevHintEndCol = 0;
998 if (!
I->CodeToInsert.empty()) {
1001 std::pair<FileID, unsigned> HintLocInfo
1003 if (LineNo == SM.
getLineNumber(HintLocInfo.first, HintLocInfo.second) &&
1004 StringRef(
I->CodeToInsert).find_first_of(
"\n\r") == StringRef::npos) {
1010 unsigned HintByteOffset
1014 assert(HintByteOffset < static_cast<unsigned>(map.bytes())+1);
1015 unsigned HintCol = map.byteToContainingColumn(HintByteOffset);
1024 if (HintCol < PrevHintEndCol)
1025 HintCol = PrevHintEndCol + 1;
1029 unsigned NewFixItLineSize = FixItInsertionLine.size() +
1030 (HintCol - PrevHintEndCol) +
I->CodeToInsert.size();
1031 if (NewFixItLineSize > FixItInsertionLine.size())
1032 FixItInsertionLine.resize(NewFixItLineSize,
' ');
1034 std::copy(
I->CodeToInsert.begin(),
I->CodeToInsert.end(),
1035 FixItInsertionLine.end() -
I->CodeToInsert.size());
1040 FixItInsertionLine.clear();
1046 expandTabs(FixItInsertionLine, DiagOpts->TabStop);
1048 return FixItInsertionLine;
1058 void TextDiagnostic::emitSnippetAndCaret(
1063 assert(Loc.
isValid() &&
"must have a valid source location here");
1064 assert(Loc.
isFileID() &&
"must have a file location here");
1074 if (Loc ==
LastLoc && Ranges.empty() && Hints.empty() &&
1080 FileID FID = LocInfo.first;
1081 unsigned FileOffset = LocInfo.second;
1085 const char *BufStart = SM.
getBufferData(FID, &Invalid).data();
1093 static const size_t MaxLineLengthToPrint = 4096;
1094 if (ColNo > MaxLineLengthToPrint)
1098 const char *TokPtr = BufStart+FileOffset;
1099 const char *LineStart = TokPtr-ColNo+1;
1103 const char *LineEnd = TokPtr;
1104 while (*LineEnd !=
'\n' && *LineEnd !=
'\r' && *LineEnd !=
'\0')
1108 if (
size_t(LineEnd - LineStart) > MaxLineLengthToPrint)
1112 std::string SourceLine(LineStart, LineEnd);
1115 const SourceColumnMap sourceColMap(SourceLine,
DiagOpts->TabStop);
1119 std::string CaretLine(sourceColMap.columns(),
' ');
1128 ColNo = sourceColMap.byteToContainingColumn(ColNo-1);
1129 if (CaretLine.size()<ColNo+1)
1130 CaretLine.resize(ColNo+1,
' ');
1131 CaretLine[ColNo] =
'^';
1140 unsigned Columns =
DiagOpts->MessageLength;
1143 Columns, sourceColMap);
1150 SourceLine =
' ' + SourceLine;
1151 CaretLine =
' ' + CaretLine;
1155 while (CaretLine[CaretLine.size()-1] ==
' ')
1156 CaretLine.erase(CaretLine.end()-1);
1159 emitSnippet(SourceLine);
1163 OS << CaretLine <<
'\n';
1167 if (!FixItInsertionLine.empty()) {
1173 OS << FixItInsertionLine <<
'\n';
1179 emitParseableFixits(Hints, SM);
1182 void TextDiagnostic::emitSnippet(StringRef line) {
1188 std::string to_print;
1189 bool print_reversed =
false;
1191 while (i<line.size()) {
1192 std::pair<SmallString<16>,
bool> res
1194 bool was_printable = res.second;
1196 if (
DiagOpts->ShowColors && was_printable == print_reversed) {
1205 print_reversed = !was_printable;
1206 to_print += res.first.str();
1209 if (print_reversed &&
DiagOpts->ShowColors)
1212 if (print_reversed &&
DiagOpts->ShowColors)
1220 if (!
DiagOpts->ShowParseableFixits)
1227 if (
I->RemoveRange.isInvalid() ||
1228 I->RemoveRange.getBegin().isMacroID() ||
1229 I->RemoveRange.getEnd().isMacroID())
1242 if (
I->RemoveRange.isTokenRange())
1258 OS.write_escaped(
I->CodeToInsert);
SourceLocation getBegin() const
unsigned getColumn() const
Return the presumed column number of this location.
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
Defines the clang::FileManager interface and associated types.
static LLVM_READONLY bool isWhitespace(unsigned char c)
Return true if this character is horizontal or vertical ASCII whitespace: ' ', '\t', '\f', '\v', '\n', '\r'.
void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level, ArrayRef< CharSourceRange > Ranges, const SourceManager &SM) override
Print out the file/line/column information and include trace.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
Defines the SourceManager interface.
static enum raw_ostream::Colors fatalColor
const LangOptions & LangOpts
static unsigned findEndOfWord(unsigned Start, StringRef Str, unsigned Length, unsigned Column, unsigned Columns)
Find the end of the word starting at the given offset within a string.
static enum raw_ostream::Colors caretColor
static enum raw_ostream::Colors templateColor
static enum raw_ostream::Colors errorColor
static StringRef bytes(const std::vector< T, Allocator > &v)
static enum raw_ostream::Colors fixitColor
void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc, StringRef ModuleName, const SourceManager &SM) override
static std::pair< SmallString< 16 >, bool > printableTextForNextCharacter(StringRef SourceLine, size_t *i, unsigned TabStop)
returns a printable representation of first item from input range
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
std::pair< SourceLocation, SourceLocation > getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Class to encapsulate the logic for formatting a diagnostic message.
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
static void selectInterestingSourceRegion(std::string &SourceLine, std::string &CaretLine, std::string &FixItInsertionLine, unsigned Columns, const SourceColumnMap &map)
When the source code line we want to print is too long for the terminal, select the "interesting" reg...
static bool printWordWrapped(raw_ostream &OS, StringRef Str, unsigned Columns, unsigned Column=0, bool Bold=false, unsigned Indentation=WordWrapIndentation)
Print the given string to a stream, word-wrapping it to some number of columns in the process...
DiagnosticsEngine::Level LastLevel
The level of the last diagnostic emitted.
unsigned getLine() const
Return the presumed line number of this location.
TextDiagnostic(raw_ostream &OS, const LangOptions &LangOpts, DiagnosticOptions *DiagOpts)
detail::InMemoryDirectory::const_iterator I
static unsigned skipWhitespace(unsigned Idx, StringRef Str, unsigned Length)
Skip over whitespace in the string, starting at the given index.
~TextDiagnostic() override
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
Represents a character-granular source range.
SourceLocation getEnd() const
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
IntrusiveRefCntPtr< DiagnosticOptions > DiagOpts
Represents an unpacked "presumed" location which can be presented to the user.
static int bytesSincePreviousTabOrLineBegin(StringRef SourceLine, size_t i)
unsigned getColumnNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Return the column # for the specified file position.
void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level, StringRef Message, ArrayRef< CharSourceRange > Ranges, const SourceManager *SM, DiagOrStoredDiag D) override
static enum raw_ostream::Colors warningColor
static enum raw_ostream::Colors noteColor
llvm::PointerUnion< const Diagnostic *, const StoredDiagnostic * > DiagOrStoredDiag
bool isTokenRange() const
Return true if the end of this range specifies the start of the last token.
const char * getFilename() const
Return the presumed filename of this location.
const char * getName() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
Options for controlling the compiler diagnostics engine.
static void highlightRange(const CharSourceRange &R, unsigned LineNo, FileID FID, const SourceColumnMap &map, std::string &CaretLine, const SourceManager &SM, const LangOptions &LangOpts)
Highlight a SourceRange (with ~'s) for any characters on LineNo.
static void printDiagnosticLevel(raw_ostream &OS, DiagnosticsEngine::Level Level, bool ShowColors, bool CLFallbackMode=false)
Print the diagonstic level to a raw_ostream.
Cached information about one file (either on disk or in the virtual file system). ...
const char ToggleHighlight
Special character that the diagnostic printer will use to toggle the bold attribute.
static void printDiagnosticMessage(raw_ostream &OS, bool IsSupplemental, StringRef Message, unsigned CurrentColumn, unsigned Columns, bool ShowColors)
Pretty-print a diagnostic message to a raw_ostream.
static void byteToColumn(StringRef SourceLine, unsigned TabStop, SmallVectorImpl< int > &out)
This function takes a raw source line and produces a mapping from the bytes of the printable represen...
const unsigned WordWrapIndentation
Number of spaces to indent when word-wrapping.
static char findMatchingPunctuation(char c)
If the given character is the start of some kind of balanced punctuation (e.g., quotes or parentheses...
static void expandTabs(std::string &SourceLine, unsigned TabStop)
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
SourceLocation LastLoc
The location of the previous diagnostic if known.
static void applyTemplateHighlighting(raw_ostream &OS, StringRef Str, bool &Normal, bool Bold)
Add highlights to differences in template strings.
unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Given a SourceLocation, return the spelling line number for the position indicated.
static void columnToByte(StringRef SourceLine, unsigned TabStop, SmallVectorImpl< int > &out)
This function takes a raw source line and produces a mapping from columns to the byte of the source l...
void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc, const SourceManager &SM) override
detail::InMemoryDirectory::const_iterator E
static std::string buildFixItInsertionLine(unsigned LineNo, const SourceColumnMap &map, ArrayRef< FixItHint > Hints, const SourceManager &SM, const DiagnosticOptions *DiagOpts)
void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc, StringRef ModuleName, const SourceManager &SM) override
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
Level
The level of the diagnostic, after it has been through mapping.
static enum raw_ostream::Colors remarkColor
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
static enum raw_ostream::Colors savedColor
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.