Index: clang/include/clang/Rewrite/Core/Rewriter.h =================================================================== --- clang/include/clang/Rewrite/Core/Rewriter.h +++ clang/include/clang/Rewrite/Core/Rewriter.h @@ -46,6 +46,16 @@ /// If true and removing some text leaves a blank line /// also remove the empty line (false by default). + /// + /// FIXME: This sometimes corrupts the file's rewrite buffer due to + /// incorrect indexing in the implementation. Moreover, it's inefficient + /// because it must scan the buffer from the beginning to find the start of + /// the line. When feasible, it's better for the caller to check for a + /// blank line and then, if found, expand the removal range to include it. + /// Checking for a blank line is easy if, for example, the caller can + /// guarantee this is the first edit of a line. In that case, it can just + /// scan before and after the removal range until the next newline or + /// begin/end of the input. bool RemoveLineIfEmpty = false; RewriteOptions() {} Index: clang/lib/Rewrite/Rewriter.cpp =================================================================== --- clang/lib/Rewrite/Rewriter.cpp +++ clang/lib/Rewrite/Rewriter.cpp @@ -96,6 +96,15 @@ } if (posI != end() && *posI == '\n') { Buffer.erase(curLineStartOffs, lineSize + 1/* + '\n'*/); + // FIXME: Here, the offset of the start of the line is supposed to be + // expressed in terms of the original input not the "real" rewrite + // buffer. How do we compute that reliably? It might be tempting to use + // curLineStartOffs + OrigOffset - RealOffset, but that assumes the + // difference between the original and real offset is the same at the + // removed text and at the start of the line, but that's not true if + // edits were previously made earlier on the line. Even if that's + // corrected, this still assumes all the whitespace characters being + // removed were originally contiguous. Is that OK? AddReplaceDelta(curLineStartOffs, -(lineSize + 1/* + '\n'*/)); } }