Index: lib/Format/UnwrappedLineParser.h =================================================================== --- lib/Format/UnwrappedLineParser.h +++ lib/Format/UnwrappedLineParser.h @@ -114,6 +114,8 @@ void nextToken(); const FormatToken *getPreviousToken(); void readToken(); + void organiseComments(const SmallVectorImpl &Comments, + const FormatToken *NextTok); void flushComments(bool NewlineBeforeNext); void pushToken(FormatToken *Tok); void calculateBraceTypes(bool ExpectClassBody = false); Index: lib/Format/UnwrappedLineParser.cpp =================================================================== --- lib/Format/UnwrappedLineParser.cpp +++ lib/Format/UnwrappedLineParser.cpp @@ -2201,13 +2201,48 @@ return Line->Tokens.back().Tok; } -void UnwrappedLineParser::readToken() { +void UnwrappedLineParser::organiseComments( + const SmallVectorImpl &Comments, + const FormatToken* NextTok) { bool CommentsInCurrentLine = true; + int StartOfSectionAlignedWithNextToken = -1; + if (NextTok) { + for (int i = Comments.size() - 1; i >= 0; --i) { + if (Comments[i]->OriginalColumn == + NextTok->OriginalColumn) { + StartOfSectionAlignedWithNextToken = i; + } + } + } + for (int i = 0, e = Comments.size(); i < e; ++i) { + FormatToken *FormatTok = Comments[i]; + if (i == StartOfSectionAlignedWithNextToken) { + FormatTok->ContinuesLineCommentSection = false; + } else { + FormatTok->ContinuesLineCommentSection = + continuesLineComment(*FormatTok, *Line, CommentPragmasRegex); + } + if (!FormatTok->ContinuesLineCommentSection && + (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) { + CommentsInCurrentLine = false; + } + if (CommentsInCurrentLine) { + pushToken(FormatTok); + } else { + CommentsBeforeNextToken.push_back(FormatTok); + } + } +} + +void UnwrappedLineParser::readToken() { + SmallVector Comments; do { FormatTok = Tokens->getNextToken(); assert(FormatTok); while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) && (FormatTok->HasUnescapedNewline || FormatTok->IsFirst)) { + organiseComments(Comments, FormatTok); + Comments.clear(); // If there is an unfinished unwrapped line, we flush the preprocessor // directives only after that unwrapped line was finished later. bool SwitchToPreprocessorLines = !Line->Tokens.empty(); @@ -2237,20 +2272,17 @@ continue; } - if (!FormatTok->Tok.is(tok::comment)) + if (!FormatTok->Tok.is(tok::comment)) { + organiseComments(Comments, FormatTok); + Comments.clear(); return; - FormatTok->ContinuesLineCommentSection = - continuesLineComment(*FormatTok, *Line, CommentPragmasRegex); - if (!FormatTok->ContinuesLineCommentSection && - (isOnNewLine(*FormatTok) || FormatTok->IsFirst)) { - CommentsInCurrentLine = false; - } - if (CommentsInCurrentLine) { - pushToken(FormatTok); - } else { - CommentsBeforeNextToken.push_back(FormatTok); } + + Comments.push_back(FormatTok); } while (!eof()); + + organiseComments(Comments, nullptr); + Comments.clear(); } void UnwrappedLineParser::pushToken(FormatToken *Tok) { Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -11924,6 +11924,97 @@ "\n" "// long", getLLVMStyleWithColumns(15))); + + // Align comment line sections aligned with the next token with the next + // token. + EXPECT_EQ("class A {\n" + "public: // public comment\n" + " // comment about a\n" + " int a;\n" + "};", + format("class A {\n" + "public: // public comment\n" + " // comment about a\n" + " int a;\n" + "};", + getLLVMStyleWithColumns(40))); + EXPECT_EQ("class A {\n" + "public: // public comment 1\n" + " // public comment 2\n" + " // comment 1 about a\n" + " // comment 2 about a\n" + " int a;\n" + "};", + format("class A {\n" + "public: // public comment 1\n" + " // public comment 2\n" + " // comment 1 about a\n" + " // comment 2 about a\n" + " int a;\n" + "};", + getLLVMStyleWithColumns(40))); + EXPECT_EQ("int f(int n) { // comment line 1 on f\n" + " // comment line 2 on f\n" + " // comment line 1 before return\n" + " // comment line 2 before return\n" + " return n; // comment line 1 on return\n" + " // comment line 2 on return\n" + " // comment line 1 after return\n" + "}", + format("int f(int n) { // comment line 1 on f\n" + " // comment line 2 on f\n" + " // comment line 1 before return\n" + " // comment line 2 before return\n" + " return n; // comment line 1 on return\n" + " // comment line 2 on return\n" + " // comment line 1 after return\n" + "}", + getLLVMStyleWithColumns(40))); + EXPECT_EQ("int f(int n) {\n" + " switch (n) { // comment line 1 on switch\n" + " // comment line 2 on switch\n" + " // comment line 1 before case 1\n" + " // comment line 2 before case 1\n" + " case 1: // comment line 1 on case 1\n" + " // comment line 2 on case 1\n" + " // comment line 1 before return 1\n" + " // comment line 2 before return 1\n" + " return 1; // comment line 1 on return 1\n" + " // comment line 2 on return 1\n" + " // comment line 1 before default\n" + " // comment line 2 before default\n" + " default: // comment line 1 on default\n" + " // comment line 2 on default\n" + " // comment line 1 before return 2\n" + " return 2 * f(n - 1); // comment line 1 on return 2\n" + " // comment line 2 on return 2\n" + " // comment line 1 after return\n" + " // comment line 2 after return\n" + " }\n" + "}", + format("int f(int n) {\n" + " switch (n) { // comment line 1 on switch\n" + " // comment line 2 on switch\n" + " // comment line 1 before case 1\n" + " // comment line 2 before case 1\n" + " case 1: // comment line 1 on case 1\n" + " // comment line 2 on case 1\n" + " // comment line 1 before return 1\n" + " // comment line 2 before return 1\n" + " return 1; // comment line 1 on return 1\n" + " // comment line 2 on return 1\n" + " // comment line 1 before default\n" + " // comment line 2 before default\n" + " default: // comment line 1 on default\n" + " // comment line 2 on default\n" + " // comment line 1 before return 2\n" + " return 2 * f(n - 1); // comment line 1 on return 2\n" + " // comment line 2 on return 2\n" + " // comment line 1 after return\n" + " // comment line 2 after return\n" + " }\n" + "}", + getLLVMStyleWithColumns(80))); } } // end namespace } // end namespace format