summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrasimir Georgiev <krasimir@google.com>2017-07-12 15:21:43 +0000
committerKrasimir Georgiev <krasimir@google.com>2017-07-12 15:21:43 +0000
commite092634f31afdf0fa5f82d81223d4726cfc7c537 (patch)
tree8a4795489b51dd1e187e96ff26fd489e5b128688
parent8c804d97467964bee14f47c72ec6b89f8d231f99 (diff)
downloadbcm5719-llvm-e092634f31afdf0fa5f82d81223d4726cfc7c537.tar.gz
bcm5719-llvm-e092634f31afdf0fa5f82d81223d4726cfc7c537.zip
[clang-format] Keep level of comment before an empty line
Summary: This patch fixes bug https://bugs.llvm.org/show_bug.cgi?id=3313: a comment line was aligned with the next #ifdef even in the presence of an empty line between them. Reviewers: djasper, klimek Reviewed By: djasper Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D35296 llvm-svn: 307795
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp17
-rw-r--r--clang/unittests/Format/FormatTest.cpp25
-rw-r--r--clang/unittests/Format/FormatTestComments.cpp64
3 files changed, 101 insertions, 5 deletions
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index b4d20a7bd6e..c6e90a9175e 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -1694,17 +1694,26 @@ void TokenAnnotator::setCommentLineLevels(
for (SmallVectorImpl<AnnotatedLine *>::reverse_iterator I = Lines.rbegin(),
E = Lines.rend();
I != E; ++I) {
- bool CommentLine = (*I)->First;
+ bool CommentLine = true;
for (const FormatToken *Tok = (*I)->First; Tok; Tok = Tok->Next) {
if (!Tok->is(tok::comment)) {
CommentLine = false;
break;
}
}
- if (NextNonCommentLine && CommentLine)
- (*I)->Level = NextNonCommentLine->Level;
- else
+
+ if (NextNonCommentLine && CommentLine) {
+ // If the comment is currently aligned with the line immediately following
+ // it, that's probably intentional and we should keep it.
+ bool AlignedWithNextLine =
+ NextNonCommentLine->First->NewlinesBefore <= 1 &&
+ NextNonCommentLine->First->OriginalColumn ==
+ (*I)->First->OriginalColumn;
+ if (AlignedWithNextLine)
+ (*I)->Level = NextNonCommentLine->Level;
+ } else {
NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr;
+ }
setCommentLineLevels((*I)->Children);
}
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index b5f959f9c1f..937362f5c9d 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -825,12 +825,35 @@ TEST_F(FormatTest, FormatsSwitchStatement) {
" case A:\n"
" f();\n"
" break;\n"
- " // On B:\n"
+ " // fallthrough\n"
" case B:\n"
" g();\n"
" break;\n"
" }\n"
"});");
+ EXPECT_EQ("DEBUG({\n"
+ " switch (x) {\n"
+ " case A:\n"
+ " f();\n"
+ " break;\n"
+ " // On B:\n"
+ " case B:\n"
+ " g();\n"
+ " break;\n"
+ " }\n"
+ "});",
+ format("DEBUG({\n"
+ " switch (x) {\n"
+ " case A:\n"
+ " f();\n"
+ " break;\n"
+ " // On B:\n"
+ " case B:\n"
+ " g();\n"
+ " break;\n"
+ " }\n"
+ "});",
+ getLLVMStyle()));
verifyFormat("switch (a) {\n"
"case (b):\n"
" return;\n"
diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp
index fdb5a08e7a2..7916e65e511 100644
--- a/clang/unittests/Format/FormatTestComments.cpp
+++ b/clang/unittests/Format/FormatTestComments.cpp
@@ -805,6 +805,70 @@ TEST_F(FormatTestComments, ParsesCommentsAdjacentToPPDirectives) {
format("namespace {}\n /* Test */ #define A"));
}
+TEST_F(FormatTestComments, KeepsLevelOfCommentBeforePPDirective) {
+ // Keep the current level if the comment was originally not aligned with
+ // the preprocessor directive.
+ EXPECT_EQ("void f() {\n"
+ " int i;\n"
+ " /* comment */\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}",
+ format("void f() {\n"
+ " int i;\n"
+ " /* comment */\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}"));
+
+ EXPECT_EQ("void f() {\n"
+ " int i;\n"
+ " /* comment */\n"
+ "\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}",
+ format("void f() {\n"
+ " int i;\n"
+ " /* comment */\n"
+ "\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}"));
+
+ // Keep the current level if there is an empty line between the comment and
+ // the preprocessor directive.
+ EXPECT_EQ("void f() {\n"
+ " int i;\n"
+ " /* comment */\n"
+ "\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}",
+ format("void f() {\n"
+ " int i;\n"
+ "/* comment */\n"
+ "\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}"));
+
+ // Align with the preprocessor directive if the comment was originally aligned
+ // with the preprocessor directive.
+ EXPECT_EQ("void f() {\n"
+ " int i;\n"
+ "/* comment */\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}",
+ format("void f() {\n"
+ " int i;\n"
+ "/* comment */\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}"));
+}
+
TEST_F(FormatTestComments, SplitsLongLinesInComments) {
EXPECT_EQ("/* This is a long\n"
" * comment that\n"
OpenPOWER on IntegriCloud