owenpan updated this revision to Diff 531538. owenpan edited the summary of this revision. owenpan added a reviewer: paulkirth. owenpan removed a subscriber: paulkirth. owenpan added a comment.
Add a member `Newlines` to `struct FormatToken` and compute it only once in `UnwrappedLineFormatter::formatFirstToken()`. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D151954/new/ https://reviews.llvm.org/D151954 Files: clang/lib/Format/FormatToken.h clang/lib/Format/UnwrappedLineFormatter.cpp clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -12856,6 +12856,71 @@ " void f() {}\n" "};\n", Style); + verifyFormat("struct foo {\n" + "#ifdef FOO\n" + "#else\n" + "private:\n" + "\n" + "#endif\n" + "};", + "struct foo {\n" + "#ifdef FOO\n" + "#else\n" + "private:\n" + "\n" + "#endif\n" + "};", + Style); + verifyFormat("struct foo {\n" + "#ifdef FOO\n" + "#else\n" + "private:\n" + "\n" + "#endif\n" + "};", + "struct foo {\n" + "#ifdef FOO\n" + "#else\n" + "private:\n" + "\n" + "\n" + "#endif\n" + "};", + Style); + verifyFormat("struct foo {\n" + "#ifdef FOO\n" + "private:\n" + "#else\n" + "#endif\n" + "};", + "struct foo {\n" + "#ifdef FOO\n" + "private:\n" + "\n" + "\n" + "#else\n" + "#endif\n" + "};", + Style); + verifyFormat("struct foo {\n" + "#if 0\n" + "#else\n" + "#endif\n" + "#ifdef FOO\n" + "private:\n" + "#endif\n" + "};", + "struct foo {\n" + "#if 0\n" + "#else\n" + "#endif\n" + "#ifdef FOO\n" + "private:\n" + "\n" + "\n" + "#endif\n" + "};", + Style); Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always; verifyFormat("struct foo {\n" Index: clang/lib/Format/UnwrappedLineFormatter.cpp =================================================================== --- clang/lib/Format/UnwrappedLineFormatter.cpp +++ clang/lib/Format/UnwrappedLineFormatter.cpp @@ -1418,22 +1418,13 @@ return Penalty; } -void UnwrappedLineFormatter::formatFirstToken( - const AnnotatedLine &Line, const AnnotatedLine *PreviousLine, - const AnnotatedLine *PrevPrevLine, - const SmallVectorImpl<AnnotatedLine *> &Lines, unsigned Indent, - unsigned NewlineIndent) { - FormatToken &RootToken = *Line.First; - if (RootToken.is(tok::eof)) { - unsigned Newlines = - std::min(RootToken.NewlinesBefore, - Style.KeepEmptyLinesAtEOF ? Style.MaxEmptyLinesToKeep + 1 : 1); - unsigned TokenIndent = Newlines ? NewlineIndent : 0; - Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent, - TokenIndent); - return; - } - unsigned Newlines = +static auto computeNewlines(const AnnotatedLine &Line, + const AnnotatedLine *PreviousLine, + const AnnotatedLine *PrevPrevLine, + const SmallVectorImpl<AnnotatedLine *> &Lines, + const FormatStyle &Style) { + const auto &RootToken = *Line.First; + auto Newlines = std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1); // Remove empty lines before "}" where applicable. if (RootToken.is(tok::r_brace) && @@ -1512,7 +1503,32 @@ } } - if (Newlines) + return Newlines; +} + +void UnwrappedLineFormatter::formatFirstToken( + const AnnotatedLine &Line, const AnnotatedLine *PreviousLine, + const AnnotatedLine *PrevPrevLine, + const SmallVectorImpl<AnnotatedLine *> &Lines, unsigned Indent, + unsigned NewlineIndent) { + FormatToken &RootToken = *Line.First; + if (RootToken.is(tok::eof)) { + unsigned Newlines = + std::min(RootToken.NewlinesBefore, + Style.KeepEmptyLinesAtEOF ? Style.MaxEmptyLinesToKeep + 1 : 1); + unsigned TokenIndent = Newlines ? NewlineIndent : 0; + Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent, + TokenIndent); + return; + } + + if (RootToken.Newlines < 0) { + RootToken.Newlines = + computeNewlines(Line, PreviousLine, PrevPrevLine, Lines, Style); + assert(RootToken.Newlines >= 0); + } + + if (RootToken.Newlines > 0) Indent = NewlineIndent; // Preprocessor directives get indented before the hash only if specified. In @@ -1524,7 +1540,7 @@ Indent = 0; } - Whitespaces->replaceWhitespace(RootToken, Newlines, Indent, Indent, + Whitespaces->replaceWhitespace(RootToken, RootToken.Newlines, Indent, Indent, /*IsAligned=*/false, Line.InPPDirective && !RootToken.HasUnescapedNewline); Index: clang/lib/Format/FormatToken.h =================================================================== --- clang/lib/Format/FormatToken.h +++ clang/lib/Format/FormatToken.h @@ -418,6 +418,12 @@ /// and thereby e.g. leave an empty line between two function definitions. unsigned NewlinesBefore = 0; + /// The number of newlines immediately before the \c Token after formatting. + /// + /// This is used to avoid overlapping whitespace replacements when \c Newlines + /// is recomputed for a finalized preprocessor branching directive. + int Newlines = -1; + /// The offset just past the last '\n' in this token's leading /// whitespace (relative to \c WhiteSpaceStart). 0 if there is no '\n'. unsigned LastNewlineOffset = 0;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits