diff options
author | Nico Weber <nicolasweber@gmx.de> | 2012-07-20 06:44:52 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2012-07-20 06:44:52 +0000 |
commit | 43972898614d91c00982f10cdf7f2bfb4a9f6275 (patch) | |
tree | 317c35107fb61a8daa08055d348d9149e92a3c3a /lib/Frontend/TextDiagnostic.cpp | |
parent | 381767fcfe2fdf53727099d95b23b0c9e6a9aa6c (diff) |
Revert r160319, it caused PR13417. Add a test for PR13417.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160542 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/TextDiagnostic.cpp')
-rw-r--r-- | lib/Frontend/TextDiagnostic.cpp | 53 |
1 files changed, 27 insertions, 26 deletions
diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp index f604f8aa57..306306d3ac 100644 --- a/lib/Frontend/TextDiagnostic.cpp +++ b/lib/Frontend/TextDiagnostic.cpp @@ -1124,7 +1124,7 @@ std::string TextDiagnostic::buildFixItInsertionLine( std::string FixItInsertionLine; if (Hints.empty() || !DiagOpts.ShowFixits) return FixItInsertionLine; - unsigned PrevHintEndCol = 0; + unsigned PrevHintEnd = 0; for (ArrayRef<FixItHint>::iterator I = Hints.begin(), E = Hints.end(); I != E; ++I) { @@ -1136,15 +1136,11 @@ std::string TextDiagnostic::buildFixItInsertionLine( if (LineNo == SM.getLineNumber(HintLocInfo.first, HintLocInfo.second)) { // Insert the new code into the line just below the code // that the user wrote. - // Note: When modifying this function, be very careful about what is a - // "column" (printed width, platform-dependent) and what is a - // "byte offset" (SourceManager "column"). - unsigned HintByteOffset + unsigned HintColNo = SM.getColumnNumber(HintLocInfo.first, HintLocInfo.second) - 1; - - // The hint must start inside the source or right at the end - assert(HintByteOffset < static_cast<unsigned>(map.bytes())+1); - unsigned HintCol = map.byteToColumn(HintByteOffset); + // hint must start inside the source or right at the end + assert(HintColNo<static_cast<unsigned>(map.bytes())+1); + HintColNo = map.byteToColumn(HintColNo); // If we inserted a long previous hint, push this one forwards, and add // an extra space to show that this is not part of the previous @@ -1153,27 +1149,32 @@ std::string TextDiagnostic::buildFixItInsertionLine( // // Note that if this hint is located immediately after the previous // hint, no space will be added, since the location is more important. - if (HintCol < PrevHintEndCol) - HintCol = PrevHintEndCol + 1; - - // FIXME: This function handles multibyte characters in the source, but - // not in the fixits. This assertion is intended to catch unintended - // use of multibyte characters in fixits. If we decide to do this, we'll - // have to track separate byte widths for the source and fixit lines. - assert((size_t)llvm::sys::locale::columnWidth(I->CodeToInsert) == - I->CodeToInsert.size()); - - // This relies on one byte per column in our fixit hints. - // This should NOT use HintByteOffset, because the source might have - // Unicode characters in earlier columns. - unsigned LastColumnModified = HintCol + I->CodeToInsert.size(); + if (HintColNo < PrevHintEnd) + HintColNo = PrevHintEnd + 1; + + // FIXME: if the fixit includes tabs or other characters that do not + // take up a single column per byte when displayed then + // I->CodeToInsert.size() is not a column number and we're mixing + // units (columns + bytes). We should get printable versions + // of each fixit before using them. + unsigned LastColumnModified + = HintColNo + I->CodeToInsert.size(); + + if (LastColumnModified <= static_cast<unsigned>(map.bytes())) { + // If we're right in the middle of a multibyte character skip to + // the end of it. + while (map.byteToColumn(LastColumnModified) == -1) + ++LastColumnModified; + LastColumnModified = map.byteToColumn(LastColumnModified); + } + if (LastColumnModified > FixItInsertionLine.size()) FixItInsertionLine.resize(LastColumnModified, ' '); - + assert(HintColNo+I->CodeToInsert.size() <= FixItInsertionLine.size()); std::copy(I->CodeToInsert.begin(), I->CodeToInsert.end(), - FixItInsertionLine.begin() + HintCol); + FixItInsertionLine.begin() + HintColNo); - PrevHintEndCol = LastColumnModified; + PrevHintEnd = LastColumnModified; } else { FixItInsertionLine.clear(); break; |