diff --git a/clang/lib/Frontend/TextDiagnosticPrinter.cpp b/clang/lib/Frontend/TextDiagnosticPrinter.cpp index d4c7e0f6f330..973a47f7794a 100644 --- a/clang/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/TextDiagnosticPrinter.cpp @@ -66,7 +66,7 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, SourceLocation Begin = SM.getInstantiationLoc(R.getBegin()); SourceLocation End = SM.getInstantiationLoc(R.getEnd()); - + // If the End location and the start location are the same and are a macro // location, then the range was something that came from a macro expansion // or _Pragma. If this is an object-like macro, the best we can do is to @@ -74,15 +74,15 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, // highlight the arguments. if (Begin == End && R.getEnd().isMacroID()) End = SM.getInstantiationRange(R.getEnd()).second; - + unsigned StartLineNo = SM.getInstantiationLineNumber(Begin); if (StartLineNo > LineNo || SM.getFileID(Begin) != FID) return; // No intersection. - + unsigned EndLineNo = SM.getInstantiationLineNumber(End); if (EndLineNo < LineNo || SM.getFileID(End) != FID) return; // No intersection. - + // Compute the column number of the start. unsigned StartColNo = 0; if (StartLineNo == LineNo) { @@ -94,21 +94,21 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, while (StartColNo < SourceLine.size() && (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t')) ++StartColNo; - + // Compute the column number of the end. unsigned EndColNo = CaretLine.size(); if (EndLineNo == LineNo) { EndColNo = SM.getInstantiationColumnNumber(End); if (EndColNo) { --EndColNo; // Zero base the col #. - + // Add in the length of the token, so that we cover multi-char tokens. EndColNo += Lexer::MeasureTokenLength(End, SM, *LangOpts); } else { EndColNo = CaretLine.size(); } } - + // Pick the last non-whitespace column. if (EndColNo <= SourceLine.size()) while (EndColNo-1 && @@ -116,7 +116,7 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, --EndColNo; else EndColNo = SourceLine.size(); - + // Fill the range with ~'s. assert(StartColNo <= EndColNo && "Invalid range!"); for (unsigned i = StartColNo; i < EndColNo; ++i) @@ -156,7 +156,7 @@ static void SelectInterestingSourceRegion(std::string &SourceLine, for (; FixItStart != FixItEnd; ++FixItStart) if (!isspace(FixItInsertionLine[FixItStart])) break; - + for (; FixItEnd != FixItStart; --FixItEnd) if (!isspace(FixItInsertionLine[FixItEnd - 1])) break; @@ -189,16 +189,16 @@ static void SelectInterestingSourceRegion(std::string &SourceLine, CaretStart = 0; else if (CaretStart > 1) { unsigned NewStart = CaretStart - 1; - + // Skip over any whitespace we see here; we're looking for // another bit of interesting text. while (NewStart && isspace(SourceLine[NewStart])) --NewStart; - + // Skip over this bit of "interesting" text. while (NewStart && !isspace(SourceLine[NewStart])) --NewStart; - + // Move up to the non-whitespace character we just saw. if (NewStart) ++NewStart; @@ -220,7 +220,7 @@ static void SelectInterestingSourceRegion(std::string &SourceLine, // another bit of interesting text. while (NewEnd != SourceLength && isspace(SourceLine[NewEnd - 1])) ++NewEnd; - + // Skip over this bit of "interesting" text. while (NewEnd != SourceLength && !isspace(SourceLine[NewEnd - 1])) ++NewEnd; @@ -244,7 +244,7 @@ static void SelectInterestingSourceRegion(std::string &SourceLine, CaretLine.erase(CaretEnd, std::string::npos); if (FixItInsertionLine.size() > CaretEnd) FixItInsertionLine.erase(CaretEnd, std::string::npos); - + if (CaretStart > 2) { SourceLine.replace(0, CaretStart, " ..."); CaretLine.replace(0, CaretStart, " "); @@ -271,7 +271,7 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, EmitCaretDiagnostic(OneLevelUp, Ranges, NumRanges, SM, 0, 0, Columns); Loc = SM.getImmediateSpellingLoc(Loc); - + // Map the ranges. for (unsigned i = 0; i != NumRanges; ++i) { SourceLocation S = Ranges[i].getBegin(), E = Ranges[i].getEnd(); @@ -279,10 +279,10 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, if (E.isMacroID()) E = SM.getImmediateSpellingLoc(E); Ranges[i] = SourceRange(S, E); } - + if (ShowLocation) { std::pair IInfo = SM.getDecomposedInstantiationLoc(Loc); - + // Emit the file/line/column that this expansion came from. OS << SM.getBuffer(IInfo.first)->getBufferIdentifier() << ':' << SM.getLineNumber(IInfo.first, IInfo.second) << ':'; @@ -291,75 +291,75 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, OS << ' '; } OS << "note: instantiated from:\n"; - + EmitCaretDiagnostic(Loc, Ranges, NumRanges, SM, Hints, NumHints, Columns); return; } - + // Decompose the location into a FID/Offset pair. std::pair LocInfo = SM.getDecomposedLoc(Loc); FileID FID = LocInfo.first; unsigned FileOffset = LocInfo.second; - + // Get information about the buffer it points into. std::pair BufferInfo = SM.getBufferData(FID); const char *BufStart = BufferInfo.first; unsigned ColNo = SM.getColumnNumber(FID, FileOffset); - unsigned CaretEndColNo + unsigned CaretEndColNo = ColNo + Lexer::MeasureTokenLength(Loc, SM, *LangOpts); // Rewind from the current position to the start of the line. const char *TokPtr = BufStart+FileOffset; const char *LineStart = TokPtr-ColNo+1; // Column # is 1-based. - - + + // Compute the line end. Scan forward from the error position to the end of // the line. const char *LineEnd = TokPtr; while (*LineEnd != '\n' && *LineEnd != '\r' && *LineEnd != '\0') ++LineEnd; - + // Copy the line of code into an std::string for ease of manipulation. std::string SourceLine(LineStart, LineEnd); - + // Create a line for the caret that is filled with spaces that is the same // length as the line of source code. std::string CaretLine(LineEnd-LineStart, ' '); - + // Highlight all of the characters covered by Ranges with ~ characters. if (NumRanges) { unsigned LineNo = SM.getLineNumber(FID, FileOffset); - + for (unsigned i = 0, e = NumRanges; i != e; ++i) HighlightRange(Ranges[i], SM, LineNo, FID, CaretLine, SourceLine); } - + // Next, insert the caret itself. if (ColNo-1 < CaretLine.size()) CaretLine[ColNo-1] = '^'; else CaretLine.push_back('^'); - + // Scan the source line, looking for tabs. If we find any, manually expand // them to 8 characters and update the CaretLine to match. for (unsigned i = 0; i != SourceLine.size(); ++i) { if (SourceLine[i] != '\t') continue; - + // Replace this tab with at least one space. SourceLine[i] = ' '; - + // Compute the number of spaces we need to insert. unsigned NumSpaces = ((i+8)&~7) - (i+1); assert(NumSpaces < 8 && "Invalid computation of space amt"); - + // Insert spaces into the SourceLine. SourceLine.insert(i+1, NumSpaces, ' '); - + // Insert spaces or ~'s into CaretLine. CaretLine.insert(i+1, NumSpaces, CaretLine[i] == '~' ? '~' : ' '); } - + // If we are in -fdiagnostics-print-source-range-info mode, we are trying to // produce easily machine parsable output. Add a space before the source line // and the caret to make it trivial to tell the main diagnostic line from what @@ -368,7 +368,7 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, SourceLine = ' ' + SourceLine; CaretLine = ' ' + CaretLine; } - + std::string FixItInsertionLine; if (NumHints && PrintFixItInfo) { for (const CodeModificationHint *Hint = Hints, *LastHint = Hints + NumHints; @@ -376,15 +376,15 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, if (Hint->InsertionLoc.isValid()) { // We have an insertion hint. Determine whether the inserted // code is on the same line as the caret. - std::pair HintLocInfo + std::pair HintLocInfo = SM.getDecomposedInstantiationLoc(Hint->InsertionLoc); if (SM.getLineNumber(HintLocInfo.first, HintLocInfo.second) == SM.getLineNumber(FID, FileOffset)) { // Insert the new code into the line just below the code // that the user wrote. - unsigned HintColNo + unsigned HintColNo = SM.getColumnNumber(HintLocInfo.first, HintLocInfo.second); - unsigned LastColumnModified + unsigned LastColumnModified = HintColNo - 1 + Hint->CodeToInsert.size(); if (LastColumnModified > FixItInsertionLine.size()) FixItInsertionLine.resize(LastColumnModified, ' '); @@ -407,7 +407,7 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, // Finally, remove any blank spaces from the end of CaretLine. while (CaretLine[CaretLine.size()-1] == ' ') CaretLine.erase(CaretLine.end()-1); - + // Emit what we have computed. OS << SourceLine << '\n'; @@ -421,7 +421,7 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, if (UseColors) // Print fixit line in color OS.changeColor(fixitColor, false); - if (PrintRangeInfo) + if (PrintRangeInfo) OS << ' '; OS << FixItInsertionLine << '\n'; if (UseColors) @@ -435,7 +435,7 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, /// \returns The index of the first non-whitespace character that is /// greater than or equal to Idx or, if no such character exists, /// returns the end of the string. -static unsigned skipWhitespace(unsigned Idx, +static unsigned skipWhitespace(unsigned Idx, const llvm::SmallVectorImpl &Str, unsigned Length) { while (Idx < Length && isspace(Str[Idx])) @@ -455,7 +455,7 @@ static inline char findMatchingPunctuation(char c) { case '`': return '\''; case '"': return '"'; case '(': return ')'; - case '[': return ']'; + case '[': return ']'; case '{': return '}'; default: break; } @@ -468,9 +468,9 @@ static inline char findMatchingPunctuation(char c) { /// /// \returns the index pointing one character past the end of the /// word. -unsigned findEndOfWord(unsigned Start, +unsigned findEndOfWord(unsigned Start, const llvm::SmallVectorImpl &Str, - unsigned Length, unsigned Column, + unsigned Length, unsigned Column, unsigned Columns) { unsigned End = Start + 1; @@ -535,13 +535,13 @@ unsigned findEndOfWord(unsigned Start, /// /// \returns true if word-wrapping was required, or false if the /// string fit on the first line. -static bool PrintWordWrapped(llvm::raw_ostream &OS, - const llvm::SmallVectorImpl &Str, - unsigned Columns, +static bool PrintWordWrapped(llvm::raw_ostream &OS, + const llvm::SmallVectorImpl &Str, + unsigned Columns, unsigned Column = 0, unsigned Indentation = WordWrapIndentation) { unsigned Length = Str.size(); - + // If there is a newline in this message somewhere, find that // newline and split the message into the part before the newline // (which will be word-wrapped) and the part from the newline one @@ -556,7 +556,7 @@ static bool PrintWordWrapped(llvm::raw_ostream &OS, llvm::SmallString<16> IndentStr; IndentStr.assign(Indentation, ' '); bool Wrapped = false; - for (unsigned WordStart = 0, WordEnd; WordStart < Length; + for (unsigned WordStart = 0, WordEnd; WordStart < Length; WordStart = WordEnd) { // Find the beginning of the next word. WordStart = skipWhitespace(WordStart, Str, Length); @@ -565,7 +565,7 @@ static bool PrintWordWrapped(llvm::raw_ostream &OS, // Find the end of this word. WordEnd = findEndOfWord(WordStart, Str, Length, Column, Columns); - + // Does this word fit on the current line? unsigned WordLength = WordEnd - WordStart; if (Column + WordLength < Columns) { @@ -587,7 +587,7 @@ static bool PrintWordWrapped(llvm::raw_ostream &OS, Column = Indentation + WordLength; Wrapped = true; } - + if (Length == Str.size()) return Wrapped; // We're done. @@ -597,7 +597,7 @@ static bool PrintWordWrapped(llvm::raw_ostream &OS, return true; } -void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, +void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info) { // Keeps track of the the starting position of the location // information (e.g., "foo.c:10:4:") that precedes the error @@ -611,7 +611,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, const SourceManager &SM = Info.getLocation().getManager(); PresumedLoc PLoc = SM.getPresumedLoc(Info.getLocation()); unsigned LineNo = PLoc.getLine(); - + // First, if this diagnostic is not in the main file, print out the // "included from" lines. if (LastWarningLoc != PLoc.getIncludeLoc()) { @@ -619,7 +619,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, PrintIncludeStack(LastWarningLoc, SM); StartOfLocationInfo = OS.tell(); } - + // Compute the column number. if (ShowLocation) { if (UseColors) @@ -628,12 +628,12 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, if (ShowColumn) if (unsigned ColNo = PLoc.getColumn()) OS << ColNo << ':'; - + if (PrintRangeInfo && Info.getNumRanges()) { FileID CaretFileID = SM.getFileID(SM.getInstantiationLoc(Info.getLocation())); bool PrintedRange = false; - + for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) { // Ignore invalid ranges. if (!Info.getRange(i).isValid()) continue; @@ -642,7 +642,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, SourceLocation E = Info.getRange(i).getEnd(); B = SM.getInstantiationLoc(B); E = SM.getInstantiationLoc(E); - + // If the End location and the start location are the same and are a // macro location, then the range was something that came from a macro // expansion or _Pragma. If this is an object-like macro, the best we @@ -653,22 +653,22 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, std::pair BInfo = SM.getDecomposedLoc(B); std::pair EInfo = SM.getDecomposedLoc(E); - + // If the start or end of the range is in another file, just discard // it. if (BInfo.first != CaretFileID || EInfo.first != CaretFileID) continue; - + // Add in the length of the token, so that we cover multi-char tokens. unsigned TokSize = Lexer::MeasureTokenLength(E, SM, *LangOpts); - + OS << '{' << SM.getLineNumber(BInfo.first, BInfo.second) << ':' << SM.getColumnNumber(BInfo.first, BInfo.second) << '-' << SM.getLineNumber(EInfo.first, EInfo.second) << ':' << (SM.getColumnNumber(EInfo.first, EInfo.second)+TokSize) << '}'; PrintedRange = true; } - + if (PrintedRange) OS << ':'; } @@ -688,7 +688,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, case Diagnostic::Fatal: OS.changeColor(fatalColor, true); break; } } - + switch (Level) { case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type"); case Diagnostic::Note: OS << "note: "; break; @@ -702,14 +702,14 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, llvm::SmallString<100> OutStr; Info.FormatDiagnostic(OutStr); - + if (PrintDiagnosticOption) if (const char *Opt = Diagnostic::getWarningOptionForDiag(Info.getID())) { OutStr += " [-W"; OutStr += Opt; OutStr += ']'; } - + if (UseColors) { // Print warnings, errors and fatal errors in bold, no color switch (Level) { @@ -732,7 +732,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, OS << '\n'; if (UseColors) OS.resetColor(); - + // If caret diagnostics are enabled and we have location, we want to // emit the caret. However, we only do this if the location moved // from the last diagnostic, if the last diagnostic was a note that @@ -740,7 +740,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, // diagnostic has ranges. We don't want to emit the same caret // multiple times if one loc has multiple diagnostics. if (CaretDiagnostics && Info.getLocation().isValid() && - ((LastLoc != Info.getLocation()) || Info.getNumRanges() || + ((LastLoc != Info.getLocation()) || Info.getNumRanges() || (LastCaretDiagnosticWasNote && Level != Diagnostic::Note) || Info.getNumCodeModificationHints())) { // Cache the LastLoc, it allows us to omit duplicate source/caret spewage. @@ -753,7 +753,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, assert(NumRanges < 20 && "Out of space"); for (unsigned i = 0; i != NumRanges; ++i) Ranges[i] = Info.getRange(i); - + unsigned NumHints = Info.getNumCodeModificationHints(); for (unsigned idx = 0; idx < NumHints; ++idx) { const CodeModificationHint &Hint = Info.getCodeModificationHint(idx); @@ -768,6 +768,6 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, Info.getNumCodeModificationHints(), MessageLength); } - + OS.flush(); }