[clang] 14c30c7 - [clang-format] Avoid crash in LevelIndentTracker.
Author: Marek Kurdej Date: 2022-07-07T10:15:45+02:00 New Revision: 14c30c70c4595d8f410c74a72357a5a31fdd5507 URL: https://github.com/llvm/llvm-project/commit/14c30c70c4595d8f410c74a72357a5a31fdd5507 DIFF: https://github.com/llvm/llvm-project/commit/14c30c70c4595d8f410c74a72357a5a31fdd5507.diff LOG: [clang-format] Avoid crash in LevelIndentTracker. Fixes https://github.com/llvm/llvm-project/issues/56352. Reviewed By: HazardyKnusperkeks, owenpan, MyDeveloperDay Differential Revision: https://reviews.llvm.org/D129064 Added: Modified: clang/lib/Format/UnwrappedLineFormatter.cpp clang/unittests/Format/FormatTestSelective.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 22509a5042465..9a6f8884fcec3 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -66,7 +66,6 @@ class LevelIndentTracker { (Style.PPIndentWidth >= 0) ? Style.PPIndentWidth : Style.IndentWidth; Indent = Line.Level * IndentWidth + AdditionalIndent; } else { - IndentForLevel.resize(Line.Level + 1); Indent = getIndent(Line.Level); } if (static_cast(Indent) + Offset >= 0) @@ -91,6 +90,7 @@ class LevelIndentTracker { unsigned LevelIndent = Line.First->OriginalColumn; if (static_cast(LevelIndent) - Offset >= 0) LevelIndent -= Offset; +assert(Line.Level < IndentForLevel.size()); if ((!Line.First->is(tok::comment) || IndentForLevel[Line.Level] == -1) && !Line.InPPDirective) { IndentForLevel[Line.Level] = LevelIndent; diff --git a/clang/unittests/Format/FormatTestSelective.cpp b/clang/unittests/Format/FormatTestSelective.cpp index 2725e4cf776f6..86ed7aba1913d 100644 --- a/clang/unittests/Format/FormatTestSelective.cpp +++ b/clang/unittests/Format/FormatTestSelective.cpp @@ -609,6 +609,14 @@ TEST_F(FormatTestSelective, DontAssert) { " return a == 8 ? 32 : 16;\n" "}\n"; EXPECT_EQ(Code, format(Code, 40, 0)); + + // https://llvm.org/PR56352 + Style.CompactNamespaces = true; + Style.NamespaceIndentation = FormatStyle::NI_All; + Code = "\n" + "namespace ns1 { namespace ns2 {\n" + "}}"; + EXPECT_EQ(Code, format(Code, 0, 0)); } } // end namespace ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 8f70d16 - [clang-format] Handle attributes in enum declaration.
Author: Tyler Chatow Date: 2022-05-26T15:43:57+02:00 New Revision: 8f70d16c9ab2d7c060f5c92a31a0fc4a82349897 URL: https://github.com/llvm/llvm-project/commit/8f70d16c9ab2d7c060f5c92a31a0fc4a82349897 DIFF: https://github.com/llvm/llvm-project/commit/8f70d16c9ab2d7c060f5c92a31a0fc4a82349897.diff LOG: [clang-format] Handle attributes in enum declaration. Fixes https://github.com/llvm/llvm-project/issues/55457 Ensures that attributes in the enum declaration are interpreted correctly, for instance: ``` enum class [[nodiscard]] E { a, b }; ``` Reviewed By: MyDeveloperDay, curdeius Differential Revision: https://reviews.llvm.org/D125848 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index a20562dd77a4..0611e9eace47 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3419,11 +3419,18 @@ bool UnwrappedLineParser::parseEnum() { while (FormatTok->Tok.getIdentifierInfo() || FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less, -tok::greater, tok::comma, tok::question)) { +tok::greater, tok::comma, tok::question, +tok::l_square, tok::r_square)) { nextToken(); // We can have macros or attributes in between 'enum' and the enum name. if (FormatTok->is(tok::l_paren)) parseParens(); +if (FormatTok->is(TT_AttributeSquare)) { + parseSquare(); + // Consume the closing TT_AttributeSquare. + if (FormatTok->Next && FormatTok->is(TT_AttributeSquare)) +nextToken(); +} if (FormatTok->is(tok::identifier)) { nextToken(); // If there are two identifiers in a row, this is likely an elaborate diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 3621ba667818..44ef882fe7db 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -3573,6 +3573,7 @@ TEST_F(FormatTest, FormatsEnum) { verifyFormat("enum X E {} d;"); verifyFormat("enum __attribute__((...)) E {} d;"); verifyFormat("enum __declspec__((...)) E {} d;"); + verifyFormat("enum [[nodiscard]] E {} d;"); verifyFormat("enum {\n" " Bar = Foo::value\n" "};", @@ -3619,6 +3620,17 @@ TEST_F(FormatTest, FormatsEnum) { "};", EightIndent); + verifyFormat("enum [[nodiscard]] E {\n" + " ONE,\n" + " TWO,\n" + "};"); + verifyFormat("enum [[nodiscard]] E {\n" + " // Comment 1\n" + " ONE,\n" + " // Comment 2\n" + " TWO,\n" + "};"); + // Not enums. verifyFormat("enum X f() {\n" " a();\n" @@ -3666,7 +3678,19 @@ TEST_F(FormatTest, FormatsEnumStruct) { verifyFormat("enum struct X E {} d;"); verifyFormat("enum struct __attribute__((...)) E {} d;"); verifyFormat("enum struct __declspec__((...)) E {} d;"); + verifyFormat("enum struct [[nodiscard]] E {} d;"); verifyFormat("enum struct X f() {\n a();\n return 42;\n}"); + + verifyFormat("enum struct [[nodiscard]] E {\n" + " ONE,\n" + " TWO,\n" + "};"); + verifyFormat("enum struct [[nodiscard]] E {\n" + " // Comment 1\n" + " ONE,\n" + " // Comment 2\n" + " TWO,\n" + "};"); } TEST_F(FormatTest, FormatsEnumClass) { @@ -3683,7 +3707,19 @@ TEST_F(FormatTest, FormatsEnumClass) { verifyFormat("enum class X E {} d;"); verifyFormat("enum class __attribute__((...)) E {} d;"); verifyFormat("enum class __declspec__((...)) E {} d;"); + verifyFormat("enum class [[nodiscard]] E {} d;"); verifyFormat("enum class X f() {\n a();\n return 42;\n}"); + + verifyFormat("enum class [[nodiscard]] E {\n" + " ONE,\n" + " TWO,\n" + "};"); + verifyFormat("enum class [[nodiscard]] E {\n" + " // Comment 1\n" + " ONE,\n" + " // Comment 2\n" + " TWO,\n" + "};"); } TEST_F(FormatTest, FormatsEnumTypes) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] d4d28f2 - [clang-format] Fix QualifierAlignment with global namespace qualified types.
Author: Marek Kurdej Date: 2022-05-26T15:02:33+02:00 New Revision: d4d28f2ace764a0420a33462628b43a1c71fc3dc URL: https://github.com/llvm/llvm-project/commit/d4d28f2ace764a0420a33462628b43a1c71fc3dc DIFF: https://github.com/llvm/llvm-project/commit/d4d28f2ace764a0420a33462628b43a1c71fc3dc.diff LOG: [clang-format] Fix QualifierAlignment with global namespace qualified types. Fixes https://github.com/llvm/llvm-project/issues/55610. Reviewed By: MyDeveloperDay Differential Revision: https://reviews.llvm.org/D126096 Added: Modified: clang/lib/Format/QualifierAlignmentFixer.cpp clang/unittests/Format/QualifierFixerTest.cpp Removed: diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp index dd12298a57ff..61f17cae383e 100644 --- a/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -216,6 +216,29 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight( if (LeftRightQualifierAlignmentFixer::isPossibleMacro(Tok->Next)) return Tok; + auto AnalyzeTemplate = + [&](const FormatToken *Tok, + const FormatToken *StartTemplate) -> const FormatToken * { +// Read from the TemplateOpener to TemplateCloser. +FormatToken *EndTemplate = StartTemplate->MatchingParen; +if (EndTemplate) { + // Move to the end of any template class members e.g. + // `Foo::iterator`. + if (EndTemplate->startsSequence(TT_TemplateCloser, tok::coloncolon, + tok::identifier)) { +EndTemplate = EndTemplate->Next->Next; + } +} +if (EndTemplate && EndTemplate->Next && +!EndTemplate->Next->isOneOf(tok::equal, tok::l_paren)) { + insertQualifierAfter(SourceMgr, Fixes, EndTemplate, Qualifier); + // Remove the qualifier. + removeToken(SourceMgr, Fixes, Tok); + return Tok; +} +return nullptr; + }; + FormatToken *Qual = Tok->Next; FormatToken *LastQual = Qual; while (Qual && isQualifierOrType(Qual, ConfiguredQualifierTokens)) { @@ -233,27 +256,24 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight( return Tok; } else if (Tok->startsSequence(QualifierType, tok::identifier, TT_TemplateOpener)) { -// Read from the TemplateOpener to -// TemplateCloser as in const ArrayRef a; const ArrayRef -FormatToken *EndTemplate = Tok->Next->Next->MatchingParen; -if (EndTemplate) { - // Move to the end of any template class members e.g. - // `Foo::iterator`. - if (EndTemplate->startsSequence(TT_TemplateCloser, tok::coloncolon, - tok::identifier)) { -EndTemplate = EndTemplate->Next->Next; - } -} -if (EndTemplate && EndTemplate->Next && -!EndTemplate->Next->isOneOf(tok::equal, tok::l_paren)) { - insertQualifierAfter(SourceMgr, Fixes, EndTemplate, Qualifier); - // Remove the qualifier. - removeToken(SourceMgr, Fixes, Tok); - return Tok; -} - } else if (Tok->startsSequence(QualifierType, tok::identifier)) { +// `const ArrayRef a;` +// `const ArrayRef ` +const FormatToken *NewTok = AnalyzeTemplate(Tok, Tok->Next->Next); +if (NewTok) + return NewTok; + } else if (Tok->startsSequence(QualifierType, tok::coloncolon, + tok::identifier, TT_TemplateOpener)) { +// `const ::ArrayRef a;` +// `const ::ArrayRef ` +const FormatToken *NewTok = AnalyzeTemplate(Tok, Tok->Next->Next->Next); +if (NewTok) + return NewTok; + } else if (Tok->startsSequence(QualifierType, tok::identifier) || + Tok->startsSequence(QualifierType, tok::coloncolon, + tok::identifier)) { FormatToken *Next = Tok->Next; // The case `const Foo` -> `Foo const` +// The case `const ::Foo` -> `::Foo const` // The case `const Foo *` -> `Foo const *` // The case `const Foo &` -> `Foo const &` // The case `const Foo &&` -> `Foo const &&` @@ -331,7 +351,9 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft( Tok->Next->Next && Tok->Next->Next->is(QualifierType)) { rotateTokens(SourceMgr, Fixes, Tok->Next, Tok->Next->Next, /*Left=*/true); } - if (Tok->startsSequence(tok::identifier) && Tok->Next) { + if ((Tok->startsSequence(tok::coloncolon, tok::identifier) || + Tok->is(tok::identifier)) && + Tok->Next) { if (Tok->Previous && Tok->Previous->isOneOf(tok::star, tok::ampamp, tok::amp)) { return Tok; diff --git a/clang/unittests/Format/QualifierFixerTest.cpp b/clang/unittests/Format/QualifierFixerTest.cpp index fc7e932af440..b01aff53150d 100755 --- a/clang/unittests/Format/QualifierFixerTest.cpp +++ b/clang/unittests/Format/QualifierFixerTest.cpp @@ -318,6 +318,8 @@
[clang] 573a5b5 - Revert "[clang-format] Fix WhitespaceSensitiveMacros not being honoured when macro closing parenthesis is followed by a newline."
Author: Marek Kurdej Date: 2022-05-18T07:27:45+02:00 New Revision: 573a5b58001d6dd86d404832b7b1c45a1b4f4c55 URL: https://github.com/llvm/llvm-project/commit/573a5b58001d6dd86d404832b7b1c45a1b4f4c55 DIFF: https://github.com/llvm/llvm-project/commit/573a5b58001d6dd86d404832b7b1c45a1b4f4c55.diff LOG: Revert "[clang-format] Fix WhitespaceSensitiveMacros not being honoured when macro closing parenthesis is followed by a newline." This reverts commit 50cd52d9357224cce66a9e00c9a0417c658a5655. It provoked regressions in C++ and ObjectiveC as described in https://reviews.llvm.org/D123676#3515949. Reproducers: ``` MACRO_BEGIN #if A int f(); #else int f(); #endif ``` ``` NS_SWIFT_NAME(A) @interface B : C @property(readonly) D value; @end ``` Added: Modified: clang/lib/Format/FormatTokenLexer.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index d1d236cf032b2..187b30fd55a7e 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -1027,10 +1027,7 @@ FormatToken *FormatTokenLexer::getNextToken() { Tokens.back()->Tok.getIdentifierInfo()->getPPKeywordID() == tok::pp_define) && it != Macros.end()) { - if (it->second == TT_UntouchableMacroFunc) -FormatTok->setFinalizedType(TT_UntouchableMacroFunc); - else -FormatTok->setType(it->second); + FormatTok->setType(it->second); if (it->second == TT_IfMacro) { // The lexer token currently has type tok::kw_unknown. However, for this // substitution to be treated correctly in the TokenAnnotator, faking diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index bde543131931e..be081a9189600 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1839,8 +1839,7 @@ void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind, : CommentsBeforeNextToken.front()->NewlinesBefore > 0; if (FollowedByNewline && (Text.size() >= 5 || FunctionLike) && -tokenCanStartNewLine(*FormatTok) && Text == Text.upper() && -!PreviousToken->isTypeFinalized()) { +tokenCanStartNewLine(*FormatTok) && Text == Text.upper()) { PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro); addUnwrappedLine(); return; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 22c46a129403b..e54a6db2ca46b 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -23661,11 +23661,6 @@ TEST_F(FormatTest, WhitespaceSensitiveMacros) { // Don't use the helpers here, since 'mess up' will change the whitespace // and these are all whitespace sensitive by definition - - // Newlines are important here. - EXPECT_EQ("FOO(1+2 );\n", format("FOO(1+2 );\n", Style)); - EXPECT_EQ("FOO(1+2 )\n", format("FOO(1+2 )\n", Style)); - EXPECT_EQ("FOO(String-ized+But(: :Still)=Intentional);", format("FOO(String-ized+But(: :Still)=Intentional);", Style)); EXPECT_EQ( ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e57f578 - [clang-format] fix alignment w/o binpacked args
Author: Gregory Fong Date: 2022-05-16T10:25:06+02:00 New Revision: e57f57841fbb0cd1d1dbd3237c2cbe6ce15984dd URL: https://github.com/llvm/llvm-project/commit/e57f57841fbb0cd1d1dbd3237c2cbe6ce15984dd DIFF: https://github.com/llvm/llvm-project/commit/e57f57841fbb0cd1d1dbd3237c2cbe6ce15984dd.diff LOG: [clang-format] fix alignment w/o binpacked args The combination of - AlignConsecutiveAssignments.Enabled = true - BinPackArguments = false would result in the first continuation line of a braced-init-list being improperly indented (missing a shift) when in a continued function call. Indentation was also wrong for braced-init-lists continuing a direct-list-initialization. Check for opening braced lists in continuation and ensure that the correct shift occurs. Fixes https://github.com/llvm/llvm-project/issues/55360 Reviewed By: curdeius Differential Revision: https://reviews.llvm.org/D125162 Added: Modified: clang/lib/Format/WhitespaceManager.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 673af51d2daa..f20383800ab4 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -371,6 +371,9 @@ AlignTokenSequence(const FormatStyle , unsigned Start, unsigned End, return false; if (Changes[ScopeStart].NewlinesBefore > 0) return false; + if (Changes[i].Tok->is(tok::l_brace) && + Changes[i].Tok->is(BK_BracedInit)) +return true; return Style.BinPackArguments; } @@ -387,6 +390,14 @@ AlignTokenSequence(const FormatStyle , unsigned Start, unsigned End, Changes[i].Tok->Previous->is(TT_ConditionalExpr)) return true; +// Continued direct-list-initialization using braced list. +if (ScopeStart > Start + 1 && +Changes[ScopeStart - 2].Tok->is(tok::identifier) && +Changes[ScopeStart - 1].Tok->is(tok::l_brace) && +Changes[i].Tok->is(tok::l_brace) && +Changes[i].Tok->is(BK_BracedInit)) + return true; + // Continued braced list. if (ScopeStart > Start + 1 && Changes[ScopeStart - 2].Tok->isNot(tok::identifier) && diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 44da34001f99..22c46a129403 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -17318,6 +17318,23 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) { // "ccc ? a : b,\n" // "dd);", // Alignment); + + // Confirm proper handling of AlignConsecutiveAssignments with + // BinPackArguments. + // See https://llvm.org/PR55360 + Alignment = getLLVMStyleWithColumns(50); + Alignment.AlignConsecutiveAssignments.Enabled = true; + Alignment.BinPackArguments = false; + verifyFormat("int a_long_name = 1;\n" + "auto b = B({a_long_name, a_long_name},\n" + "{a_longer_name_for_wrap,\n" + " a_longer_name_for_wrap});", + Alignment); + verifyFormat("int a_long_name = 1;\n" + "auto b = B{{a_long_name, a_long_name},\n" + "{a_longer_name_for_wrap,\n" + " a_longer_name_for_wrap}};", + Alignment); } TEST_F(FormatTest, AlignConsecutiveBitFields) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e20bc89 - [clang-format] Fix PointerAlignment: Right not working with tab indentation.
Author: Marek Kurdej Date: 2022-05-16T09:42:20+02:00 New Revision: e20bc892b6facc56fffc012929157888bb798bed URL: https://github.com/llvm/llvm-project/commit/e20bc892b6facc56fffc012929157888bb798bed DIFF: https://github.com/llvm/llvm-project/commit/e20bc892b6facc56fffc012929157888bb798bed.diff LOG: [clang-format] Fix PointerAlignment: Right not working with tab indentation. Fixes https://github.com/llvm/llvm-project/issues/55407. Given configuration: ``` UseTab: Always PointerAlignment: Right AlignConsecutiveDeclarations: true ``` Before, the pointer was misaligned in this code: ``` void f() { unsigned long long big; char *ptr; // misaligned inti; } ``` That was due to the fact that when handling right-aligned pointers, the Spaces were changed but StartOfTokenColumn was not. Also, a tab was used not only for indentation but for spacing too when using `UseTab: ForIndentation` config option: ``` void f() { unsigned long long big; char *ptr; // \t after char inti; } ``` Reviewed By: owenpan Differential Revision: https://reviews.llvm.org/D125528 Added: Modified: clang/lib/Format/WhitespaceManager.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 8563312b45bb0..673af51d2daae 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -432,6 +432,7 @@ AlignTokenSequence(const FormatStyle , unsigned Start, unsigned End, --Previous) { Changes[Previous + 1].Spaces -= Shift; Changes[Previous].Spaces += Shift; +Changes[Previous].StartOfTokenColumn += Shift; } } } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index e4fea9085b574..44da34001f990 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -14161,6 +14161,21 @@ TEST_F(FormatTest, ConfigurableUseOfTab) { "int ; // x\n", Tab); + FormatStyle TabAlignment = Tab; + TabAlignment.AlignConsecutiveDeclarations.Enabled = true; + TabAlignment.PointerAlignment = FormatStyle::PAS_Left; + verifyFormat("unsigned long long big;\n" + "char*\t\t ptr;", + TabAlignment); + TabAlignment.PointerAlignment = FormatStyle::PAS_Middle; + verifyFormat("unsigned long long big;\n" + "char *\t\t ptr;", + TabAlignment); + TabAlignment.PointerAlignment = FormatStyle::PAS_Right; + verifyFormat("unsigned long long big;\n" + "char\t\t *ptr;", + TabAlignment); + Tab.TabWidth = 4; Tab.IndentWidth = 8; verifyFormat("class TabWidth4Indent8 {\n" @@ -14203,6 +14218,26 @@ TEST_F(FormatTest, ConfigurableUseOfTab) { " \t */", Tab)); + TabAlignment.UseTab = FormatStyle::UT_ForIndentation; + TabAlignment.PointerAlignment = FormatStyle::PAS_Left; + verifyFormat("void f() {\n" + "\tunsigned long long big;\n" + "\tchar* ptr;\n" + "}", + TabAlignment); + TabAlignment.PointerAlignment = FormatStyle::PAS_Middle; + verifyFormat("void f() {\n" + "\tunsigned long long big;\n" + "\tchar * ptr;\n" + "}", + TabAlignment); + TabAlignment.PointerAlignment = FormatStyle::PAS_Right; + verifyFormat("void f() {\n" + "\tunsigned long long big;\n" + "\tchar *ptr;\n" + "}", + TabAlignment); + Tab.UseTab = FormatStyle::UT_ForIndentation; verifyFormat("{\n" "\t();\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] dab5e10 - [clang-format] fix nested angle brackets parse inside concept definition
Author: Sergey Semushin Date: 2022-05-11T14:02:51+02:00 New Revision: dab5e10ea5dbc2e6314e0e7ce54a9c51fbcb44bd URL: https://github.com/llvm/llvm-project/commit/dab5e10ea5dbc2e6314e0e7ce54a9c51fbcb44bd DIFF: https://github.com/llvm/llvm-project/commit/dab5e10ea5dbc2e6314e0e7ce54a9c51fbcb44bd.diff LOG: [clang-format] fix nested angle brackets parse inside concept definition Due to how parseBracedList always stopped on the first closing angle bracket and was used in parsing angle bracketed expression inside concept definition, nested brackets inside concepts were parsed incorrectly. nextToken() call before calling parseBracedList is required because we were processing opening angle bracket inside parseBracedList second time leading to incorrect logic after my fix. Fixes https://github.com/llvm/llvm-project/issues/54943 Fixes https://github.com/llvm/llvm-project/issues/54837 Reviewed By: HazardyKnusperkeks, curdeius Differential Revision: https://reviews.llvm.org/D123896 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index f13e3d725cbd3..f90e8fcb834c7 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2180,7 +2180,8 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons, parseBracedList(); break; case tok::less: - if (Style.Language == FormatStyle::LK_Proto) { + if (Style.Language == FormatStyle::LK_Proto || + ClosingBraceKind == tok::greater) { nextToken(); parseBracedList(/*ContinueOnSemicolons=*/false, /*IsEnum=*/false, /*ClosingBraceKind=*/tok::greater); @@ -3220,6 +3221,7 @@ void UnwrappedLineParser::parseConstraintExpression() { if (!FormatTok->is(tok::less)) return; + nextToken(); parseBracedList(/*ContinueOnSemicolons=*/false, /*IsEnum=*/false, /*ClosingBraceKind=*/tok::greater); break; @@ -3260,9 +3262,11 @@ void UnwrappedLineParser::parseConstraintExpression() { // Read identifier with optional template declaration. nextToken(); - if (FormatTok->is(tok::less)) + if (FormatTok->is(tok::less)) { +nextToken(); parseBracedList(/*ContinueOnSemicolons=*/false, /*IsEnum=*/false, /*ClosingBraceKind=*/tok::greater); + } break; } } while (!eof()); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 78f7eee809c4d..8f9c7215d6193 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -24114,6 +24114,12 @@ TEST_F(FormatTest, Concepts) { verifyFormat("template \n" "concept Same = __is_same_as;"); + verifyFormat( + "template \n" + "concept _Can_reread_dest =\n" + "std::forward_iterator<_OutIt> &&\n" + "std::same_as, std::iter_value_t<_OutIt>>;"); + auto Style = getLLVMStyle(); Style.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Allowed; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 3d2c3a498c724..138cab9b6b257 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -390,6 +390,18 @@ TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) { EXPECT_TOKEN(Tokens[21], tok::r_brace, TT_Unknown); EXPECT_EQ(Tokens[21]->MatchingParen, Tokens[15]); EXPECT_TRUE(Tokens[21]->ClosesRequiresClause); + + Tokens = + annotate("template concept C =" + "std::same_as, std::iter_value_t>;"); + ASSERT_EQ(Tokens.size(), 31u) << Tokens; + EXPECT_TOKEN(Tokens[8], tok::kw_concept, TT_Unknown); + EXPECT_TOKEN(Tokens[14], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[18], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[20], tok::greater, TT_TemplateCloser); + EXPECT_TOKEN(Tokens[25], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[27], tok::greater, TT_TemplateCloser); + EXPECT_TOKEN(Tokens[28], tok::greater, TT_TemplateCloser); } TEST_F(TokenAnnotatorTest, UnderstandsRequiresExpressions) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 85ec8a9 - [clang-format] Correctly handle SpaceBeforeParens for builtins.
Author: Marek Kurdej Date: 2022-05-09T11:42:41+02:00 New Revision: 85ec8a9ac141a1807d907b7514546f531007d87d URL: https://github.com/llvm/llvm-project/commit/85ec8a9ac141a1807d907b7514546f531007d87d DIFF: https://github.com/llvm/llvm-project/commit/85ec8a9ac141a1807d907b7514546f531007d87d.diff LOG: [clang-format] Correctly handle SpaceBeforeParens for builtins. That's a partial fix for https://github.com/llvm/llvm-project/issues/55292. Before, known builtins behaved differently from other identifiers: ``` void f () { return F (__builtin_LINE() + __builtin_FOO ()); } ``` After: ``` void f () { return F (__builtin_LINE () + __builtin_FOO ()); } ``` Reviewed By: owenpan Differential Revision: https://reviews.llvm.org/D125085 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 8cbe157b1fb21..68f35643bbf2f 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3436,9 +3436,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine , return (Style.SpaceBeforeParens != FormatStyle::SBPO_Never) || spaceRequiredBeforeParens(Right); } +// Handle builtins like identifiers. if (Line.Type != LT_PreprocessorDirective && -(Left.is(tok::identifier) || Left.isFunctionLikeKeyword() || - Left.is(tok::r_paren) || Left.isSimpleTypeSpecifier())) +(Left.Tok.getIdentifierInfo() || Left.is(tok::r_paren))) return spaceRequiredBeforeParens(Right); return false; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 98da4f773de95..78f7eee809c4d 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -15082,6 +15082,9 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { // verifyFormat("X A::operator++ (T);", Space); verifyFormat("auto lambda = [] () { return 0; };", Space); verifyFormat("int x = int (y);", Space); + verifyFormat("#define F(...) __VA_OPT__ (__VA_ARGS__)", Space); + verifyFormat("__builtin_LINE ()", Space); + verifyFormat("__builtin_UNKNOWN ()", Space); FormatStyle SomeSpace = getLLVMStyle(); SomeSpace.SpaceBeforeParens = FormatStyle::SBPO_NonEmptyParentheses; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 50cd52d - [clang-format] Fix WhitespaceSensitiveMacros not being honoured when macro closing parenthesis is followed by a newline.
Author: Marek Kurdej Date: 2022-05-09T10:59:33+02:00 New Revision: 50cd52d9357224cce66a9e00c9a0417c658a5655 URL: https://github.com/llvm/llvm-project/commit/50cd52d9357224cce66a9e00c9a0417c658a5655 DIFF: https://github.com/llvm/llvm-project/commit/50cd52d9357224cce66a9e00c9a0417c658a5655.diff LOG: [clang-format] Fix WhitespaceSensitiveMacros not being honoured when macro closing parenthesis is followed by a newline. Fixes https://github.com/llvm/llvm-project/issues/54522. This fixes regression introduced in https://github.com/llvm/llvm-project/commit/5e5efd8a91f2e340e79a73bedbc6ab66ad4a4281. Before the culprit commit, macros in WhitespaceSensitiveMacros were correctly formatted even if their closing parenthesis weren't followed by semicolon (or, to be precise, when they were followed by a newline). That commit changed the type of the macro token type from TT_UntouchableMacroFunc to TT_FunctionLikeOrFreestandingMacro. Correct formatting (with `WhitespaceSensitiveMacros = ['FOO']`): ``` FOO(1+2) FOO(1+2); ``` Regressed formatting: ``` FOO(1 + 2) FOO(1+2); ``` Reviewed By: HazardyKnusperkeks, owenpan, ksyx Differential Revision: https://reviews.llvm.org/D123676 Added: Modified: clang/lib/Format/FormatTokenLexer.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index 187b30fd55a7e..d1d236cf032b2 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -1027,7 +1027,10 @@ FormatToken *FormatTokenLexer::getNextToken() { Tokens.back()->Tok.getIdentifierInfo()->getPPKeywordID() == tok::pp_define) && it != Macros.end()) { - FormatTok->setType(it->second); + if (it->second == TT_UntouchableMacroFunc) +FormatTok->setFinalizedType(TT_UntouchableMacroFunc); + else +FormatTok->setType(it->second); if (it->second == TT_IfMacro) { // The lexer token currently has type tok::kw_unknown. However, for this // substitution to be treated correctly in the TokenAnnotator, faking diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 52ce0fff251c2..f13e3d725cbd3 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1787,7 +1787,8 @@ void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind, : CommentsBeforeNextToken.front()->NewlinesBefore > 0; if (FollowedByNewline && (Text.size() >= 5 || FunctionLike) && -tokenCanStartNewLine(*FormatTok) && Text == Text.upper()) { +tokenCanStartNewLine(*FormatTok) && Text == Text.upper() && +!PreviousToken->isTypeFinalized()) { PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro); addUnwrappedLine(); return; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index d7d69f950a323..98da4f773de95 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -23606,6 +23606,11 @@ TEST_F(FormatTest, WhitespaceSensitiveMacros) { // Don't use the helpers here, since 'mess up' will change the whitespace // and these are all whitespace sensitive by definition + + // Newlines are important here. + EXPECT_EQ("FOO(1+2 );\n", format("FOO(1+2 );\n", Style)); + EXPECT_EQ("FOO(1+2 )\n", format("FOO(1+2 )\n", Style)); + EXPECT_EQ("FOO(String-ized+But(: :Still)=Intentional);", format("FOO(String-ized+But(: :Still)=Intentional);", Style)); EXPECT_EQ( ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c819dce - [clang-format] Add a regression test for aligning macros with keywords.
Author: Marek Kurdej Date: 2022-05-03T11:09:38+02:00 New Revision: c819dce2d304817ae7f47628067092f4353a148e URL: https://github.com/llvm/llvm-project/commit/c819dce2d304817ae7f47628067092f4353a148e DIFF: https://github.com/llvm/llvm-project/commit/c819dce2d304817ae7f47628067092f4353a148e.diff LOG: [clang-format] Add a regression test for aligning macros with keywords. Test from issue https://github.com/llvm/llvm-project/issues/54953. Added: Modified: clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index da25395b7df49..37f32691a1d36 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -16030,6 +16030,10 @@ TEST_F(FormatTest, AlignConsecutiveMacros) { "#define ccc (5)", Style); + verifyFormat("#define true 1\n" + "#define false 0", + Style); + verifyFormat("#define f(x) (x * x)\n" "#define fff(x, y, z) (x * y + z)\n" "#define (x, y) (x - y)", ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b58616c - [clang-format] Fix SeparateDefinitionBlocks breaking up function-try-block.
Author: Marek Kurdej Date: 2022-04-13T16:44:04+02:00 New Revision: b58616c2cdf70e075b887a66edf6bbc568e2ff99 URL: https://github.com/llvm/llvm-project/commit/b58616c2cdf70e075b887a66edf6bbc568e2ff99 DIFF: https://github.com/llvm/llvm-project/commit/b58616c2cdf70e075b887a66edf6bbc568e2ff99.diff LOG: [clang-format] Fix SeparateDefinitionBlocks breaking up function-try-block. Fixes https://github.com/llvm/llvm-project/issues/54536. Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D122468 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/DefinitionBlockSeparatorTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index c5594a6d66484..018a7ae3ee794 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2603,6 +2603,7 @@ void UnwrappedLineParser::parseTryCatch() { nextToken(); } NeedsUnwrappedLine = false; +Line->MustBeDeclaration = false; CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(); if (Style.BraceWrapping.BeforeCatch) diff --git a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp index 53a3c57ad59fa..cb24cc921bc05 100644 --- a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp +++ b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp @@ -43,7 +43,8 @@ class DefinitionBlockSeparatorTest : public ::testing::Test { static void _verifyFormat(const char *File, int Line, llvm::StringRef Code, const FormatStyle = getLLVMStyle(), -llvm::StringRef ExpectedCode = "") { +llvm::StringRef ExpectedCode = "", +bool Inverse = true) { ::testing::ScopedTrace t(File, Line, ::testing::Message() << Code.str()); bool HasOriginalCode = true; if (ExpectedCode == "") { @@ -51,16 +52,18 @@ class DefinitionBlockSeparatorTest : public ::testing::Test { HasOriginalCode = false; } -FormatStyle InverseStyle = Style; -if (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always) - InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never; -else - InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always; EXPECT_EQ(ExpectedCode, separateDefinitionBlocks(ExpectedCode, Style)) << "Expected code is not stable"; -EXPECT_NE(ExpectedCode, - separateDefinitionBlocks(ExpectedCode, InverseStyle)) -<< "Inverse formatting makes no diff erence"; +if (Inverse) { + FormatStyle InverseStyle = Style; + if (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always) +InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never; + else +InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always; + EXPECT_NE(ExpectedCode, +separateDefinitionBlocks(ExpectedCode, InverseStyle)) + << "Inverse formatting makes no diff erence"; +} std::string CodeToFormat = HasOriginalCode ? Code.str() : removeEmptyLines(Code); std::string Result = separateDefinitionBlocks(CodeToFormat, Style); @@ -448,6 +451,32 @@ TEST_F(DefinitionBlockSeparatorTest, OpeningBracketOwnsLine) { Style); } +TEST_F(DefinitionBlockSeparatorTest, TryBlocks) { + FormatStyle Style = getLLVMStyle(); + Style.BreakBeforeBraces = FormatStyle::BS_Allman; + Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always; + verifyFormat("void FunctionWithInternalTry()\n" + "{\n" + " try\n" + " {\n" + "return;\n" + " }\n" + " catch (const std::exception &)\n" + " {\n" + " }\n" + "}", + Style, "", /*Inverse=*/false); + verifyFormat("void FunctionWithTryBlock()\n" + "try\n" + "{\n" + " return;\n" + "}\n" + "catch (const std::exception &)\n" + "{\n" + "}", + Style, "", /*Inverse=*/false); +} + TEST_F(DefinitionBlockSeparatorTest, Leave) { FormatStyle Style = getLLVMStyle(); Style.SeparateDefinitionBlocks = FormatStyle::SDS_Leave; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 311a00c - [clang-format] Clean up DefinitionBlockSeparatorTest. NFC.
Author: Marek Kurdej Date: 2022-03-25T10:59:46+01:00 New Revision: 311a00c39046ed3f84cd31ffcd513975d3000402 URL: https://github.com/llvm/llvm-project/commit/311a00c39046ed3f84cd31ffcd513975d3000402 DIFF: https://github.com/llvm/llvm-project/commit/311a00c39046ed3f84cd31ffcd513975d3000402.diff LOG: [clang-format] Clean up DefinitionBlockSeparatorTest. NFC. Added: Modified: clang/unittests/Format/DefinitionBlockSeparatorTest.cpp Removed: diff --git a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp index 582b62e445df9..53a3c57ad59fa 100644 --- a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp +++ b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp @@ -56,17 +56,15 @@ class DefinitionBlockSeparatorTest : public ::testing::Test { InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never; else InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always; -EXPECT_EQ(ExpectedCode.str(), separateDefinitionBlocks(ExpectedCode, Style)) +EXPECT_EQ(ExpectedCode, separateDefinitionBlocks(ExpectedCode, Style)) << "Expected code is not stable"; -std::string InverseResult = -separateDefinitionBlocks(ExpectedCode, InverseStyle); -EXPECT_NE(ExpectedCode.str(), InverseResult) +EXPECT_NE(ExpectedCode, + separateDefinitionBlocks(ExpectedCode, InverseStyle)) << "Inverse formatting makes no diff erence"; std::string CodeToFormat = HasOriginalCode ? Code.str() : removeEmptyLines(Code); std::string Result = separateDefinitionBlocks(CodeToFormat, Style); -EXPECT_EQ(ExpectedCode.str(), Result) << "Test failed. Formatted:\n" - << Result; +EXPECT_EQ(ExpectedCode, Result) << "Test failed. Formatted:\n" << Result; } static std::string removeEmptyLines(llvm::StringRef Code) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 4e88cb6 - [clang-format] Handle attributes before case label. Relanded.
Author: Marek Kurdej Date: 2022-03-23T16:24:24+01:00 New Revision: 4e88cb6825eefca3c0eb66b5ae40ab123fcc7073 URL: https://github.com/llvm/llvm-project/commit/4e88cb6825eefca3c0eb66b5ae40ab123fcc7073 DIFF: https://github.com/llvm/llvm-project/commit/4e88cb6825eefca3c0eb66b5ae40ab123fcc7073.diff LOG: [clang-format] Handle attributes before case label. Relanded. Fixes https://github.com/llvm/llvm-project/issues/53110. Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D121450 Relanding as the original patch provoked an infinite loop in JavaScript/TypeScript. A reproducer test case was added and the issue fixed. Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/lib/Format/UnwrappedLineParser.h clang/unittests/Format/FormatTest.cpp clang/unittests/Format/FormatTestJS.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 36205b8ee18cd..8052eb932141d 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -480,6 +480,10 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace, unsigned StatementCount = 0; bool SwitchLabelEncountered = false; do { +if (FormatTok->getType() == TT_AttributeMacro) { + nextToken(); + continue; +} tok::TokenKind kind = FormatTok->Tok.getKind(); if (FormatTok->getType() == TT_MacroBlockBegin) kind = tok::l_brace; @@ -569,6 +573,8 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace, parseCSharpAttribute(); break; } + if (handleCppAttributes()) +break; LLVM_FALLTHROUGH; default: ParseDefault(); @@ -1397,9 +1403,11 @@ void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind, // e.g. "default void f() {}" in a Java interface. break; case tok::kw_case: -if (Style.isJavaScript() && Line->MustBeDeclaration) +if (Style.isJavaScript() && Line->MustBeDeclaration) { // 'case: string' field declaration. + nextToken(); break; +} parseCaseLabel(); return; case tok::kw_try: @@ -1820,6 +1828,14 @@ void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind, case tok::kw_new: parseNew(); break; +case tok::kw_case: + if (Style.isJavaScript() && Line->MustBeDeclaration) { +// 'case: string' field declaration. +nextToken(); +break; + } + parseCaseLabel(); + break; default: nextToken(); break; @@ -2388,17 +2404,24 @@ static void markOptionalBraces(FormatToken *LeftBrace) { RightBrace->Optional = true; } +void UnwrappedLineParser::handleAttributes() { + // Handle AttributeMacro, e.g. `if (x) UNLIKELY`. + if (FormatTok->is(TT_AttributeMacro)) +nextToken(); + handleCppAttributes(); +} + +bool UnwrappedLineParser::handleCppAttributes() { + // Handle [[likely]] / [[unlikely]] attributes. + if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute()) { +parseSquare(); +return true; + } + return false; +} + FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces) { - auto HandleAttributes = [this]() { -// Handle AttributeMacro, e.g. `if (x) UNLIKELY`. -if (FormatTok->is(TT_AttributeMacro)) - nextToken(); -// Handle [[likely]] / [[unlikely]] attributes. -if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute()) - parseSquare(); - }; - assert(FormatTok->is(tok::kw_if) && "'if' expected"); nextToken(); if (FormatTok->is(tok::exclaim)) @@ -2411,7 +2434,7 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind, if (FormatTok->is(tok::l_paren)) parseParens(); } - HandleAttributes(); + handleAttributes(); bool NeedsUnwrappedLine = false; keepAncestorBraces(); @@ -2448,7 +2471,7 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind, Kind = IfStmtKind::IfElse; } nextToken(); -HandleAttributes(); +handleAttributes(); if (FormatTok->is(tok::l_brace)) { ElseLeftBrace = FormatTok; CompoundStatementIndenter Indenter(this, Style, Line->Level); diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index 5cc01398a5457..798bae24ad075 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -121,6 +121,8 @@ class UnwrappedLineParser { void parseSquare(bool LambdaIntroducer = false); void keepAncestorBraces(); void parseUnbracedBody(bool CheckEOF = false); + void handleAttributes(); + bool handleCppAttributes(); FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false); void parseTryCatch();
[clang] a45ad3c - [clang-format] [doc] Add script to automatically update help output in ClangFormat.rst.
Author: Marek Kurdej Date: 2022-03-23T13:17:50+01:00 New Revision: a45ad3ca8ce78988a4d51b432455ce0bbf13 URL: https://github.com/llvm/llvm-project/commit/a45ad3ca8ce78988a4d51b432455ce0bbf13 DIFF: https://github.com/llvm/llvm-project/commit/a45ad3ca8ce78988a4d51b432455ce0bbf13.diff LOG: [clang-format] [doc] Add script to automatically update help output in ClangFormat.rst. Fixes https://github.com/llvm/llvm-project/issues/54418. Reviewed By: MyDeveloperDay Differential Revision: https://reviews.llvm.org/D121916 Added: clang/docs/tools/dump_format_help.py Modified: clang/docs/ClangFormat.rst clang/tools/clang-format/ClangFormat.cpp Removed: diff --git a/clang/docs/ClangFormat.rst b/clang/docs/ClangFormat.rst index 5fc9656a4756a..745c66efa9e0e 100644 --- a/clang/docs/ClangFormat.rst +++ b/clang/docs/ClangFormat.rst @@ -13,6 +13,8 @@ Standalone Tool :program:`clang-format` is located in `clang/tools/clang-format` and can be used to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# code. +.. START_FORMAT_HELP + .. code-block:: console $ clang-format -help @@ -51,7 +53,9 @@ to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# code. -style=file, but can not find the .clang-format file to use. Use -fallback-style=none to skip formatting. ---ferror-limit= - Set the maximum number of clang-format errors to emit before stopping (0 = no limit). Used only with --dry-run or -n +--ferror-limit= - Set the maximum number of clang-format errors to emit + before stopping (0 = no limit). + Used only with --dry-run or -n --files= - Provide a list of files to run clang-format -i - Inplace edit s, if specified. --length=- Format a range of this length (in bytes). @@ -73,8 +77,10 @@ to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# code. several -offset and -length pairs. Can only be used with one input file. --output-replacements-xml - Output replacements as XML. ---qualifier-alignment= - If set, overrides the qualifier alignment style determined by the QualifierAlignment style flag ---sort-includes- If set, overrides the include sorting behavior determined by the SortIncludes style flag +--qualifier-alignment= - If set, overrides the qualifier alignment style + determined by the QualifierAlignment style flag +--sort-includes- If set, overrides the include sorting behavior + determined by the SortIncludes style flag --style= - Coding style, currently supports: LLVM, GNU, Google, Chromium, Microsoft, Mozilla, WebKit. Use -style=file to load style configuration from @@ -95,6 +101,8 @@ to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# code. --version - Display the version of this program +.. END_FORMAT_HELP + When the desired code formatting style is diff erent from the available options, the style can be customized using the ``-style="{key: value, ...}"`` option or by putting your style configuration in the ``.clang-format`` or ``_clang-format`` diff --git a/clang/docs/tools/dump_format_help.py b/clang/docs/tools/dump_format_help.py new file mode 100644 index 0..68869d91056ce --- /dev/null +++ b/clang/docs/tools/dump_format_help.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# A tool to parse the output of `clang-format --help` and update the +# documentation in ../ClangFormat.rst automatically. + +import os +import re +import subprocess +import sys + +CLANG_DIR = os.path.join(os.path.dirname(__file__), '../..') +DOC_FILE = os.path.join(CLANG_DIR, 'docs/ClangFormat.rst') + + +def substitute(text, tag, contents): +replacement = '\n.. START_%s\n\n%s\n\n.. END_%s\n' % (tag, contents, tag) +pattern = r'\n\.\. START_%s\n.*\n\.\. END_%s\n' % (tag, tag) +return re.sub(pattern, '%s', text, flags=re.S) % replacement + + +def indent(text, columns, indent_first_line=True): +indent_str = ' ' * columns +s = re.sub(r'\n([^\n])', '\n' + indent_str + '\\1', text, flags=re.S) +if not indent_first_line or s.startswith('\n'): +return s +return indent_str + s + + +def get_help_output(): +args = ["clang-format", "--help"] +cmd = subprocess.Popen(args, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) +out, _ = cmd.communicate() +out =
[clang] 73a15ad - [clang-format] [doc] Improve BraceWrapping documentation.
Author: Marek Kurdej Date: 2022-03-21T10:25:12+01:00 New Revision: 73a15ad567071c13e761fd6d593e2b66164865e2 URL: https://github.com/llvm/llvm-project/commit/73a15ad567071c13e761fd6d593e2b66164865e2 DIFF: https://github.com/llvm/llvm-project/commit/73a15ad567071c13e761fd6d593e2b66164865e2.diff LOG: [clang-format] [doc] Improve BraceWrapping documentation. Added: Modified: clang/include/clang/Format/Format.h Removed: diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index eb53d7987dbd2..d815eb1165bb3 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -1592,6 +1592,7 @@ struct FormatStyle { /// set, and the function could/should not be put on a single line (as per /// `AllowShortFunctionsOnASingleLine` and constructor formatting options). /// \code +/// false: true: /// int f() vs. int f() /// {} { /// } @@ -1603,6 +1604,7 @@ struct FormatStyle { /// brace of the record has already been wrapped, i.e. the `AfterClass` /// (for classes) brace wrapping mode is set. /// \code +/// false: true: /// class Foo vs. class Foo /// {} { ///} @@ -1614,6 +1616,7 @@ struct FormatStyle { /// already been wrapped, i.e. the `AfterNamespace` brace wrapping mode is /// set. /// \code +/// false: true: /// namespace Foo vs. namespace Foo /// {} { ///} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 9dad527 - [clang-format] Use range-for loop with drop_end. NFC.
Author: Marek Kurdej Date: 2022-03-21T10:05:06+01:00 New Revision: 9dad527fc048e9f6df6783abb1d6251e77f12199 URL: https://github.com/llvm/llvm-project/commit/9dad527fc048e9f6df6783abb1d6251e77f12199 DIFF: https://github.com/llvm/llvm-project/commit/9dad527fc048e9f6df6783abb1d6251e77f12199.diff LOG: [clang-format] Use range-for loop with drop_end. NFC. Added: Modified: clang/lib/Format/ContinuationIndenter.cpp Removed: diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 69508c44dc436..e3d54a0ba42a4 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -954,8 +954,8 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState , (Current.MatchingParen && Current.MatchingParen->is(TT_RequiresExpressionLBrace)); if (!NestedBlockSpecialCase) -for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) - State.Stack[i].BreakBeforeParameter = true; +for (ParenState : llvm::drop_end(State.Stack)) + PState.BreakBeforeParameter = true; if (PreviousNonComment && !PreviousNonComment->isOneOf(tok::comma, tok::colon, tok::semi) && @@ -1340,8 +1340,8 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState , !Previous->is(TT_DictLiteral) && State.Stack.size() > 1 && !CurrentState.HasMultipleNestedBlocks) { if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline) - for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) -State.Stack[i].NoLineBreak = true; + for (ParenState : llvm::drop_end(State.Stack)) +PState.NoLineBreak = true; State.Stack[State.Stack.size() - 2].NestedBlockInlined = false; } if (Previous && (Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) || ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c59c2b6 - [clang-format] Refactor ShouldBreakBeforeBrace to use switch. NFC.
Author: Marek Kurdej Date: 2022-03-18T15:16:01+01:00 New Revision: c59c2b6bd19eb7625f7c234eb68d347d8de17079 URL: https://github.com/llvm/llvm-project/commit/c59c2b6bd19eb7625f7c234eb68d347d8de17079 DIFF: https://github.com/llvm/llvm-project/commit/c59c2b6bd19eb7625f7c234eb68d347d8de17079.diff LOG: [clang-format] Refactor ShouldBreakBeforeBrace to use switch. NFC. Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index cadf1960dbf7a..bef8ed54fab8a 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -897,17 +897,24 @@ static bool isIIFE(const UnwrappedLine , static bool ShouldBreakBeforeBrace(const FormatStyle , const FormatToken ) { - if (InitialToken.isOneOf(tok::kw_namespace, TT_NamespaceMacro)) + tok::TokenKind Kind = InitialToken.Tok.getKind(); + if (InitialToken.is(TT_NamespaceMacro)) +Kind = tok::kw_namespace; + + switch (Kind) { + case tok::kw_namespace: return Style.BraceWrapping.AfterNamespace; - if (InitialToken.is(tok::kw_class)) + case tok::kw_class: return Style.BraceWrapping.AfterClass; - if (InitialToken.is(tok::kw_union)) + case tok::kw_union: return Style.BraceWrapping.AfterUnion; - if (InitialToken.is(tok::kw_struct)) + case tok::kw_struct: return Style.BraceWrapping.AfterStruct; - if (InitialToken.is(tok::kw_enum)) + case tok::kw_enum: return Style.BraceWrapping.AfterEnum; - return false; + default: +return false; + } } void UnwrappedLineParser::parseChildBlock( ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c79e18d - [clang-format] Expect instead of setting the same value in tests. NFC.
Author: Marek Kurdej Date: 2022-03-18T15:01:41+01:00 New Revision: c79e18da4f65c43bb8d94e95961e87e66d67b65a URL: https://github.com/llvm/llvm-project/commit/c79e18da4f65c43bb8d94e95961e87e66d67b65a DIFF: https://github.com/llvm/llvm-project/commit/c79e18da4f65c43bb8d94e95961e87e66d67b65a.diff LOG: [clang-format] Expect instead of setting the same value in tests. NFC. Added: Modified: clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 4ef4c9a8612a7..e36a267c01f4b 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2767,7 +2767,8 @@ TEST_F(FormatTest, CaseRanges) { TEST_F(FormatTest, ShortEnums) { FormatStyle Style = getLLVMStyle(); - Style.AllowShortEnumsOnASingleLine = true; + EXPECT_TRUE(Style.AllowShortEnumsOnASingleLine); + EXPECT_FALSE(Style.BraceWrapping.AfterEnum); verifyFormat("enum { A, B, C } ShortEnum1, ShortEnum2;", Style); verifyFormat("typedef enum { A, B, C } ShortEnum1, ShortEnum2;", Style); Style.AllowShortEnumsOnASingleLine = false; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] acc7a7f - [clang-format] Use range-for loop. NFC.
Author: Marek Kurdej Date: 2022-03-18T15:01:41+01:00 New Revision: acc7a7f9a17f683b1bbf0a4913ebadb926e1f71b URL: https://github.com/llvm/llvm-project/commit/acc7a7f9a17f683b1bbf0a4913ebadb926e1f71b DIFF: https://github.com/llvm/llvm-project/commit/acc7a7f9a17f683b1bbf0a4913ebadb926e1f71b.diff LOG: [clang-format] Use range-for loop. NFC. Added: Modified: clang/lib/Format/TokenAnnotator.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 9c94590dc0b9a..b0d48c46340a6 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -4601,8 +4601,8 @@ void TokenAnnotator::printDebugInfo(const AnnotatedLine ) { << " BK=" << Tok->getBlockKind() << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName() << " L=" << Tok->TotalLength << " PPK=" << Tok->getPackingKind() << " FakeLParens="; -for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i) - llvm::errs() << Tok->FakeLParens[i] << "/"; +for (prec::Level LParen : Tok->FakeLParens) + llvm::errs() << LParen << "/"; llvm::errs() << " FakeRParens=" << Tok->FakeRParens; llvm::errs() << " II=" << Tok->Tok.getIdentifierInfo(); llvm::errs() << " Text='" << Tok->TokenText << "'\n"; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b6baab6 - [clang-format] Refactor BreakableBlockComment constructor. NFC.
Author: Marek Kurdej Date: 2022-03-18T15:01:40+01:00 New Revision: b6baab673a7c17747c245fa7b33d9b29ad9a107d URL: https://github.com/llvm/llvm-project/commit/b6baab673a7c17747c245fa7b33d9b29ad9a107d DIFF: https://github.com/llvm/llvm-project/commit/b6baab673a7c17747c245fa7b33d9b29ad9a107d.diff LOG: [clang-format] Refactor BreakableBlockComment constructor. NFC. Added: Modified: clang/lib/Format/BreakableToken.cpp Removed: diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index ae084e9e14544..db7361bf5f2ff 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -410,11 +410,13 @@ BreakableBlockComment::BreakableBlockComment( } for (size_t i = 1, e = Content.size(); i < e && !Decoration.empty(); ++i) { const StringRef = Content[i]; -// If the last line is empty, the closing "*/" will have a star. -if (i + 1 == e && Text.empty()) - break; -if (!Text.empty() && i + 1 != e && Decoration.startswith(Text)) +if (i + 1 == e) { + // If the last line is empty, the closing "*/" will have a star. + if (Text.empty()) +break; +} else if (!Text.empty() && Decoration.startswith(Text)) { continue; +} while (!Text.startswith(Decoration)) Decoration = Decoration.drop_back(1); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 45cb2df - [clang-format][docs] Regenerate ClangFormatStyleOptions.rst
Author: Krystian Kuzniarek Date: 2022-03-17T09:45:43+01:00 New Revision: 45cb2df6788ca96a2ed6e9638b803563f51466f2 URL: https://github.com/llvm/llvm-project/commit/45cb2df6788ca96a2ed6e9638b803563f51466f2 DIFF: https://github.com/llvm/llvm-project/commit/45cb2df6788ca96a2ed6e9638b803563f51466f2.diff LOG: [clang-format][docs] Regenerate ClangFormatStyleOptions.rst Misalignment of clang/docs/ClangFormatStyleOptions.rst and clang/include/clang/Format/Format.h was introduced in c24b3db45. Regenerated with: python clang/docs/tools/dump_format_style.py Reviewed By: sstwcw, curdeius, HazardyKnusperkeks Differential Revision: https://reviews.llvm.org/D121749 Added: Modified: clang/docs/ClangFormatStyleOptions.rst Removed: diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index a9e35fdceb810..543e7bbf410a3 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -358,8 +358,8 @@ the configuration (without a prefix: ``Auto``). /* A comment. */ double e = 4; - * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound -assignments like ``+=`` are aligned along with ``=``. + * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound assignments +like ``+=`` are aligned along with ``=``. .. code-block:: c++ @@ -371,10 +371,9 @@ the configuration (without a prefix: ``Auto``). a &= 2; bbb = 2; - * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short -assignment operators are left-padded to the same length as long -ones in order to put all assignment operators to the right of -the left hand side. + * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment +operators are left-padded to the same length as long ones in order to +put all assignment operators to the right of the left hand side. .. code-block:: c++ @@ -482,8 +481,8 @@ the configuration (without a prefix: ``Auto``). /* A comment. */ double e = 4; - * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound -assignments like ``+=`` are aligned along with ``=``. + * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound assignments +like ``+=`` are aligned along with ``=``. .. code-block:: c++ @@ -495,10 +494,9 @@ the configuration (without a prefix: ``Auto``). a &= 2; bbb = 2; - * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short -assignment operators are left-padded to the same length as long -ones in order to put all assignment operators to the right of -the left hand side. + * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment +operators are left-padded to the same length as long ones in order to +put all assignment operators to the right of the left hand side. .. code-block:: c++ @@ -606,8 +604,8 @@ the configuration (without a prefix: ``Auto``). /* A comment. */ double e = 4; - * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound -assignments like ``+=`` are aligned along with ``=``. + * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound assignments +like ``+=`` are aligned along with ``=``. .. code-block:: c++ @@ -619,10 +617,9 @@ the configuration (without a prefix: ``Auto``). a &= 2; bbb = 2; - * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short -assignment operators are left-padded to the same length as long -ones in order to put all assignment operators to the right of -the left hand side. + * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short assignment +operators are left-padded to the same length as long ones in order to +put all assignment operators to the right of the left hand side. .. code-block:: c++ @@ -731,8 +728,8 @@ the configuration (without a prefix: ``Auto``). /* A comment. */ double e = 4; - * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound -assignments like ``+=`` are aligned along with ``=``. + * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``. Whether compound assignments +like ``+=`` are aligned along with ``=``. .. code-block:: c++ @@ -744,10 +741,9 @@ the configuration (without a prefix: ``Auto``). a &= 2; bbb = 2; - * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``. Whether short -assignment operators are left-padded to the same length as long -ones in order to put all assignment operators to the right of
[clang] dc142ea - [clang-format] Correctly recognize binary operators in template arguments with parenthesized literals.
Author: Marek Kurdej Date: 2022-03-17T09:36:25+01:00 New Revision: dc142ea184a526fb2879f84c4c82fff195d36b9d URL: https://github.com/llvm/llvm-project/commit/dc142ea184a526fb2879f84c4c82fff195d36b9d DIFF: https://github.com/llvm/llvm-project/commit/dc142ea184a526fb2879f84c4c82fff195d36b9d.diff LOG: [clang-format] Correctly recognize binary operators in template arguments with parenthesized literals. Fixes https://github.com/llvm/llvm-project/issues/24602. Before, code like `foo` was formatted correctly but `foo` wasn't. This patch fixes this inconsistency. Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D121846 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index f1ff1995c806d..9c94590dc0b9a 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2177,14 +2177,21 @@ class AnnotatingParser { if (PrevToken->Tok.isLiteral() || PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true, - tok::kw_false, tok::r_brace) || -NextToken->Tok.isLiteral() || -NextToken->isOneOf(tok::kw_true, tok::kw_false) || -NextToken->isUnaryOperator() || -// If we know we're in a template argument, there are no named -// declarations. Thus, having an identifier on the right-hand side -// indicates a binary operator. -(InTemplateArgument && NextToken->Tok.isAnyIdentifier())) + tok::kw_false, tok::r_brace)) + return TT_BinaryOperator; + +const FormatToken *NextNonParen = NextToken; +while (NextNonParen && NextNonParen->is(tok::l_paren)) + NextNonParen = NextNonParen->getNextNonComment(); +if (NextNonParen && (NextNonParen->Tok.isLiteral() || + NextNonParen->isOneOf(tok::kw_true, tok::kw_false) || + NextNonParen->isUnaryOperator())) + return TT_BinaryOperator; + +// If we know we're in a template argument, there are no named declarations. +// Thus, having an identifier on the right-hand side indicates a binary +// operator. +if (InTemplateArgument && NextToken->Tok.isAnyIdentifier()) return TT_BinaryOperator; // "&&(" is quite unlikely to be two successive unary "&". @@ -4508,12 +4515,11 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine , // We only break before r_paren if we're in a block indented context. if (Right.is(tok::r_paren)) { -if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) { +if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) return Right.MatchingParen && !(Right.MatchingParen->Previous && (Right.MatchingParen->Previous->is(tok::kw_for) || Right.MatchingParen->Previous->isIf())); -} return false; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 469252a252887..4ef4c9a8612a7 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -10333,6 +10333,11 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyFormat("vector v;"); verifyFormat("foo();"); verifyFormat("foo();"); + verifyFormat("foo();"); + verifyFormat("foo();"); + verifyFormat("foo();"); + verifyFormat("foo();"); + verifyFormat("foo();"); verifyFormat("decltype(*::std::declval()) void F();"); verifyFormat("typeof(*::std::declval()) void F();"); verifyFormat("_Atomic(*::std::declval()) void F();"); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 34ce42f - [clang-format] Reformat. NFC.
Author: Marek Kurdej Date: 2022-03-17T09:27:31+01:00 New Revision: 34ce42fe4de5318176e13e4cb758dfa7a0d8176b URL: https://github.com/llvm/llvm-project/commit/34ce42fe4de5318176e13e4cb758dfa7a0d8176b DIFF: https://github.com/llvm/llvm-project/commit/34ce42fe4de5318176e13e4cb758dfa7a0d8176b.diff LOG: [clang-format] Reformat. NFC. Added: Modified: clang/lib/Format/WhitespaceManager.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/FormatTestJson.cpp clang/unittests/Format/MacroExpanderTest.cpp clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp clang/unittests/Format/TestLexer.h Removed: diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index de6cdf4afd729..2dcc4fd62c5e8 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -1163,9 +1163,8 @@ void WhitespaceManager::alignArrayInitializersLeftJustified( auto Offset = std::distance(Cells.begin(), CellIter); for (const auto *Next = CellIter->NextColumnElement; Next != nullptr; Next = Next->NextColumnElement) { - if (RowCount > CellDescs.CellCounts.size()) { + if (RowCount > CellDescs.CellCounts.size()) break; - } auto *Start = (Cells.begin() + RowCount * CellDescs.CellCounts[0]); auto *End = Start + Offset; auto ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 8ee6040cd0f69..469252a252887 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -7217,9 +7217,8 @@ TEST_F(FormatTest, MemoizationTests) { OnePerLine.BinPackParameters = false; std::string input = "Constructor()\n" ": (a,\n"; - for (unsigned i = 0, e = 80; i != e; ++i) { + for (unsigned i = 0, e = 80; i != e; ++i) input += " a,\n"; - } input += " a) {}"; verifyFormat(input, OnePerLine); } diff --git a/clang/unittests/Format/FormatTestJson.cpp b/clang/unittests/Format/FormatTestJson.cpp index 14a48182f9dfe..e213f6bcbe712 100644 --- a/clang/unittests/Format/FormatTestJson.cpp +++ b/clang/unittests/Format/FormatTestJson.cpp @@ -30,14 +30,12 @@ class FormatTestJson : public ::testing::Test { if (Style.isJson() && !Style.DisableFormat) { auto Err = Replaces.add( tooling::Replacement(tooling::Replacement("", 0, 0, "x = "))); - if (Err) { + if (Err) llvm::errs() << "Bad Json variable insertion\n"; - } } auto ChangedCode = applyAllReplacements(Code, Replaces); -if (!ChangedCode) { +if (!ChangedCode) llvm::errs() << "Bad Json varibale replacement\n"; -} StringRef NewCode = *ChangedCode; std::vector Ranges(1, tooling::Range(0, NewCode.size())); diff --git a/clang/unittests/Format/MacroExpanderTest.cpp b/clang/unittests/Format/MacroExpanderTest.cpp index 7ec98a5e82b7b..37fa8d1cfc179 100644 --- a/clang/unittests/Format/MacroExpanderTest.cpp +++ b/clang/unittests/Format/MacroExpanderTest.cpp @@ -28,9 +28,8 @@ class MacroExpanderTest : public ::testing::Test { llvm::SmallVector lexArgs(const std::vector ) { llvm::SmallVector Result; -for (const auto : Args) { +for (const auto : Args) Result.push_back(uneof(Lex.lex(Arg))); -} return Result; } @@ -78,9 +77,8 @@ class MacroExpanderTest : public ::testing::Test { TEST_F(MacroExpanderTest, SkipsDefinitionOnError) { auto Macros = create({"A(", "B(,", "C(a,", "D(a a", "E(a, a", "F(,)", "G(a;"}); - for (const auto *Name : {"A", "B", "C", "D", "E", "F", "G"}) { + for (const auto *Name : {"A", "B", "C", "D", "E", "F", "G"}) EXPECT_FALSE(Macros->defined(Name)) << "for Name " << Name; - } } TEST_F(MacroExpanderTest, ExpandsWithoutArguments) { diff --git a/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp b/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp index 50b861fea1daf..342fdd3418098 100644 --- a/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp +++ b/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp @@ -469,7 +469,8 @@ TEST_F(NamespaceEndCommentsFixerTest, WorksForObjCpp) { fixNamespaceEndComments("namespace {\n" "int i;\n" "int j;\n" -"}", ObjCppStyle)); +"}", +ObjCppStyle)); } TEST_F(NamespaceEndCommentsFixerTest, AddsMacroEndComment) { diff --git a/clang/unittests/Format/TestLexer.h b/clang/unittests/Format/TestLexer.h index ae9818d7561b8..a1585fc5cac6d 100644 --- a/clang/unittests/Format/TestLexer.h +++ b/clang/unittests/Format/TestLexer.h @@ -37,9 +37,8 @@
[clang] dbefb7e - [clang-format] Reformat. NFC.
Author: Marek Kurdej Date: 2022-03-16T21:54:11+01:00 New Revision: dbefb7e86f82dcb1302b3d5559f733427d464a87 URL: https://github.com/llvm/llvm-project/commit/dbefb7e86f82dcb1302b3d5559f733427d464a87 DIFF: https://github.com/llvm/llvm-project/commit/dbefb7e86f82dcb1302b3d5559f733427d464a87.diff LOG: [clang-format] Reformat. NFC. Added: Modified: clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 926bf8905c7a6..8ee6040cd0f69 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9919,10 +9919,13 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { AlignLeft); verifyFormat("template void operator=(T) &;", AlignLeft); verifyFormat("template void operator=(T) const&;", AlignLeft); - verifyFormat("template void operator=(T) & noexcept;", AlignLeft); - verifyFormat("template void operator=(T) & = default;", AlignLeft); + verifyFormat("template void operator=(T) & noexcept;", + AlignLeft); + verifyFormat("template void operator=(T) & = default;", + AlignLeft); verifyFormat("template void operator=(T) &&;", AlignLeft); - verifyFormat("template void operator=(T) && = delete;", AlignLeft); + verifyFormat("template void operator=(T) && = delete;", + AlignLeft); verifyFormat("template void operator=(T) & {}", AlignLeft); verifyFormat("template void operator=(T) && {}", AlignLeft); @@ -9948,10 +9951,13 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { AlignMiddle); verifyFormat("template void operator=(T) &;", AlignMiddle); verifyFormat("template void operator=(T) const &;", AlignMiddle); - verifyFormat("template void operator=(T) & noexcept;", AlignMiddle); - verifyFormat("template void operator=(T) & = default;", AlignMiddle); + verifyFormat("template void operator=(T) & noexcept;", + AlignMiddle); + verifyFormat("template void operator=(T) & = default;", + AlignMiddle); verifyFormat("template void operator=(T) &&;", AlignMiddle); - verifyFormat("template void operator=(T) && = delete;", AlignMiddle); + verifyFormat("template void operator=(T) && = delete;", + AlignMiddle); verifyFormat("template void operator=(T) & {}", AlignMiddle); verifyFormat("template void operator=(T) && {}", AlignMiddle); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3227aa3 - [clang-format] Correctly format variable templates.
Author: Marek Kurdej Date: 2022-03-15T13:16:56+01:00 New Revision: 3227aa3aa83440ff94a3b13a29623e03b05098f2 URL: https://github.com/llvm/llvm-project/commit/3227aa3aa83440ff94a3b13a29623e03b05098f2 DIFF: https://github.com/llvm/llvm-project/commit/3227aa3aa83440ff94a3b13a29623e03b05098f2.diff LOG: [clang-format] Correctly format variable templates. Fixes https://github.com/llvm/llvm-project/issues/54257. Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D121456 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 0c760b5b2811d..f0a17af677016 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1526,8 +1526,36 @@ class AnnotatingParser { if (Current.getPrecedence() != prec::Assignment) return false; - if (Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return)) + if (Line.First->isOneOf(tok::kw_using, tok::kw_return)) return false; + if (Line.First->is(tok::kw_template)) { +assert(Current.Previous); +if (Current.Previous->is(tok::kw_operator)) { + // `template ... operator=` cannot be an expression. + return false; +} + +// `template` keyword can start a variable template. +const FormatToken *Tok = Line.First->getNextNonComment(); +assert(Tok); // Current token is on the same line. +if (Tok->isNot(TT_TemplateOpener)) { + // Explicit template instantiations do not have `<>`. + return false; +} + +Tok = Tok->MatchingParen; +if (!Tok) + return false; +Tok = Tok->getNextNonComment(); +if (!Tok) + return false; + +if (Tok->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_concept, + tok::kw_struct, tok::kw_using)) + return false; + +return true; + } // Type aliases use `type X = ...;` in TypeScript and can be exported // using `export type ...`. diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 557438de70fe0..459cbf1c7681c 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -25657,6 +25657,12 @@ TEST_F(FormatTest, AlignArrayOfStructuresRightAlignmentNonSquare) { Style); } +TEST_F(FormatTest, FormatsVariableTemplates) { + verifyFormat("inline bool var = is_integral_v && is_signed_v;"); + verifyFormat("template " + "inline bool var = is_integral_v && is_signed_v;"); +} + } // namespace } // namespace format } // namespace clang diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 9240e812ba927..cc624d0760d12 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -131,6 +131,31 @@ TEST_F(TokenAnnotatorTest, UnderstandsEnums) { EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_EnumLBrace); } +TEST_F(TokenAnnotatorTest, UnderstandsDefaultedAndDeletedFunctions) { + auto Tokens = annotate("auto operator<=>(const T &) const & = default;"); + EXPECT_EQ(Tokens.size(), 14u) << Tokens; + EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference); + + Tokens = annotate("template void F(T) && = delete;"); + EXPECT_EQ(Tokens.size(), 15u) << Tokens; + EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_PointerOrReference); +} + +TEST_F(TokenAnnotatorTest, UnderstandsVariables) { + auto Tokens = + annotate("inline bool var = is_integral_v && is_signed_v;"); + EXPECT_EQ(Tokens.size(), 15u) << Tokens; + EXPECT_TOKEN(Tokens[8], tok::ampamp, TT_BinaryOperator); +} + +TEST_F(TokenAnnotatorTest, UnderstandsVariableTemplates) { + auto Tokens = + annotate("template " + "inline bool var = is_integral_v && is_signed_v;"); + EXPECT_EQ(Tokens.size(), 20u) << Tokens; + EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_BinaryOperator); +} + TEST_F(TokenAnnotatorTest, UnderstandsLBracesInMacroDefinition) { auto Tokens = annotate("#define BEGIN NS {"); EXPECT_EQ(Tokens.size(), 6u) << Tokens; @@ -164,17 +189,17 @@ TEST_F(TokenAnnotatorTest, UnderstandsFunctionRefQualifiers) { EXPECT_EQ(Tokens.size(), 7u) << Tokens; EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference); - Tokens = annotate("void operator=() &&;"); - EXPECT_EQ(Tokens.size(), 8u) << Tokens; - EXPECT_TOKEN(Tokens[5], tok::ampamp, TT_PointerOrReference); + Tokens = annotate("void operator=(T) &&;"); + EXPECT_EQ(Tokens.size(), 9u) << Tokens; + EXPECT_TOKEN(Tokens[6], tok::ampamp, TT_PointerOrReference); Tokens =
[clang] e60defb - [clang-format] Add regression tests for function ref qualifiers on operator definition. NFC.
Author: Marek Kurdej Date: 2022-03-15T12:58:08+01:00 New Revision: e60defb931cfc333d143f6000a6a65ae4dc106a2 URL: https://github.com/llvm/llvm-project/commit/e60defb931cfc333d143f6000a6a65ae4dc106a2 DIFF: https://github.com/llvm/llvm-project/commit/e60defb931cfc333d143f6000a6a65ae4dc106a2.diff LOG: [clang-format] Add regression tests for function ref qualifiers on operator definition. NFC. Fixes https://github.com/llvm/llvm-project/issues/54374. Added: Modified: clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 354b60e27a5c7..557438de70fe0 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9889,6 +9889,14 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { verifyFormat("template \n" "void F(T) && = delete;", getGoogleStyle()); + verifyFormat("template void operator=(T) &;"); + verifyFormat("template void operator=(T) const &;"); + verifyFormat("template void operator=(T) "); + verifyFormat("template void operator=(T) & = default;"); + verifyFormat("template void operator=(T) &&;"); + verifyFormat("template void operator=(T) && = delete;"); + verifyFormat("template void operator=(T) & {}"); + verifyFormat("template void operator=(T) && {}"); FormatStyle AlignLeft = getLLVMStyle(); AlignLeft.PointerAlignment = FormatStyle::PAS_Left; @@ -9909,6 +9917,14 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { verifyFormat("void Fn(T const volatile&&) const volatile&&;", AlignLeft); verifyFormat("void Fn(T const volatile&&) const volatile&& noexcept;", AlignLeft); + verifyFormat("template void operator=(T) &;", AlignLeft); + verifyFormat("template void operator=(T) const&;", AlignLeft); + verifyFormat("template void operator=(T) & noexcept;", AlignLeft); + verifyFormat("template void operator=(T) & = default;", AlignLeft); + verifyFormat("template void operator=(T) &&;", AlignLeft); + verifyFormat("template void operator=(T) && = delete;", AlignLeft); + verifyFormat("template void operator=(T) & {}", AlignLeft); + verifyFormat("template void operator=(T) && {}", AlignLeft); FormatStyle AlignMiddle = getLLVMStyle(); AlignMiddle.PointerAlignment = FormatStyle::PAS_Middle; @@ -9930,6 +9946,14 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { verifyFormat("void Fn(T const volatile &&) const volatile &&;", AlignMiddle); verifyFormat("void Fn(T const volatile &&) const volatile && noexcept;", AlignMiddle); + verifyFormat("template void operator=(T) &;", AlignMiddle); + verifyFormat("template void operator=(T) const &;", AlignMiddle); + verifyFormat("template void operator=(T) & noexcept;", AlignMiddle); + verifyFormat("template void operator=(T) & = default;", AlignMiddle); + verifyFormat("template void operator=(T) &&;", AlignMiddle); + verifyFormat("template void operator=(T) && = delete;", AlignMiddle); + verifyFormat("template void operator=(T) & {}", AlignMiddle); + verifyFormat("template void operator=(T) && {}", AlignMiddle); FormatStyle Spaces = getLLVMStyle(); Spaces.SpacesInCStyleCastParentheses = true; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 5f346fa5f8bfa..9240e812ba927 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -159,6 +159,24 @@ TEST_F(TokenAnnotatorTest, UnderstandsDelete) { EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen); } +TEST_F(TokenAnnotatorTest, UnderstandsFunctionRefQualifiers) { + auto Tokens = annotate("void f() &;"); + EXPECT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference); + + Tokens = annotate("void operator=() &&;"); + EXPECT_EQ(Tokens.size(), 8u) << Tokens; + EXPECT_TOKEN(Tokens[5], tok::ampamp, TT_PointerOrReference); + + Tokens = annotate("template void f() &;"); + EXPECT_EQ(Tokens.size(), 12u) << Tokens; + EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference); + + Tokens = annotate("template void operator=() &;"); + EXPECT_EQ(Tokens.size(), 13u) << Tokens; + EXPECT_TOKEN(Tokens[10], tok::amp, TT_PointerOrReference); +} + TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) { auto Tokens = annotate("template \n" "concept C = (Foo && Bar) && (Bar && Baz);"); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 126b37a - [clang-format] Correctly recognize arrays in template parameter list.
Author: Marek Kurdej Date: 2022-03-15T11:33:13+01:00 New Revision: 126b37a713dc1c67cbc7dc8b5288b2f907c906a9 URL: https://github.com/llvm/llvm-project/commit/126b37a713dc1c67cbc7dc8b5288b2f907c906a9 DIFF: https://github.com/llvm/llvm-project/commit/126b37a713dc1c67cbc7dc8b5288b2f907c906a9.diff LOG: [clang-format] Correctly recognize arrays in template parameter list. Fixes https://github.com/llvm/llvm-project/issues/54245. Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D121584 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index b03296c7e02d9..cadf1960dbf7a 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1935,6 +1935,11 @@ bool UnwrappedLineParser::tryToParseLambda() { if (!tryToParseLambdaIntroducer()) return false; + // `[something] >` is not a lambda, but an array type in a template parameter + // list. + if (FormatTok->is(tok::greater)) +return false; + bool SeenArrow = false; bool InTemplateParameterList = false; @@ -3524,7 +3529,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { // Don't try parsing a lambda if we had a closing parenthesis before, // it was probably a pointer to an array: int (*)[]. if (!tryToParseLambda()) -break; +continue; } else { parseSquare(); continue; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index dff8c04662601..5f346fa5f8bfa 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -98,6 +98,20 @@ TEST_F(TokenAnnotatorTest, UnderstandsStructs) { auto Tokens = annotate("struct S {};"); EXPECT_EQ(Tokens.size(), 6u) << Tokens; EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_StructLBrace); + + Tokens = annotate("template struct S {};"); + EXPECT_EQ(Tokens.size(), 18u) << Tokens; + EXPECT_TOKEN(Tokens[7], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[10], tok::l_square, TT_ArraySubscriptLSquare); + EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser); + EXPECT_TOKEN(Tokens[14], tok::l_brace, TT_StructLBrace); + + Tokens = annotate("template struct S {};"); + EXPECT_EQ(Tokens.size(), 18u) << Tokens; + EXPECT_TOKEN(Tokens[7], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[10], tok::l_square, TT_ArraySubscriptLSquare); + EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser); + EXPECT_TOKEN(Tokens[14], tok::l_brace, TT_StructLBrace); } TEST_F(TokenAnnotatorTest, UnderstandsUnions) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] a6b2f50 - Revert "[clang-format] Correctly format variable templates."
Author: Marek Kurdej Date: 2022-03-14T16:04:09+01:00 New Revision: a6b2f50fb47da3baeee10b1906da6e30ac5d26ec URL: https://github.com/llvm/llvm-project/commit/a6b2f50fb47da3baeee10b1906da6e30ac5d26ec DIFF: https://github.com/llvm/llvm-project/commit/a6b2f50fb47da3baeee10b1906da6e30ac5d26ec.diff LOG: Revert "[clang-format] Correctly format variable templates." This reverts commit a140b7104fdae0d9eff5b18efbc784754e0ca274. It provoked the bug https://github.com/llvm/llvm-project/issues/54374. Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 6cf3681cdd9d5..0c760b5b2811d 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1526,30 +1526,8 @@ class AnnotatingParser { if (Current.getPrecedence() != prec::Assignment) return false; - if (Line.First->isOneOf(tok::kw_using, tok::kw_return)) + if (Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return)) return false; - if (Line.First->is(tok::kw_template)) { -// `template` keyword can start a variable template. -const FormatToken *Tok = Line.First->getNextNonComment(); -assert(Tok); // Current token is on the same line. -if (Tok->isNot(TT_TemplateOpener)) { - // Explicit template instantiations do not have `<>`. - return false; -} - -Tok = Tok->MatchingParen; -if (!Tok) - return false; -Tok = Tok->getNextNonComment(); -if (!Tok) - return false; - -if (Tok->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_concept, - tok::kw_struct, tok::kw_using)) - return false; - -return true; - } // Type aliases use `type X = ...;` in TypeScript and can be exported // using `export type ...`. diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index aadd24a0d6ca6..05427c6249749 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -25625,12 +25625,6 @@ TEST_F(FormatTest, AlignArrayOfStructuresRightAlignmentNonSquare) { Style); } -TEST_F(FormatTest, FormatsVariableTemplates) { - verifyFormat("inline bool var = is_integral_v && is_signed_v;"); - verifyFormat("template " - "inline bool var = is_integral_v && is_signed_v;"); -} - } // namespace } // namespace format } // namespace clang diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index dd868be99f45e..dff8c04662601 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -117,31 +117,6 @@ TEST_F(TokenAnnotatorTest, UnderstandsEnums) { EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_EnumLBrace); } -TEST_F(TokenAnnotatorTest, UnderstandsDefaultedAndDeletedFunctions) { - auto Tokens = annotate("auto operator<=>(const T &) const & = default;"); - EXPECT_EQ(Tokens.size(), 14u) << Tokens; - EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference); - - Tokens = annotate("template void F(T) && = delete;"); - EXPECT_EQ(Tokens.size(), 15u) << Tokens; - EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_PointerOrReference); -} - -TEST_F(TokenAnnotatorTest, UnderstandsVariables) { - auto Tokens = - annotate("inline bool var = is_integral_v && is_signed_v;"); - EXPECT_EQ(Tokens.size(), 15u) << Tokens; - EXPECT_TOKEN(Tokens[8], tok::ampamp, TT_BinaryOperator); -} - -TEST_F(TokenAnnotatorTest, UnderstandsVariableTemplates) { - auto Tokens = - annotate("template " - "inline bool var = is_integral_v && is_signed_v;"); - EXPECT_EQ(Tokens.size(), 20u) << Tokens; - EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_BinaryOperator); -} - TEST_F(TokenAnnotatorTest, UnderstandsLBracesInMacroDefinition) { auto Tokens = annotate("#define BEGIN NS {"); EXPECT_EQ(Tokens.size(), 6u) << Tokens; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 2507e0a - [clang-format] Clean up UnwrappedLineParser::parseRecord. NFC.
Author: Marek Kurdej Date: 2022-03-14T11:59:52+01:00 New Revision: 2507e0a257991fd46bd847c8fa0964bc70891add URL: https://github.com/llvm/llvm-project/commit/2507e0a257991fd46bd847c8fa0964bc70891add DIFF: https://github.com/llvm/llvm-project/commit/2507e0a257991fd46bd847c8fa0964bc70891add.diff LOG: [clang-format] Clean up UnwrappedLineParser::parseRecord. NFC. Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 47e794c7b1ca6..b03296c7e02d9 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3511,7 +3511,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { // (this would still leave us with an ambiguity between template function // and class declarations). if (FormatTok->isOneOf(tok::colon, tok::less)) { -while (!eof()) { +do { if (FormatTok->is(tok::l_brace)) { calculateBraceTypes(/*ExpectClassBody=*/true); if (!tryToParseBracedList()) @@ -3525,6 +3525,9 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { // it was probably a pointer to an array: int (*)[]. if (!tryToParseLambda()) break; +} else { + parseSquare(); + continue; } } if (FormatTok->is(tok::semi)) @@ -3536,7 +3539,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { break; } nextToken(); -} +} while (!eof()); } auto GetBraceType = [](const FormatToken ) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 0570af1 - [clang-format] Fix incorrect assertion on macro definitions with keyword class.
Author: Marek Kurdej Date: 2022-03-13T22:17:48+01:00 New Revision: 0570af17585d98be0c12f6760118eb94071d9c26 URL: https://github.com/llvm/llvm-project/commit/0570af17585d98be0c12f6760118eb94071d9c26 DIFF: https://github.com/llvm/llvm-project/commit/0570af17585d98be0c12f6760118eb94071d9c26.diff LOG: [clang-format] Fix incorrect assertion on macro definitions with keyword class. Fixes https://github.com/llvm/llvm-project/issues/54348. Added: Modified: clang/lib/Format/UnwrappedLineFormatter.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 5b5439901b2f7..1393a2a321183 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -484,7 +484,8 @@ class LineJoiner { } else { // Try to merge a block with left brace unwrapped that wasn't yet // covered. -assert(!TheLine->First->isOneOf(tok::kw_class, tok::kw_enum, +assert(TheLine->InPPDirective || + !TheLine->First->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_struct)); ShouldMerge = !Style.BraceWrapping.AfterFunction || (NextLine.First->is(tok::r_brace) && diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 45e8c0b79cfb2..baa3993805bcb 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -1877,6 +1877,13 @@ TEST_F(FormatTest, UnderstandsMacros) { verifyFormat("#define __except(x)"); verifyFormat("#define __try(x)"); + // https://llvm.org/PR54348. + verifyFormat( + "#define A" + " " + "\\\n" + " class & {}"); + FormatStyle Style = getLLVMStyle(); Style.BreakBeforeBraces = FormatStyle::BS_Custom; Style.BraceWrapping.AfterFunction = true; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] a140b71 - [clang-format] Correctly format variable templates.
Author: Marek Kurdej Date: 2022-03-13T22:00:17+01:00 New Revision: a140b7104fdae0d9eff5b18efbc784754e0ca274 URL: https://github.com/llvm/llvm-project/commit/a140b7104fdae0d9eff5b18efbc784754e0ca274 DIFF: https://github.com/llvm/llvm-project/commit/a140b7104fdae0d9eff5b18efbc784754e0ca274.diff LOG: [clang-format] Correctly format variable templates. Fixes https://github.com/llvm/llvm-project/issues/54257. Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D121456 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 1c662c9a909c9..77ef54e0e2d59 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1510,8 +1510,30 @@ class AnnotatingParser { if (Current.getPrecedence() != prec::Assignment) return false; - if (Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return)) + if (Line.First->isOneOf(tok::kw_using, tok::kw_return)) return false; + if (Line.First->is(tok::kw_template)) { +// `template` keyword can start a variable template. +const FormatToken *Tok = Line.First->getNextNonComment(); +assert(Tok); // Current token is on the same line. +if (Tok->isNot(TT_TemplateOpener)) { + // Explicit template instantiations do not have `<>`. + return false; +} + +Tok = Tok->MatchingParen; +if (!Tok) + return false; +Tok = Tok->getNextNonComment(); +if (!Tok) + return false; + +if (Tok->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_concept, + tok::kw_struct, tok::kw_using)) + return false; + +return true; + } // Type aliases use `type X = ...;` in TypeScript and can be exported // using `export type ...`. diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 430a195f60255..45e8c0b79cfb2 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -25525,6 +25525,12 @@ TEST_F(FormatTest, AlignArrayOfStructuresRightAlignmentNonSquare) { Style); } +TEST_F(FormatTest, FormatsVariableTemplates) { + verifyFormat("inline bool var = is_integral_v && is_signed_v;"); + verifyFormat("template " + "inline bool var = is_integral_v && is_signed_v;"); +} + } // namespace } // namespace format } // namespace clang diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 17801e4bb9839..7e753bc5a34d5 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -117,6 +117,31 @@ TEST_F(TokenAnnotatorTest, UnderstandsEnums) { EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_EnumLBrace); } +TEST_F(TokenAnnotatorTest, UnderstandsDefaultedAndDeletedFunctions) { + auto Tokens = annotate("auto operator<=>(const T &) const & = default;"); + EXPECT_EQ(Tokens.size(), 14u) << Tokens; + EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference); + + Tokens = annotate("template void F(T) && = delete;"); + EXPECT_EQ(Tokens.size(), 15u) << Tokens; + EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_PointerOrReference); +} + +TEST_F(TokenAnnotatorTest, UnderstandsVariables) { + auto Tokens = + annotate("inline bool var = is_integral_v && is_signed_v;"); + EXPECT_EQ(Tokens.size(), 15u) << Tokens; + EXPECT_TOKEN(Tokens[8], tok::ampamp, TT_BinaryOperator); +} + +TEST_F(TokenAnnotatorTest, UnderstandsVariableTemplates) { + auto Tokens = + annotate("template " + "inline bool var = is_integral_v && is_signed_v;"); + EXPECT_EQ(Tokens.size(), 20u) << Tokens; + EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_BinaryOperator); +} + TEST_F(TokenAnnotatorTest, UnderstandsLBracesInMacroDefinition) { auto Tokens = annotate("#define BEGIN NS {"); EXPECT_EQ(Tokens.size(), 6u) << Tokens; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 36d13d3 - [clang-format] Add space to comments starting with '#'.
Author: Marek Kurdej Date: 2022-03-13T21:56:22+01:00 New Revision: 36d13d3f8adb3d1a6bae71370afa23d11a94dc78 URL: https://github.com/llvm/llvm-project/commit/36d13d3f8adb3d1a6bae71370afa23d11a94dc78 DIFF: https://github.com/llvm/llvm-project/commit/36d13d3f8adb3d1a6bae71370afa23d11a94dc78.diff LOG: [clang-format] Add space to comments starting with '#'. Fixes https://github.com/llvm/llvm-project/issues/35116. Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D121451 Added: Modified: clang/lib/Format/BreakableToken.cpp clang/unittests/Format/FormatTestComments.cpp Removed: diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 967ddeb82383a..ae084e9e14544 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -779,11 +779,14 @@ BreakableLineCommentSection::BreakableLineCommentSection( const char FirstCommentChar = Lines[i][IndentPrefix.size()]; const unsigned FirstCharByteSize = encoding::getCodePointNumBytes(FirstCommentChar, Encoding); -return encoding::columnWidth( - Lines[i].substr(IndentPrefix.size(), FirstCharByteSize), - Encoding) == 1 && - (FirstCommentChar == '\\' || isPunctuation(FirstCommentChar) || -isHorizontalWhitespace(FirstCommentChar)); +if (encoding::columnWidth( +Lines[i].substr(IndentPrefix.size(), FirstCharByteSize), +Encoding) != 1) + return false; +if (FirstCommentChar == '#') + return false; +return FirstCommentChar == '\\' || isPunctuation(FirstCommentChar) || + isHorizontalWhitespace(FirstCommentChar); }; // On the first line of the comment section we calculate how many spaces diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index f83ffb393ac2f..27cc6013611c2 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -91,6 +91,9 @@ TEST_F(FormatTestComments, UnderstandsSingleLineComments) { "// line 2\n" "void f() {}\n"); + EXPECT_EQ("// comment\n", format("//comment\n")); + EXPECT_EQ("// #comment\n", format("//#comment\n")); + EXPECT_EQ("// comment\n" "// clang-format on\n", format("//comment\n" @@ -3302,6 +3305,7 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { format(NoTextInComment, Style)); Style.SpacesInLineCommentPrefix.Minimum = 0; + EXPECT_EQ("//#comment", format("//#comment", Style)); EXPECT_EQ("//\n" "\n" "void foo() { //\n" @@ -3310,6 +3314,7 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { format(NoTextInComment, Style)); Style.SpacesInLineCommentPrefix.Minimum = 5; + EXPECT_EQ("// #comment", format("//#comment", Style)); EXPECT_EQ("//\n" "\n" "void foo() { //\n" @@ -3463,6 +3468,7 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { format(Code, Style)); Style.SpacesInLineCommentPrefix = {0, 0}; + EXPECT_EQ("//#comment", format("// #comment", Style)); EXPECT_EQ("//Free comment without space\n" "\n" "//Free comment with 3 spaces\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 596fa2d - [clang-format] Handle attributes before case label.
Author: Marek Kurdej Date: 2022-03-13T21:53:40+01:00 New Revision: 596fa2d90044841c33b9a0e6b17406c2a45077a2 URL: https://github.com/llvm/llvm-project/commit/596fa2d90044841c33b9a0e6b17406c2a45077a2 DIFF: https://github.com/llvm/llvm-project/commit/596fa2d90044841c33b9a0e6b17406c2a45077a2.diff LOG: [clang-format] Handle attributes before case label. Fixes https://github.com/llvm/llvm-project/issues/53110. Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D121450 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/lib/Format/UnwrappedLineParser.h clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 3a245b8b5fa0d..47e794c7b1ca6 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -480,6 +480,10 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace, unsigned StatementCount = 0; bool SwitchLabelEncountered = false; do { +if (FormatTok->getType() == TT_AttributeMacro) { + nextToken(); + continue; +} tok::TokenKind kind = FormatTok->Tok.getKind(); if (FormatTok->getType() == TT_MacroBlockBegin) kind = tok::l_brace; @@ -569,6 +573,8 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace, parseCSharpAttribute(); break; } + if (handleCppAttributes()) +break; LLVM_FALLTHROUGH; default: ParseDefault(); @@ -1390,9 +1396,11 @@ void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind, // e.g. "default void f() {}" in a Java interface. break; case tok::kw_case: -if (Style.isJavaScript() && Line->MustBeDeclaration) +if (Style.isJavaScript() && Line->MustBeDeclaration) { // 'case: string' field declaration. + nextToken(); break; +} parseCaseLabel(); return; case tok::kw_try: @@ -1813,6 +1821,12 @@ void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind, case tok::kw_new: parseNew(); break; +case tok::kw_case: + if (Style.isJavaScript() && Line->MustBeDeclaration) +// 'case: string' field declaration. +break; + parseCaseLabel(); + break; default: nextToken(); break; @@ -2376,17 +2390,24 @@ static void markOptionalBraces(FormatToken *LeftBrace) { RightBrace->Optional = true; } +void UnwrappedLineParser::handleAttributes() { + // Handle AttributeMacro, e.g. `if (x) UNLIKELY`. + if (FormatTok->is(TT_AttributeMacro)) +nextToken(); + handleCppAttributes(); +} + +bool UnwrappedLineParser::handleCppAttributes() { + // Handle [[likely]] / [[unlikely]] attributes. + if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute()) { +parseSquare(); +return true; + } + return false; +} + FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces) { - auto HandleAttributes = [this]() { -// Handle AttributeMacro, e.g. `if (x) UNLIKELY`. -if (FormatTok->is(TT_AttributeMacro)) - nextToken(); -// Handle [[likely]] / [[unlikely]] attributes. -if (FormatTok->is(tok::l_square) && tryToParseSimpleAttribute()) - parseSquare(); - }; - assert(FormatTok->is(tok::kw_if) && "'if' expected"); nextToken(); if (FormatTok->is(tok::exclaim)) @@ -2399,7 +2420,7 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind, if (FormatTok->is(tok::l_paren)) parseParens(); } - HandleAttributes(); + handleAttributes(); bool NeedsUnwrappedLine = false; keepAncestorBraces(); @@ -2436,7 +2457,7 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind, Kind = IfStmtKind::IfElse; } nextToken(); -HandleAttributes(); +handleAttributes(); if (FormatTok->is(tok::l_brace)) { ElseLeftBrace = FormatTok; CompoundStatementIndenter Indenter(this, Style, Line->Level); diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index 5cc01398a5457..798bae24ad075 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -121,6 +121,8 @@ class UnwrappedLineParser { void parseSquare(bool LambdaIntroducer = false); void keepAncestorBraces(); void parseUnbracedBody(bool CheckEOF = false); + void handleAttributes(); + bool handleCppAttributes(); FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false); void parseTryCatch(); void parseForOrWhileLoop(); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 37a42382e8f85..430a195f60255 100644 --- a/clang/unittests/Format/FormatTest.cpp +++
[clang] b44eb20 - [clang-format] Refactor condition in AnnotatingParser::modifyContext(). NFC.
Author: Marek Kurdej Date: 2022-03-11T13:12:43+01:00 New Revision: b44eb207e96a5e20aecbb6084147ae97e3eabd22 URL: https://github.com/llvm/llvm-project/commit/b44eb207e96a5e20aecbb6084147ae97e3eabd22 DIFF: https://github.com/llvm/llvm-project/commit/b44eb207e96a5e20aecbb6084147ae97e3eabd22.diff LOG: [clang-format] Refactor condition in AnnotatingParser::modifyContext(). NFC. Added: Modified: clang/lib/Format/TokenAnnotator.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 8f5f4e0f43362..1c662c9a909c9 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1506,15 +1506,24 @@ class AnnotatingParser { }; void modifyContext(const FormatToken ) { -if (Current.getPrecedence() == prec::Assignment && -!Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return) && -// Type aliases use `type X = ...;` in TypeScript and can be exported -// using `export type ...`. -!(Style.isJavaScript() && +auto AssignmentStartsExpression = [&]() { + if (Current.getPrecedence() != prec::Assignment) +return false; + + if (Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return)) +return false; + + // Type aliases use `type X = ...;` in TypeScript and can be exported + // using `export type ...`. + if (Style.isJavaScript() && (Line.startsWith(Keywords.kw_type, tok::identifier) || - Line.startsWith(tok::kw_export, Keywords.kw_type, - tok::identifier))) && -(!Current.Previous || Current.Previous->isNot(tok::kw_operator))) { + Line.startsWith(tok::kw_export, Keywords.kw_type, tok::identifier))) +return false; + + return !Current.Previous || Current.Previous->isNot(tok::kw_operator); +}; + +if (AssignmentStartsExpression()) { Contexts.back().IsExpression = true; if (!Line.startsWith(TT_UnaryOperator)) { for (FormatToken *Previous = Current.Previous; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f537a40 - [clang-format] Correctly detect `!` as TT_NonNullAssertion after `default`.
Author: Marek Kurdej Date: 2022-03-08T13:35:26+01:00 New Revision: f537a409160dc1e506445724c5256bb116c0d71a URL: https://github.com/llvm/llvm-project/commit/f537a409160dc1e506445724c5256bb116c0d71a DIFF: https://github.com/llvm/llvm-project/commit/f537a409160dc1e506445724c5256bb116c0d71a.diff LOG: [clang-format] Correctly detect `!` as TT_NonNullAssertion after `default`. Fixes https://github.com/llvm/llvm-project/issues/53153. Depends on D121132. Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D121136 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTestCSharp.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 236e9a73b33a8..8f5f4e0f43362 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1650,9 +1650,9 @@ class AnnotatingParser { : Current.Previous->is(tok::identifier); if (IsIdentifier || Current.Previous->isOneOf( -tok::kw_namespace, tok::r_paren, tok::r_square, tok::r_brace, -tok::kw_false, tok::kw_true, Keywords.kw_type, Keywords.kw_get, -Keywords.kw_init, Keywords.kw_set) || +tok::kw_default, tok::kw_namespace, tok::r_paren, tok::r_square, +tok::r_brace, tok::kw_false, tok::kw_true, Keywords.kw_type, +Keywords.kw_get, Keywords.kw_init, Keywords.kw_set) || Current.Previous->Tok.isLiteral()) { Current.setType(TT_NonNullAssertion); return; diff --git a/clang/unittests/Format/FormatTestCSharp.cpp b/clang/unittests/Format/FormatTestCSharp.cpp index 2a7642012a5f9..aa0304f73fed4 100644 --- a/clang/unittests/Format/FormatTestCSharp.cpp +++ b/clang/unittests/Format/FormatTestCSharp.cpp @@ -1078,6 +1078,26 @@ public class SaleItem MicrosoftStyle); } +TEST_F(FormatTestCSharp, DefaultLiteral) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); + + verifyFormat( + "T[] InitializeArray(int length, T initialValue = default) {}", Style); + verifyFormat("System.Numerics.Complex fillValue = default;", Style); + verifyFormat("int Value { get } = default;", Style); + verifyFormat("int Value { get } = default!;", Style); + verifyFormat(R"(// +public record Person { + public string GetInit { get; init; } = default!; +};)", + Style); + verifyFormat(R"(// +public record Person { + public string GetSet { get; set; } = default!; +};)", + Style); +} + TEST_F(FormatTestCSharp, CSharpSpaces) { FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); Style.SpaceBeforeSquareBrackets = false; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7a54fce - [clang-format] Handle C# 9 `init` accessor specifier.
Author: Marek Kurdej Date: 2022-03-08T13:33:36+01:00 New Revision: 7a54fceb256257e3f8c8bd16ffd55531d806c96e URL: https://github.com/llvm/llvm-project/commit/7a54fceb256257e3f8c8bd16ffd55531d806c96e DIFF: https://github.com/llvm/llvm-project/commit/7a54fceb256257e3f8c8bd16ffd55531d806c96e.diff LOG: [clang-format] Handle C# 9 `init` accessor specifier. Before, the code: ``` int Value { get; } = 0; int Value { init; } = 0; ``` was formatted incoherently: ``` int Value { get; } = 0; int Value { init; } = 0; ``` because `init` was not recognised as an accessor specifier. Reviewed By: MyDeveloperDay, HazardyKnusperkeks Differential Revision: https://reviews.llvm.org/D121132 Added: Modified: clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTestCSharp.cpp Removed: diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index b00b8ab7b927c..fa76da15a53d3 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -954,6 +954,7 @@ struct AdditionalKeywords { kw_event = ("event"); kw_fixed = ("fixed"); kw_foreach = ("foreach"); +kw_init = ("init"); kw_implicit = ("implicit"); kw_internal = ("internal"); kw_lock = ("lock"); @@ -986,11 +987,11 @@ struct AdditionalKeywords { CSharpExtraKeywords = std::unordered_set( {kw_base, kw_byte, kw_checked, kw_decimal, kw_delegate, kw_event, - kw_fixed, kw_foreach, kw_implicit, kw_in, kw_interface, kw_internal, - kw_is, kw_lock, kw_null, kw_object, kw_out, kw_override, kw_params, - kw_readonly, kw_ref, kw_string, kw_stackalloc, kw_sbyte, kw_sealed, - kw_uint, kw_ulong, kw_unchecked, kw_unsafe, kw_ushort, kw_when, - kw_where, + kw_fixed, kw_foreach, kw_implicit, kw_in, kw_init, kw_interface, + kw_internal, kw_is, kw_lock, kw_null, kw_object, kw_out, kw_override, + kw_params, kw_readonly, kw_ref, kw_string, kw_stackalloc, kw_sbyte, + kw_sealed, kw_uint, kw_ulong, kw_unchecked, kw_unsafe, kw_ushort, + kw_when, kw_where, // Keywords from the JavaScript section. kw_as, kw_async, kw_await, kw_declare, kw_finally, kw_from, kw_function, kw_get, kw_import, kw_is, kw_let, kw_module, kw_readonly, @@ -1078,6 +1079,7 @@ struct AdditionalKeywords { IdentifierInfo *kw_fixed; IdentifierInfo *kw_foreach; IdentifierInfo *kw_implicit; + IdentifierInfo *kw_init; IdentifierInfo *kw_internal; IdentifierInfo *kw_lock; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 3015cd2be8879..236e9a73b33a8 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1652,7 +1652,7 @@ class AnnotatingParser { Current.Previous->isOneOf( tok::kw_namespace, tok::r_paren, tok::r_square, tok::r_brace, tok::kw_false, tok::kw_true, Keywords.kw_type, Keywords.kw_get, -Keywords.kw_set) || +Keywords.kw_init, Keywords.kw_set) || Current.Previous->Tok.isLiteral()) { Current.setType(TT_NonNullAssertion); return; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index a62aa5e649839..994b197347bc1 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1837,16 +1837,16 @@ bool UnwrappedLineParser::tryToParsePropertyAccessor() { FormatToken *Tok = Tokens->getNextToken(); // A trivial property accessor is of the form: - // { [ACCESS_SPECIFIER] [get]; [ACCESS_SPECIFIER] [set] } + // { [ACCESS_SPECIFIER] [get]; [ACCESS_SPECIFIER] [set|init] } // Track these as they do not require line breaks to be introduced. - bool HasGetOrSet = false; + bool HasSpecialAccessor = false; bool IsTrivialPropertyAccessor = true; while (!eof()) { if (Tok->isOneOf(tok::semi, tok::kw_public, tok::kw_private, tok::kw_protected, Keywords.kw_internal, Keywords.kw_get, - Keywords.kw_set)) { - if (Tok->isOneOf(Keywords.kw_get, Keywords.kw_set)) -HasGetOrSet = true; + Keywords.kw_init, Keywords.kw_set)) { + if (Tok->isOneOf(Keywords.kw_get, Keywords.kw_init, Keywords.kw_set)) +HasSpecialAccessor = true; Tok = Tokens->getNextToken(); continue; } @@ -1855,7 +1855,7 @@ bool UnwrappedLineParser::tryToParsePropertyAccessor() { break; } - if (!HasGetOrSet) { + if (!HasSpecialAccessor) { Tokens->setPosition(StoredPosition); return false; } @@ -1897,7 +1897,8 @@ bool UnwrappedLineParser::tryToParsePropertyAccessor() { nextToken(); break; default: - if
[clang] d03e342 - [clang-format] Fix assertion failure/crash with `AllowShortFunctionsOnASingleLine: Inline/InlineOnly`.
Author: Marek Kurdej Date: 2022-03-07T16:54:08+01:00 New Revision: d03e342803df7a75fb86c5a5c07cd84f3683bef9 URL: https://github.com/llvm/llvm-project/commit/d03e342803df7a75fb86c5a5c07cd84f3683bef9 DIFF: https://github.com/llvm/llvm-project/commit/d03e342803df7a75fb86c5a5c07cd84f3683bef9.diff LOG: [clang-format] Fix assertion failure/crash with `AllowShortFunctionsOnASingleLine: Inline/InlineOnly`. Fixes https://github.com/llvm/llvm-project/issues/54147. When handling `AllowShortFunctionsOnASingleLine`, we were searching for the last line with a smaller level than the current line. The search was incorrect when the first line had the same level as the current one. This led to an unsatisfied assumption about the existence of a brace (non-comment token). Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D120902 Added: Modified: clang/lib/Format/UnwrappedLineFormatter.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index dbf1e4cbbf6a3..5b5439901b2f7 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -310,6 +310,8 @@ class LineJoiner { for (; J != AnnotatedLines.begin(); --J) if ((*J)->Level < TheLine->Level) break; + if ((*J)->Level >= TheLine->Level) +return false; // Check if the found line starts a record. const FormatToken *LastNonComment = (*J)->Last; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 8909acdae5dc3..1f8601d30857c 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -12669,6 +12669,13 @@ TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) { "};", MergeInlineOnly); verifyFormat("int f() {}", MergeInlineOnly); + // https://llvm.org/PR54147 + verifyFormat("auto lambda = []() {\n" + " // comment\n" + " f();\n" + " g();\n" + "};", + MergeInlineOnly); // Also verify behavior when BraceWrapping.AfterFunction = true MergeInlineOnly.BreakBeforeBraces = FormatStyle::BS_Custom; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 13351fd - [clang-format] Recognize "if consteval".
Author: Marek Kurdej Date: 2022-03-02T17:46:45+01:00 New Revision: 13351fdf8cb448ffd60727f031df0d7cb348e48a URL: https://github.com/llvm/llvm-project/commit/13351fdf8cb448ffd60727f031df0d7cb348e48a DIFF: https://github.com/llvm/llvm-project/commit/13351fdf8cb448ffd60727f031df0d7cb348e48a.diff LOG: [clang-format] Recognize "if consteval". Fixes https://github.com/llvm/llvm-project/issues/54140. Reviewed By: MyDeveloperDay, JohelEGP Differential Revision: https://reviews.llvm.org/D120806 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 8f034a8ce1599..46562f7ae8b84 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2384,10 +2384,16 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind, assert(FormatTok->is(tok::kw_if) && "'if' expected"); nextToken(); - if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier)) + if (FormatTok->is(tok::exclaim)) nextToken(); - if (FormatTok->is(tok::l_paren)) -parseParens(); + if (FormatTok->is(tok::kw_consteval)) { +nextToken(); + } else { +if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier)) + nextToken(); +if (FormatTok->is(tok::l_paren)) + parseParens(); + } HandleAttributes(); bool NeedsUnwrappedLine = false; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 5fa56a9048b03..94f6dea1a2ed4 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -583,6 +583,29 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) { " }\n" "g();"); + verifyFormat("if consteval {\n}"); + verifyFormat("if !consteval {\n}"); + verifyFormat("if not consteval {\n}"); + verifyFormat("if consteval {\n} else {\n}"); + verifyFormat("if !consteval {\n} else {\n}"); + verifyFormat("if consteval {\n" + " f();\n" + "}"); + verifyFormat("if !consteval {\n" + " f();\n" + "}"); + verifyFormat("if consteval {\n" + " f();\n" + "} else {\n" + " g();\n" + "}"); + verifyFormat("if CONSTEVAL {\n" + " f();\n" + "}"); + verifyFormat("if !CONSTEVAL {\n" + " f();\n" + "}"); + verifyFormat("if (a)\n" " g();"); verifyFormat("if (a) {\n" @@ -1569,6 +1592,9 @@ TEST_F(FormatTest, FormatShortBracedStatements) { verifyFormat("if (true) {}", AllowSimpleBracedStatements); verifyFormat("if constexpr (true) {}", AllowSimpleBracedStatements); verifyFormat("if CONSTEXPR (true) {}", AllowSimpleBracedStatements); + verifyFormat("if consteval {}", AllowSimpleBracedStatements); + verifyFormat("if !consteval {}", AllowSimpleBracedStatements); + verifyFormat("if CONSTEVAL {}", AllowSimpleBracedStatements); verifyFormat("MYIF (true) {}", AllowSimpleBracedStatements); verifyFormat("MYIF constexpr (true) {}", AllowSimpleBracedStatements); verifyFormat("MYIF CONSTEXPR (true) {}", AllowSimpleBracedStatements); @@ -1577,9 +1603,13 @@ TEST_F(FormatTest, FormatShortBracedStatements) { verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements); verifyFormat("if constexpr (true) { f(); }", AllowSimpleBracedStatements); verifyFormat("if CONSTEXPR (true) { f(); }", AllowSimpleBracedStatements); + verifyFormat("if consteval { f(); }", AllowSimpleBracedStatements); + verifyFormat("if CONSTEVAL { f(); }", AllowSimpleBracedStatements); verifyFormat("MYIF (true) { f(); }", AllowSimpleBracedStatements); verifyFormat("MYIF constexpr (true) { f(); }", AllowSimpleBracedStatements); verifyFormat("MYIF CONSTEXPR (true) { f(); }", AllowSimpleBracedStatements); + verifyFormat("MYIF consteval { f(); }", AllowSimpleBracedStatements); + verifyFormat("MYIF CONSTEVAL { f(); }", AllowSimpleBracedStatements); verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements); verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements); verifyFormat("if (true) { fff(); }", ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 24d4f60 - [clang-format] Treat && followed by noexcept operator as a binary operator inside template arguments
Author: Luis Penagos Date: 2022-02-28T11:55:04+01:00 New Revision: 24d4f601aa6dd83b46ca41913452d0771a97d603 URL: https://github.com/llvm/llvm-project/commit/24d4f601aa6dd83b46ca41913452d0771a97d603 DIFF: https://github.com/llvm/llvm-project/commit/24d4f601aa6dd83b46ca41913452d0771a97d603.diff LOG: [clang-format] Treat && followed by noexcept operator as a binary operator inside template arguments Fixes https://github.com/llvm/llvm-project/issues/44544. Reviewed By: curdeius, MyDeveloperDay Differential Revision: https://reviews.llvm.org/D120445 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 36ff757922a9..e3d79aaf9184 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2089,6 +2089,10 @@ class AnnotatingParser { return TT_UnaryOperator; const FormatToken *NextToken = Tok.getNextNonComment(); + +if (InTemplateArgument && NextToken && NextToken->is(tok::kw_noexcept)) + return TT_BinaryOperator; + if (!NextToken || NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_noexcept) || NextToken->canBePointerOrReferenceQualifier() || diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 8008cce232d3..9a0890f874dd 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9512,6 +9512,8 @@ TEST_F(FormatTest, UnderstandsTemplateParameters) { verifyFormat("f(aa\n" " .template operator()());", getLLVMStyleWithColumns(35)); + verifyFormat("bool_constant"); + verifyFormat("bool_constant"); // Not template parameters. verifyFormat("return a < b && c > d;"); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] bfb4afe - [clang-format] Avoid inserting space after C++ casts.
Author: Marek Kurdej Date: 2022-02-24T10:21:02+01:00 New Revision: bfb4afee74c8d6e3b1d020564bfe163073f07a04 URL: https://github.com/llvm/llvm-project/commit/bfb4afee74c8d6e3b1d020564bfe163073f07a04 DIFF: https://github.com/llvm/llvm-project/commit/bfb4afee74c8d6e3b1d020564bfe163073f07a04.diff LOG: [clang-format] Avoid inserting space after C++ casts. Fixes https://github.com/llvm/llvm-project/issues/53876. This is a solution for standard C++ casts: const_cast, dynamic_cast, reinterpret_cast, static_cast. A general approach handling all possible casts is not possible without semantic information. Consider the code: ``` static_cast(*function_pointer_variable)(arguments); ``` vs. ``` some_return_type (*function_pointer_variable)(parameters); // Later used as: function_pointer_variable = _function; return function_pointer_variable(args); ``` In the latter case, it's not a cast but a variable declaration of a pointer to function. Without knowing what `some_return_type` is (and clang-format does not know it), it's hard to distinguish between the two cases. Theoretically, one could check whether "parameters" are types (not a cast) and "arguments" are value/expressions (a cast), but that might be inefficient (needs lots of lookahead). Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D120140 Added: Modified: clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index bd1d447328a0..d1dc3ffb129d 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -43,6 +43,7 @@ namespace format { TYPE(ConflictAlternative) \ TYPE(ConflictEnd) \ TYPE(ConflictStart) \ + TYPE(CppCastLParen) \ TYPE(CtorInitializerColon) \ TYPE(CtorInitializerComma) \ TYPE(DesignatedInitializerLSquare) \ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 01c215f6ad9d..36ff757922a9 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -358,7 +358,8 @@ class AnnotatingParser { if (CurrentToken->Previous->is(TT_BinaryOperator)) Contexts.back().IsExpression = true; if (CurrentToken->is(tok::r_paren)) { -if (MightBeFunctionType && ProbablyFunctionType && CurrentToken->Next && +if (Left->isNot(TT_CppCastLParen) && MightBeFunctionType && +ProbablyFunctionType && CurrentToken->Next && (CurrentToken->Next->is(tok::l_paren) || (CurrentToken->Next->is(tok::l_square) && Line.MustBeDeclaration))) Left->setType(Left->Next->is(tok::caret) ? TT_ObjCBlockLParen @@ -1733,6 +1734,9 @@ class AnnotatingParser { Current.Tok.setKind(tok::unknown); else Current.setType(TT_LineComment); +} else if (Current.is(tok::l_paren)) { + if (lParenStartsCppCast(Current)) +Current.setType(TT_CppCastLParen); } else if (Current.is(tok::r_paren)) { if (rParenEndsCast(Current)) Current.setType(TT_CastRParen); @@ -1880,6 +1884,25 @@ class AnnotatingParser { return Style.isJavaScript() && PreviousNotConst->is(tok::kw_const); } + /// Determine whether '(' is starting a C++ cast. + bool lParenStartsCppCast(const FormatToken ) { +// C-style casts are only used in C++. +if (!Style.isCpp()) + return false; + +FormatToken *LeftOfParens = Tok.getPreviousNonComment(); +if (LeftOfParens && LeftOfParens->is(TT_TemplateCloser) && +LeftOfParens->MatchingParen) { + auto *Prev = LeftOfParens->MatchingParen->getPreviousNonComment(); + if (Prev && Prev->isOneOf(tok::kw_const_cast, tok::kw_dynamic_cast, +tok::kw_reinterpret_cast, tok::kw_static_cast)) +// FIXME: Maybe we should handle identifiers ending with "_cast", +// e.g. any_cast? +return true; +} +return false; + } + /// Determine whether ')' is ending a cast. bool rParenEndsCast(const FormatToken ) { // C-style casts are only used in C++, C# and Java. diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 6cd6c4ab9a60..624f3a78755f 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -10570,6 +10570,19 @@ TEST_F(FormatTest, FormatsBinaryOperatorsPrecedingEquals) {
[clang] 46f6c83 - [clang-format] Fix QualifierOrder breaking the code with requires clause.
Author: Marek Kurdej Date: 2022-02-24T10:16:10+01:00 New Revision: 46f6c834d9f95d99e0a85aa0c6dc07419aa6dee2 URL: https://github.com/llvm/llvm-project/commit/46f6c834d9f95d99e0a85aa0c6dc07419aa6dee2 DIFF: https://github.com/llvm/llvm-project/commit/46f6c834d9f95d99e0a85aa0c6dc07419aa6dee2.diff LOG: [clang-format] Fix QualifierOrder breaking the code with requires clause. Fixes https://github.com/llvm/llvm-project/issues/53962. Given the config: ``` BasedOnStyle: LLVM QualifierAlignment: Custom QualifierOrder: ['constexpr', 'type'] ``` The code: ``` template requires std::invocable constexpr constructor(); ``` was incorrectly formatted to: ``` template requires constexpr std::invocable constructor(); ``` because we considered `std::invocable constexpr` as a type, not recognising the requires clause. This patch avoids moving the qualifier across the boundary of the requires clause (checking `ClosesRequiresClause`). Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D120309 Added: Modified: clang/lib/Format/QualifierAlignmentFixer.cpp clang/unittests/Format/QualifierFixerTest.cpp Removed: diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp index 233b081a95f6d..aff5562dd9721 100644 --- a/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -328,14 +328,17 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft( if (Next->is(tok::comment) && Next->getNextNonComment()) Next = Next->getNextNonComment(); assert(Next->MatchingParen && "Missing template closer"); - Next = Next->MatchingParen->Next; + Next = Next->MatchingParen; + if (Next->ClosesRequiresClause) +return Next; + Next = Next->Next; // Move to the end of any template class members e.g. // `Foo::iterator`. if (Next && Next->startsSequence(tok::coloncolon, tok::identifier)) Next = Next->Next->Next; if (Next && Next->is(QualifierType)) { -// Remove the const. +// Move the qualifier. insertQualifierBefore(SourceMgr, Fixes, Tok, Qualifier); removeToken(SourceMgr, Fixes, Next); return Next; @@ -344,7 +347,7 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft( if (Next && Next->Next && Next->Next->isOneOf(tok::amp, tok::ampamp, tok::star)) { if (Next->is(QualifierType)) { -// Remove the qualifier. +// Move the qualifier. insertQualifierBefore(SourceMgr, Fixes, Tok, Qualifier); removeToken(SourceMgr, Fixes, Next); return Next; diff --git a/clang/unittests/Format/QualifierFixerTest.cpp b/clang/unittests/Format/QualifierFixerTest.cpp index 14f09d875e6be..0c81c831e1f18 100755 --- a/clang/unittests/Format/QualifierFixerTest.cpp +++ b/clang/unittests/Format/QualifierFixerTest.cpp @@ -858,6 +858,21 @@ TEST_F(QualifierFixerTest, QualifierTemplates) { Style); } +TEST_F(QualifierFixerTest, WithConstraints) { + FormatStyle Style = getLLVMStyle(); + Style.QualifierAlignment = FormatStyle::QAS_Custom; + Style.QualifierOrder = {"constexpr", "type"}; + + verifyFormat("template \n" + " requires Concept\n" + "constexpr constructor();", + Style); + verifyFormat("template \n" + " requires Concept1 && Concept2\n" + "constexpr constructor();", + Style); +} + TEST_F(QualifierFixerTest, DisableRegions) { FormatStyle Style = getLLVMStyle(); Style.QualifierAlignment = FormatStyle::QAS_Custom; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] dbc4d28 - [clang-format] Do not insert space after new/delete keywords in C function declarations
Author: Luis Penagos Date: 2022-02-24T10:06:40+01:00 New Revision: dbc4d281bd6954362ccfc0747893ceaae842671b URL: https://github.com/llvm/llvm-project/commit/dbc4d281bd6954362ccfc0747893ceaae842671b DIFF: https://github.com/llvm/llvm-project/commit/dbc4d281bd6954362ccfc0747893ceaae842671b.diff LOG: [clang-format] Do not insert space after new/delete keywords in C function declarations Fixes https://github.com/llvm/llvm-project/issues/46915. Reviewed By: curdeius, HazardyKnusperkeks Differential Revision: https://reviews.llvm.org/D120374 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 42c271f35be44..01c215f6ad9da 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3299,11 +3299,15 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine , if (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) return Style.SpaceBeforeParensOptions.AfterControlStatements || spaceRequiredBeforeParens(Right); - if (Left.isOneOf(tok::kw_new, tok::kw_delete) || - (Left.is(tok::r_square) && Left.MatchingParen && - Left.MatchingParen->Previous && - Left.MatchingParen->Previous->is(tok::kw_delete))) -return Style.SpaceBeforeParens != FormatStyle::SBPO_Never || + if (Left.isOneOf(tok::kw_new, tok::kw_delete)) +return ((!Line.MightBeFunctionDecl || !Left.Previous) && +Style.SpaceBeforeParens != FormatStyle::SBPO_Never) || + spaceRequiredBeforeParens(Right); + + if (Left.is(tok::r_square) && Left.MatchingParen && + Left.MatchingParen->Previous && + Left.MatchingParen->Previous->is(tok::kw_delete)) +return (Style.SpaceBeforeParens != FormatStyle::SBPO_Never) || spaceRequiredBeforeParens(Right); } if (Line.Type != LT_PreprocessorDirective && diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 98a0111d1ea40..6cd6c4ab9a602 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9919,6 +9919,11 @@ TEST_F(FormatTest, UnderstandsNewAndDelete) { verifyFormat("void operator new(void *foo) ATTRIB;"); verifyFormat("void operator delete[](void *foo) ATTRIB;"); verifyFormat("void operator delete(void *ptr) noexcept;"); + + EXPECT_EQ("void new(link p);\n" +"void delete(link p);\n", +format("void new (link p);\n" + "void delete (link p);\n")); } TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 071f870 - [clang-format] Avoid parsing "requires" as a keyword in non-C++-like languages.
Author: Marek Kurdej Date: 2022-02-22T16:55:38+01:00 New Revision: 071f870e7ff0a3d04f0d93852ff7c29b59111f78 URL: https://github.com/llvm/llvm-project/commit/071f870e7ff0a3d04f0d93852ff7c29b59111f78 DIFF: https://github.com/llvm/llvm-project/commit/071f870e7ff0a3d04f0d93852ff7c29b59111f78.diff LOG: [clang-format] Avoid parsing "requires" as a keyword in non-C++-like languages. Fixes the issue raised post-review in D113319 (cf. https://reviews.llvm.org/D113319#3337485). Reviewed By: krasimir Differential Revision: https://reviews.llvm.org/D120324 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTestJS.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 35465bf9a85b..e2cbcea14d7a 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1563,9 +1563,13 @@ void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind, parseConcept(); return; case tok::kw_requires: { - bool ParsedClause = parseRequires(); - if (ParsedClause) -return; + if (Style.isCpp()) { +bool ParsedClause = parseRequires(); +if (ParsedClause) + return; + } else { +nextToken(); + } break; } case tok::kw_enum: diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index d84533e8a2b0..67df2d41731a 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -323,6 +323,7 @@ TEST_F(FormatTestJS, ReservedWords) { verifyFormat("var struct = 2;"); verifyFormat("var union = 2;"); verifyFormat("var interface = 2;"); + verifyFormat("var requires = {};"); verifyFormat("interface = 2;"); verifyFormat("x = interface instanceof y;"); verifyFormat("interface Test {\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] fee4a97 - [clang-format] Use FormatToken::is* functions without passing through `Tok`. NFC.
Author: Marek Kurdej Date: 2022-02-22T16:41:15+01:00 New Revision: fee4a9712f58caa9f1c3fc6c76ac46c5407475b6 URL: https://github.com/llvm/llvm-project/commit/fee4a9712f58caa9f1c3fc6c76ac46c5407475b6 DIFF: https://github.com/llvm/llvm-project/commit/fee4a9712f58caa9f1c3fc6c76ac46c5407475b6.diff LOG: [clang-format] Use FormatToken::is* functions without passing through `Tok`. NFC. Added: Modified: clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/FormatTokenLexer.cpp clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineParser.cpp Removed: diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index ec268e74fd97..62e0d01871e8 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -1634,7 +1634,7 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState , NewState.HasMultipleNestedBlocks = (Current.BlockParameterCount > 1); if (Style.BraceWrapping.BeforeLambdaBody && Current.Next != nullptr && - Current.Tok.is(tok::l_paren)) { + Current.is(tok::l_paren)) { // Search for any parameter that is a lambda FormatToken const *next = Current.Next; while (next != nullptr) { diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index 1540c14686fa..a48db4ef6d90 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -91,7 +91,7 @@ ArrayRef FormatTokenLexer::lex() { handleCSharpVerbatimAndInterpolatedStrings(); if (Tokens.back()->NewlinesBefore > 0 || Tokens.back()->IsMultiline) FirstInLineIndex = Tokens.size() - 1; - } while (Tokens.back()->Tok.isNot(tok::eof)); + } while (Tokens.back()->isNot(tok::eof)); return Tokens; } @@ -851,7 +851,7 @@ FormatToken *FormatTokenLexer::getNextToken() { // Consume and record whitespace until we find a significant token. unsigned WhitespaceLength = TrailingWhitespace; - while (FormatTok->Tok.is(tok::unknown)) { + while (FormatTok->is(tok::unknown)) { StringRef Text = FormatTok->TokenText; auto EscapesNewline = [&](int pos) { // A '\r' here is just part of '\r\n'. Skip it. @@ -965,12 +965,12 @@ FormatToken *FormatTokenLexer::getNextToken() { FormatTok->OriginalColumn = Column; TrailingWhitespace = 0; - if (FormatTok->Tok.is(tok::comment)) { + if (FormatTok->is(tok::comment)) { // FIXME: Add the trimmed whitespace to Column. StringRef UntrimmedText = FormatTok->TokenText; FormatTok->TokenText = FormatTok->TokenText.rtrim(" \t\v\f"); TrailingWhitespace = UntrimmedText.size() - FormatTok->TokenText.size(); - } else if (FormatTok->Tok.is(tok::raw_identifier)) { + } else if (FormatTok->is(tok::raw_identifier)) { IdentifierInfo = IdentTable.get(FormatTok->TokenText); FormatTok->Tok.setIdentifierInfo(); FormatTok->Tok.setKind(Info.getTokenID()); @@ -985,12 +985,12 @@ FormatToken *FormatTokenLexer::getNextToken() { FormatTok->Tok.setKind(tok::identifier); FormatTok->Tok.setIdentifierInfo(nullptr); } - } else if (FormatTok->Tok.is(tok::greatergreater)) { + } else if (FormatTok->is(tok::greatergreater)) { FormatTok->Tok.setKind(tok::greater); FormatTok->TokenText = FormatTok->TokenText.substr(0, 1); ++Column; StateStack.push(LexerState::TOKEN_STASHED); - } else if (FormatTok->Tok.is(tok::lessless)) { + } else if (FormatTok->is(tok::lessless)) { FormatTok->Tok.setKind(tok::less); FormatTok->TokenText = FormatTok->TokenText.substr(0, 1); ++Column; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 9a020eb6ca7d..7649263a18a1 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -114,7 +114,7 @@ class AnnotatingParser { // If there's a template keyword before the opening angle bracket, this is a // template parameter, not an argument. Contexts.back().InTemplateArgument = -Left->Previous && Left->Previous->Tok.isNot(tok::kw_template); +Left->Previous && Left->Previous->isNot(tok::kw_template); if (Style.Language == FormatStyle::LK_Java && CurrentToken->is(tok::question)) @@ -1266,7 +1266,7 @@ class AnnotatingParser { return LT_ImportStatement; } -if (CurrentToken->Tok.is(tok::numeric_constant)) { +if (CurrentToken->is(tok::numeric_constant)) { CurrentToken->SpacesRequiredBefore = 1; return Type; } @@ -1743,7 +1743,7 @@ class AnnotatingParser { tok::coloncolon)) if (FormatToken *AfterParen = Current.MatchingParen->Next) { // Make sure this isn't the return type of an Obj-C block declaration - if (AfterParen->Tok.isNot(tok::caret)) { + if
[clang] 4701bca - Revert "[clang-format] Avoid inserting space after C++ casts."
Author: Marek Kurdej Date: 2022-02-20T22:19:51+01:00 New Revision: 4701bcae974704a336ac8e111d5b104f4834099c URL: https://github.com/llvm/llvm-project/commit/4701bcae974704a336ac8e111d5b104f4834099c DIFF: https://github.com/llvm/llvm-project/commit/4701bcae974704a336ac8e111d5b104f4834099c.diff LOG: Revert "[clang-format] Avoid inserting space after C++ casts." This reverts commit e021987273bece6e94bc6f43b6b5232de10637c8. This commit provokes failures in formatting tests of polly. Cf. https://lab.llvm.org/buildbot/#/builders/205/builds/3320. That's probably because of `)` being annotated as `CastRParen` instead of `Unknown` before, hence being kept on the same line with the next token. Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 51e7c32b7d4c7..9a020eb6ca7dc 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1734,11 +1734,8 @@ class AnnotatingParser { else Current.setType(TT_LineComment); } else if (Current.is(tok::r_paren)) { - if (rParenEndsCast(Current)) { + if (rParenEndsCast(Current)) Current.setType(TT_CastRParen); -assert(Current.MatchingParen); -Current.MatchingParen->setType(TT_Unknown); - } if (Current.MatchingParen && Current.Next && !Current.Next->isBinaryOperator() && !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace, @@ -1941,20 +1938,8 @@ class AnnotatingParser { // Certain other tokens right before the parentheses are also signals that // this cannot be a cast. - if (LeftOfParens->is(TT_TemplateCloser)) { -if (LeftOfParens->MatchingParen) { - auto *Prev = LeftOfParens->MatchingParen->getPreviousNonComment(); - if (Prev && - Prev->isOneOf(tok::kw_const_cast, tok::kw_dynamic_cast, -tok::kw_reinterpret_cast, tok::kw_static_cast)) -// FIXME: Maybe we should handle identifiers ending with "_cast", -// e.g. any_cast? -return true; -} -return false; - } if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator, -tok::ellipsis)) +TT_TemplateCloser, tok::ellipsis)) return false; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index d45146d5242fb..f71f8dc5de456 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -10565,13 +10565,6 @@ TEST_F(FormatTest, FormatsBinaryOperatorsPrecedingEquals) { TEST_F(FormatTest, FormatsCasts) { verifyFormat("Type *A = static_cast(P);"); - verifyFormat("static_cast(P);"); - verifyFormat("static_cast(Fun)(Args);"); - verifyFormat("static_cast(*Fun)(Args);"); - verifyFormat("a = static_cast(*Fun)(Args);"); - verifyFormat("const_cast(*Fun)(Args);"); - verifyFormat("dynamic_cast(*Fun)(Args);"); - verifyFormat("reinterpret_cast(*Fun)(Args);"); verifyFormat("Type *A = (Type *)P;"); verifyFormat("Type *A = (vector)P;"); verifyFormat("int a = (int)(2.0f);"); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e021987 - [clang-format] Avoid inserting space after C++ casts.
Author: Marek Kurdej Date: 2022-02-20T21:58:37+01:00 New Revision: e021987273bece6e94bc6f43b6b5232de10637c8 URL: https://github.com/llvm/llvm-project/commit/e021987273bece6e94bc6f43b6b5232de10637c8 DIFF: https://github.com/llvm/llvm-project/commit/e021987273bece6e94bc6f43b6b5232de10637c8.diff LOG: [clang-format] Avoid inserting space after C++ casts. Fixes https://github.com/llvm/llvm-project/issues/53876. This is a solution for standard C++ casts: const_cast, dynamic_cast, reinterpret_cast, static_cast. A general approach handling all possible casts is not possible without semantic information. Consider the code: ``` static_cast(*function_pointer_variable)(arguments); ``` vs. ``` some_return_type (*function_pointer_variable)(parameters); // Later used as: function_pointer_variable = _function; return function_pointer_variable(args); ``` In the latter case, it's not a cast but a variable declaration of a pointer to function. Without knowing what `some_return_type` is (and clang-format does not know it), it's hard to distinguish between the two cases. Theoretically, one could check whether "parameters" are types (not a cast) and "arguments" are value/expressions (a cast), but that might be inefficient (needs lots of lookahead). Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D120140 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 9a020eb6ca7dc..51e7c32b7d4c7 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1734,8 +1734,11 @@ class AnnotatingParser { else Current.setType(TT_LineComment); } else if (Current.is(tok::r_paren)) { - if (rParenEndsCast(Current)) + if (rParenEndsCast(Current)) { Current.setType(TT_CastRParen); +assert(Current.MatchingParen); +Current.MatchingParen->setType(TT_Unknown); + } if (Current.MatchingParen && Current.Next && !Current.Next->isBinaryOperator() && !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace, @@ -1938,8 +1941,20 @@ class AnnotatingParser { // Certain other tokens right before the parentheses are also signals that // this cannot be a cast. + if (LeftOfParens->is(TT_TemplateCloser)) { +if (LeftOfParens->MatchingParen) { + auto *Prev = LeftOfParens->MatchingParen->getPreviousNonComment(); + if (Prev && + Prev->isOneOf(tok::kw_const_cast, tok::kw_dynamic_cast, +tok::kw_reinterpret_cast, tok::kw_static_cast)) +// FIXME: Maybe we should handle identifiers ending with "_cast", +// e.g. any_cast? +return true; +} +return false; + } if (LeftOfParens->isOneOf(tok::at, tok::r_square, TT_OverloadedOperator, -TT_TemplateCloser, tok::ellipsis)) +tok::ellipsis)) return false; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index f71f8dc5de456..d45146d5242fb 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -10565,6 +10565,13 @@ TEST_F(FormatTest, FormatsBinaryOperatorsPrecedingEquals) { TEST_F(FormatTest, FormatsCasts) { verifyFormat("Type *A = static_cast(P);"); + verifyFormat("static_cast(P);"); + verifyFormat("static_cast(Fun)(Args);"); + verifyFormat("static_cast(*Fun)(Args);"); + verifyFormat("a = static_cast(*Fun)(Args);"); + verifyFormat("const_cast(*Fun)(Args);"); + verifyFormat("dynamic_cast(*Fun)(Args);"); + verifyFormat("reinterpret_cast(*Fun)(Args);"); verifyFormat("Type *A = (Type *)P;"); verifyFormat("Type *A = (vector)P;"); verifyFormat("int a = (int)(2.0f);"); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] d9567ba - Fix extraneous whitespace addition in line comments on clang-format directives
Author: Luis Penagos Date: 2022-02-20T21:53:50+01:00 New Revision: d9567babef302cfd7e827df64138151ba2614b83 URL: https://github.com/llvm/llvm-project/commit/d9567babef302cfd7e827df64138151ba2614b83 DIFF: https://github.com/llvm/llvm-project/commit/d9567babef302cfd7e827df64138151ba2614b83.diff LOG: Fix extraneous whitespace addition in line comments on clang-format directives Fixes https://github.com/llvm/llvm-project/issues/53844. I believe this regression was caused by not accounting for clang-format directives in https://reviews.llvm.org/D92257. Reviewed By: HazardyKnusperkeks, curdeius Differential Revision: https://reviews.llvm.org/D120188 Added: Modified: clang/lib/Format/BreakableToken.cpp clang/unittests/Format/FormatTestComments.cpp Removed: diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 5138c7cd42cc6..967ddeb82383a 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -815,10 +815,13 @@ BreakableLineCommentSection::BreakableLineCommentSection( assert(Lines[i].size() > IndentPrefix.size()); const auto FirstNonSpace = Lines[i][IndentPrefix.size()]; -const auto AllowsSpaceChange = -SpacesInPrefix != 0 || -(!NoSpaceBeforeFirstCommentChar() || - (FirstNonSpace == '}' && FirstLineSpaceChange != 0)); +const bool IsFormatComment = LineTok && switchesFormatting(*LineTok); +const bool LineRequiresLeadingSpace = +!NoSpaceBeforeFirstCommentChar() || +(FirstNonSpace == '}' && FirstLineSpaceChange != 0); +const bool AllowsSpaceChange = +!IsFormatComment && +(SpacesInPrefix != 0 || LineRequiresLeadingSpace); if (PrefixSpaceChange[i] > 0 && AllowsSpaceChange) { Prefix[i] = IndentPrefix.str(); diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index c988a2869e568..f83ffb393ac2f 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -91,6 +91,11 @@ TEST_F(FormatTestComments, UnderstandsSingleLineComments) { "// line 2\n" "void f() {}\n"); + EXPECT_EQ("// comment\n" +"// clang-format on\n", +format("//comment\n" + "// clang-format on\n")); + verifyFormat("void f() {\n" " // Doesn't do anything\n" "}"); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 331e8e4 - [clang-format] Do not add space after return-like keywords in macros.
Author: Marek Kurdej Date: 2022-02-17T22:12:39+01:00 New Revision: 331e8e4e27be5dd673898a89a7cf00e76903216a URL: https://github.com/llvm/llvm-project/commit/331e8e4e27be5dd673898a89a7cf00e76903216a DIFF: https://github.com/llvm/llvm-project/commit/331e8e4e27be5dd673898a89a7cf00e76903216a.diff LOG: [clang-format] Do not add space after return-like keywords in macros. Fixes https://github.com/llvm/llvm-project/issues/6. Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D120028 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 206fa4541217c..9a020eb6ca7dc 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2989,7 +2989,8 @@ bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken ) const { bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine , const FormatToken , const FormatToken ) { - if (Left.is(tok::kw_return) && Right.isNot(tok::semi)) + if (Left.is(tok::kw_return) && + !Right.isOneOf(tok::semi, tok::r_paren, tok::hashhash)) return true; if (Style.isJson() && Left.is(tok::string_literal) && Right.is(tok::colon)) return false; @@ -3026,7 +3027,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine , return false; // co_await (x), co_yield (x), co_return (x) if (Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return) && - Right.isNot(tok::semi)) + !Right.isOneOf(tok::semi, tok::r_paren)) return true; if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 73503696741a7..f71f8dc5de456 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -1861,6 +1861,16 @@ TEST_F(FormatTest, UnderstandsMacros) { "#define BBB }\n", Style); // verifyFormat("#define AAA N { //\n", Style); + + verifyFormat("MACRO(return)"); + verifyFormat("MACRO(co_await)"); + verifyFormat("MACRO(co_return)"); + verifyFormat("MACRO(co_yield)"); + verifyFormat("MACRO(return, something)"); + verifyFormat("MACRO(co_return, something)"); + verifyFormat("MACRO(something##something)"); + verifyFormat("MACRO(return##something)"); + verifyFormat("MACRO(co_return##something)"); } TEST_F(FormatTest, ShortBlocksInMacrosDontMergeWithCodeAfterMacro) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 0ae2464 - [clang-format] Fix wrong assertion with non-negative shift when aligning tokens.
Author: Marek Kurdej Date: 2022-02-17T09:49:00+01:00 New Revision: 0ae2464fcd4d2c2f285b83d16ff6e2426dd722d2 URL: https://github.com/llvm/llvm-project/commit/0ae2464fcd4d2c2f285b83d16ff6e2426dd722d2 DIFF: https://github.com/llvm/llvm-project/commit/0ae2464fcd4d2c2f285b83d16ff6e2426dd722d2.diff LOG: [clang-format] Fix wrong assertion with non-negative shift when aligning tokens. Fixes https://github.com/llvm/llvm-project/issues/53880. Added: Modified: clang/lib/Format/WhitespaceManager.cpp clang/unittests/Format/FormatTestSelective.cpp Removed: diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 758dc5860888e..55e0b7f8e8d9e 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -406,7 +406,7 @@ AlignTokenSequence(const FormatStyle , unsigned Start, unsigned End, Changes[i].Spaces += Shift; // We should not remove required spaces unless we break the line before. -assert(Changes[i].NewlinesBefore > 0 || +assert(Shift >= 0 || Changes[i].NewlinesBefore > 0 || Changes[i].Spaces >= static_cast(Changes[i].Tok->SpacesRequiredBefore) || Changes[i].Tok->is(tok::eof)); diff --git a/clang/unittests/Format/FormatTestSelective.cpp b/clang/unittests/Format/FormatTestSelective.cpp index c88d1b8bd8ba2..2725e4cf776f6 100644 --- a/clang/unittests/Format/FormatTestSelective.cpp +++ b/clang/unittests/Format/FormatTestSelective.cpp @@ -603,6 +603,14 @@ TEST_F(FormatTestSelective, KeepsIndentAfterCommentSectionImport) { EXPECT_EQ(Code, format(Code, 47, 1)); } +TEST_F(FormatTestSelective, DontAssert) { + // https://llvm.org/PR53880 + std::string Code = "void f() {\n" + " return a == 8 ? 32 : 16;\n" + "}\n"; + EXPECT_EQ(Code, format(Code, 40, 0)); +} + } // end namespace } // end namespace format } // end namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] ef39235 - [clang-format] Make checking for a record more robust and avoid a loop.
Author: Marek Kurdej Date: 2022-02-16T23:05:49+01:00 New Revision: ef39235cb94289281d610e4df52ad2a746d6af61 URL: https://github.com/llvm/llvm-project/commit/ef39235cb94289281d610e4df52ad2a746d6af61 DIFF: https://github.com/llvm/llvm-project/commit/ef39235cb94289281d610e4df52ad2a746d6af61.diff LOG: [clang-format] Make checking for a record more robust and avoid a loop. Added: Modified: clang/lib/Format/UnwrappedLineFormatter.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 16fa2e7b50f1..dbf1e4cbbf6a 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -312,10 +312,15 @@ class LineJoiner { break; // Check if the found line starts a record. - for (const FormatToken *RecordTok = (*J)->Last; RecordTok; - RecordTok = RecordTok->Previous) -if (RecordTok->is(tok::l_brace)) - return isRecordLBrace(*RecordTok); + const FormatToken *LastNonComment = (*J)->Last; + assert(LastNonComment); + if (LastNonComment->is(tok::comment)) { +LastNonComment = LastNonComment->getPreviousNonComment(); +// There must be another token (usually `{`), because we chose a +// line that has a smaller level. +assert(LastNonComment); + } + return isRecordLBrace(*LastNonComment); } } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 6e5dd3284633..73503696741a 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -3809,6 +3809,18 @@ TEST_F(FormatTest, FormatsNamespaces) { " }\n" "} // namespace\n", ShortInlineFunctions); + verifyFormat("namespace { /* comment */\n" + " void f() {\n" + "return;\n" + " }\n" + "} // namespace\n", + ShortInlineFunctions); + verifyFormat("namespace { // comment\n" + " void f() {\n" + "return;\n" + " }\n" + "} // namespace\n", + ShortInlineFunctions); verifyFormat("namespace {\n" " int some_int;\n" " void f() {\n" @@ -3828,6 +3840,18 @@ TEST_F(FormatTest, FormatsNamespaces) { " };\n" "} // namespace\n", ShortInlineFunctions); + verifyFormat("namespace {\n" + " class X { /* comment */\n" + "void f() { return; }\n" + " };\n" + "} // namespace\n", + ShortInlineFunctions); + verifyFormat("namespace {\n" + " class X { // comment\n" + "void f() { return; }\n" + " };\n" + "} // namespace\n", + ShortInlineFunctions); verifyFormat("namespace {\n" " struct X {\n" "void f() { return; }\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 48a31c8 - [clang-format] Mark FormatToken::getPreviousNonComment() nodiscard. NFC.
Author: Marek Kurdej Date: 2022-02-16T22:56:32+01:00 New Revision: 48a31c8f429022a07e2e35f3e62d5f495117f2e7 URL: https://github.com/llvm/llvm-project/commit/48a31c8f429022a07e2e35f3e62d5f495117f2e7 DIFF: https://github.com/llvm/llvm-project/commit/48a31c8f429022a07e2e35f3e62d5f495117f2e7.diff LOG: [clang-format] Mark FormatToken::getPreviousNonComment() nodiscard. NFC. Added: Modified: clang/lib/Format/FormatToken.h Removed: diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 6aaf66c7bb7e..6b7d475232b0 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -693,7 +693,7 @@ struct FormatToken { } /// Returns the previous token ignoring comments. - FormatToken *getPreviousNonComment() const { + LLVM_NODISCARD FormatToken *getPreviousNonComment() const { FormatToken *Tok = Previous; while (Tok && Tok->is(tok::comment)) Tok = Tok->Previous; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] d81f003 - [clang-format] Fix formatting of struct-like records followed by variable declaration.
Author: Marek Kurdej Date: 2022-02-16T22:37:32+01:00 New Revision: d81f003ce1419aee6cfb8d26f0bca9153278872a URL: https://github.com/llvm/llvm-project/commit/d81f003ce1419aee6cfb8d26f0bca9153278872a DIFF: https://github.com/llvm/llvm-project/commit/d81f003ce1419aee6cfb8d26f0bca9153278872a.diff LOG: [clang-format] Fix formatting of struct-like records followed by variable declaration. Fixes https://github.com/llvm/llvm-project/issues/24781. Fixes https://github.com/llvm/llvm-project/issues/38160. This patch splits `TT_RecordLBrace` for classes/enums/structs/unions (and other records, e.g. interfaces) and uses the brace type to avoid the error-prone scanning for record token. The mentioned bugs were provoked by the scanning being too limited (and so not considering `const` or `constexpr`, or other qualifiers, on an anonymous struct variable declaration). Moreover, the proposed solution is more efficient as we parse tokens once only (scanning being parsing too). Reviewed By: MyDeveloperDay, HazardyKnusperkeks Differential Revision: https://reviews.llvm.org/D119785 Added: Modified: clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineFormatter.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index fee365ecc8f91..6aaf66c7bb7e5 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -37,6 +37,7 @@ namespace format { TYPE(BlockComment) \ TYPE(BracedListLBrace) \ TYPE(CastRParen) \ + TYPE(ClassLBrace) \ TYPE(CompoundRequirementLBrace) \ TYPE(ConditionalExpr) \ TYPE(ConflictAlternative) \ @@ -47,6 +48,7 @@ namespace format { TYPE(DesignatedInitializerLSquare) \ TYPE(DesignatedInitializerPeriod) \ TYPE(DictLiteral) \ + TYPE(EnumLBrace) \ TYPE(FatArrow) \ TYPE(ForEachMacro) \ TYPE(FunctionAnnotationRParen) \ @@ -108,6 +110,7 @@ namespace format { TYPE(StartOfName) \ TYPE(StatementAttributeLikeMacro) \ TYPE(StatementMacro) \ + TYPE(StructLBrace) \ TYPE(StructuredBindingLSquare) \ TYPE(TemplateCloser) \ TYPE(TemplateOpener) \ @@ -119,6 +122,7 @@ namespace format { TYPE(TypeDeclarationParen) \ TYPE(TypenameMacro) \ TYPE(UnaryOperator) \ + TYPE(UnionLBrace) \ TYPE(UntouchableMacroFunc) \ TYPE(CSharpStringLiteral) \ TYPE(CSharpNamedArgumentColon) \ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index f3885a1f683bc..206fa4541217c 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1425,11 +1425,12 @@ class AnnotatingParser { TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator, TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral, TT_UntouchableMacroFunc, TT_StatementAttributeLikeMacro, -TT_FunctionLikeOrFreestandingMacro, TT_RecordLBrace, -TT_RequiresClause, TT_RequiresClauseInARequiresExpression, -TT_RequiresExpression, TT_RequiresExpressionLParen, -TT_RequiresExpressionLBrace, TT_BinaryOperator, -TT_CompoundRequirementLBrace, TT_BracedListLBrace)) +
[clang] 05a77fc - [clang-format] Fall through and avoid an unnecessary check. NFC.
Author: Marek Kurdej Date: 2022-02-16T22:07:09+01:00 New Revision: 05a77fc3f97adddc1af3d4fb6d4234047ed09a99 URL: https://github.com/llvm/llvm-project/commit/05a77fc3f97adddc1af3d4fb6d4234047ed09a99 DIFF: https://github.com/llvm/llvm-project/commit/05a77fc3f97adddc1af3d4fb6d4234047ed09a99.diff LOG: [clang-format] Fall through and avoid an unnecessary check. NFC. Added: Modified: clang/lib/Format/TokenAnnotator.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index cb5baae565321..f3885a1f683bc 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -982,10 +982,11 @@ class AnnotatingParser { Tok->setType(TT_JsTypeOperator); break; case tok::kw_if: -case tok::kw_while: - if (Tok->is(tok::kw_if) && CurrentToken && + if (CurrentToken && CurrentToken->isOneOf(tok::kw_constexpr, tok::identifier)) next(); + LLVM_FALLTHROUGH; +case tok::kw_while: if (CurrentToken && CurrentToken->is(tok::l_paren)) { next(); if (!parseParens(/*LookForDecls=*/true)) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] fdee512 - [clang-format] Add test for SpacesInLineCommentPrefix. NFC.
Author: Marek Kurdej Date: 2022-02-16T13:54:55+01:00 New Revision: fdee51204848dce5e0c39db332a7c488dc5b333f URL: https://github.com/llvm/llvm-project/commit/fdee51204848dce5e0c39db332a7c488dc5b333f DIFF: https://github.com/llvm/llvm-project/commit/fdee51204848dce5e0c39db332a7c488dc5b333f.diff LOG: [clang-format] Add test for SpacesInLineCommentPrefix. NFC. Fixes https://github.com/llvm/llvm-project/issues/52649. This was already fixed in commit https://github.com/llvm/llvm-project/commit/e967d97a35a93c883528a9672159edff05f5addb. Added: Modified: clang/unittests/Format/FormatTestComments.cpp Removed: diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index 8cdca0eb5900a..c988a2869e568 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -3650,6 +3650,13 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { format("// x\n" "// y", Style)); + EXPECT_EQ( + "// loong\n" + "// commentcomments\n" + "// normal comments", + format("//loong commentcomments\n" + "// normal comments", + Style)); Style.SpacesInLineCommentPrefix = {3, 3}; EXPECT_EQ("// Lorem ipsum\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e21db15 - [clang-format] Honour PointerAlignment in statements with initializers.
Author: Marek Kurdej Date: 2022-02-15T18:06:32+01:00 New Revision: e21db15be8126004304b813e5ff87c7ecbed06bf URL: https://github.com/llvm/llvm-project/commit/e21db15be8126004304b813e5ff87c7ecbed06bf DIFF: https://github.com/llvm/llvm-project/commit/e21db15be8126004304b813e5ff87c7ecbed06bf.diff LOG: [clang-format] Honour PointerAlignment in statements with initializers. Fixes https://github.com/llvm/llvm-project/issues/53843. Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D119814 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 72f49478d5b4b..a2985eb75a195 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3142,7 +3142,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine , // initializers. if (Line.IsMultiVariableDeclStmt && (Left.NestingLevel == Line.First->NestingLevel || - startsWithInitStatement(Line))) + ((Left.NestingLevel == Line.First->NestingLevel + 1) && + startsWithInitStatement(Line return false; return Left.Previous && !Left.Previous->isOneOf( tok::l_paren, tok::coloncolon, tok::l_square); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index d230964cd2860..1b99b53bbee55 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -8417,6 +8417,13 @@ TEST_F(FormatTest, DeclarationsOfMultipleVariables) { verifyFormat( "/*comment*/ switch (int *p, *q; p != q) {\n default:\nbreak;\n}", Style); + + verifyFormat("if ([](int* p, int* q) {}()) {\n}", Style); + verifyFormat("for ([](int* p, int* q) {}();;) {\n}", Style); + verifyFormat("for (; [](int* p, int* q) {}();) {\n}", Style); + verifyFormat("for (;; [](int* p, int* q) {}()) {\n}", Style); + verifyFormat("switch ([](int* p, int* q) {}()) {\n default:\nbreak;\n}", + Style); } TEST_F(FormatTest, ConditionalExpressionsInBrackets) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c72fdad - [clang-format] Reformat. NFC.
Author: Marek Kurdej Date: 2022-02-14T14:05:05+01:00 New Revision: c72fdad71b6a9e5ca39fdcc7cb8bd476ecc5bbd7 URL: https://github.com/llvm/llvm-project/commit/c72fdad71b6a9e5ca39fdcc7cb8bd476ecc5bbd7 DIFF: https://github.com/llvm/llvm-project/commit/c72fdad71b6a9e5ca39fdcc7cb8bd476ecc5bbd7.diff LOG: [clang-format] Reformat. NFC. Added: Modified: clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 689600c591b26..d230964cd2860 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -8412,8 +8412,11 @@ TEST_F(FormatTest, DeclarationsOfMultipleVariables) { verifyFormat("if (int *p, *q; p != q) {\n p = p->next;\n}", Style); verifyFormat("/*comment*/ if (int *p, *q; p != q) {\n p = p->next;\n}", Style); - verifyFormat("switch (int *p, *q; p != q) {\n default:\nbreak;\n}", Style); - verifyFormat("/*comment*/ switch (int *p, *q; p != q) {\n default:\n break;\n}", Style); + verifyFormat("switch (int *p, *q; p != q) {\n default:\nbreak;\n}", + Style); + verifyFormat( + "/*comment*/ switch (int *p, *q; p != q) {\n default:\nbreak;\n}", + Style); } TEST_F(FormatTest, ConditionalExpressionsInBrackets) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e967d97 - [clang-format] Fix SpacesInLineCommentPrefix deleting tokens.
Author: Marek Kurdej Date: 2022-02-14T09:53:16+01:00 New Revision: e967d97a35a93c883528a9672159edff05f5addb URL: https://github.com/llvm/llvm-project/commit/e967d97a35a93c883528a9672159edff05f5addb DIFF: https://github.com/llvm/llvm-project/commit/e967d97a35a93c883528a9672159edff05f5addb.diff LOG: [clang-format] Fix SpacesInLineCommentPrefix deleting tokens. Fixes https://github.com/llvm/llvm-project/issues/53799. Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D119680 Added: Modified: clang/lib/Format/BreakableToken.cpp clang/unittests/Format/FormatTestComments.cpp Removed: diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index ef8dc2a864a2a..5138c7cd42cc6 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -747,6 +747,7 @@ BreakableLineCommentSection::BreakableLineCommentSection( assert(Tok.is(TT_LineComment) && "line comment section must start with a line comment"); FormatToken *LineTok = nullptr; + const int Minimum = Style.SpacesInLineCommentPrefix.Minimum; // How many spaces we changed in the first line of the section, this will be // applied in all following lines int FirstLineSpaceChange = 0; @@ -769,7 +770,7 @@ BreakableLineCommentSection::BreakableLineCommentSection( Lines[i] = Lines[i].ltrim(Blanks); StringRef IndentPrefix = getLineCommentIndentPrefix(Lines[i], Style); OriginalPrefix[i] = IndentPrefix; - const unsigned SpacesInPrefix = llvm::count(IndentPrefix, ' '); + const int SpacesInPrefix = llvm::count(IndentPrefix, ' '); // This lambda also considers multibyte character that is not handled in // functions like isPunctuation provided by CharInfo. @@ -792,12 +793,11 @@ BreakableLineCommentSection::BreakableLineCommentSection( // e.g. from "///" to "//". if (i == 0 || OriginalPrefix[i].rtrim(Blanks) != OriginalPrefix[i - 1].rtrim(Blanks)) { -if (SpacesInPrefix < Style.SpacesInLineCommentPrefix.Minimum && -Lines[i].size() > IndentPrefix.size() && +if (SpacesInPrefix < Minimum && Lines[i].size() > IndentPrefix.size() && !NoSpaceBeforeFirstCommentChar()) { - FirstLineSpaceChange = - Style.SpacesInLineCommentPrefix.Minimum - SpacesInPrefix; -} else if (SpacesInPrefix > Style.SpacesInLineCommentPrefix.Maximum) { + FirstLineSpaceChange = Minimum - SpacesInPrefix; +} else if (static_cast(SpacesInPrefix) > + Style.SpacesInLineCommentPrefix.Maximum) { FirstLineSpaceChange = Style.SpacesInLineCommentPrefix.Maximum - SpacesInPrefix; } else { @@ -808,10 +808,9 @@ BreakableLineCommentSection::BreakableLineCommentSection( if (Lines[i].size() != IndentPrefix.size()) { PrefixSpaceChange[i] = FirstLineSpaceChange; -if (SpacesInPrefix + PrefixSpaceChange[i] < -Style.SpacesInLineCommentPrefix.Minimum) { - PrefixSpaceChange[i] += Style.SpacesInLineCommentPrefix.Minimum - - (SpacesInPrefix + PrefixSpaceChange[i]); +if (SpacesInPrefix + PrefixSpaceChange[i] < Minimum) { + PrefixSpaceChange[i] += + Minimum - (SpacesInPrefix + PrefixSpaceChange[i]); } assert(Lines[i].size() > IndentPrefix.size()); diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index dcfd219484fa5..8cdca0eb5900a 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -3645,6 +3645,11 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { " // World\n" "}", format(WrapCode, Style)); + EXPECT_EQ("// x\n" +"// y", +format("// x\n" + "// y", + Style)); Style.SpacesInLineCommentPrefix = {3, 3}; EXPECT_EQ("// Lorem ipsum\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e01f624 - [clang-format] Fix PointerAlignment within lambdas in a multi-variable declaration statement.
Author: Marek Kurdej Date: 2022-02-14T09:41:24+01:00 New Revision: e01f624adb0ed5d0f1369b0679a64484bac10d02 URL: https://github.com/llvm/llvm-project/commit/e01f624adb0ed5d0f1369b0679a64484bac10d02 DIFF: https://github.com/llvm/llvm-project/commit/e01f624adb0ed5d0f1369b0679a64484bac10d02.diff LOG: [clang-format] Fix PointerAlignment within lambdas in a multi-variable declaration statement. Fixes https://github.com/llvm/llvm-project/issues/43115. Also, handle while loops with initializers (C++20) the same way as for loops. Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D119648 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a6c6ddcad117b..72f49478d5b4b 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3134,7 +3134,15 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine , return false; if (getTokenPointerOrReferenceAlignment(Left) == FormatStyle::PAS_Right) return false; -if (Line.IsMultiVariableDeclStmt) +// FIXME: Setting IsMultiVariableDeclStmt for the whole line is error-prone, +// because it does not take into account nested scopes like lambdas. +// In multi-variable declaration statements, attach */& to the variable +// independently of the style. However, avoid doing it if we are in a nested +// scope, e.g. lambda. We still need to special-case statements with +// initializers. +if (Line.IsMultiVariableDeclStmt && +(Left.NestingLevel == Line.First->NestingLevel || + startsWithInitStatement(Line))) return false; return Left.Previous && !Left.Previous->isOneOf( tok::l_paren, tok::coloncolon, tok::l_square); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index fc2b121faee02..689600c591b26 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2031,6 +2031,10 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { verifyFormat("for (int x = 0; int : {1, 2, 3})", Style); verifyFormat("for (f(); auto : {1, 2, 3})", Style); verifyFormat("for (f(); int : {1, 2, 3})", Style); + verifyFormat( + "function res1 = [](int ) { return 0; },\n" + " res2 = [](int ) { return 0; };", + Style); Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; verifyFormat("Const unsigned int *c;\n" @@ -2068,6 +2072,10 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { verifyFormat("for (int x = 0; int& c : {1, 2, 3})", Style); verifyFormat("for (f(); auto& c : {1, 2, 3})", Style); verifyFormat("for (f(); int& c : {1, 2, 3})", Style); + verifyFormat( + "function res1 = [](int& a) { return 0; },\n" + "res2 = [](int& a) { return 0; };", + Style); Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; verifyFormat("Const unsigned int* c;\n" @@ -2121,6 +2129,10 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { verifyFormat("for (int x = 0; int & c : {1, 2, 3})", Style); verifyFormat("for (f(); auto & c : {1, 2, 3})", Style); verifyFormat("for (f(); int & c : {1, 2, 3})", Style); + verifyFormat( + "function res1 = [](int & a) { return 0; },\n" + " res2 = [](int & a) { return 0; };", + Style); Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; verifyFormat("Const unsigned int* c;\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 09559bc - Avoid a vulgarism. NFC.
Author: Marek Kurdej Date: 2022-02-13T22:01:06+01:00 New Revision: 09559bc59a718e597725c7d9747350e9c649fd0e URL: https://github.com/llvm/llvm-project/commit/09559bc59a718e597725c7d9747350e9c649fd0e DIFF: https://github.com/llvm/llvm-project/commit/09559bc59a718e597725c7d9747350e9c649fd0e.diff LOG: Avoid a vulgarism. NFC. Added: Modified: clang/unittests/Format/FormatTestComments.cpp Removed: diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index 282bc46cd048..dcfd219484fa 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -3660,17 +3660,17 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { format(WrapCode, Style)); Style = getLLVMStyleWithColumns(20); - StringRef AShitloadOfSpaces = "// This are more spaces " -"than the ColumnLimit, what now?\n" -"\n" -"// Comment\n" -"\n" -"// This is a text to split in multiple " -"lines, please. Thank you very much!\n" -"\n" -"// A comment with\n" -"// some indentation that has to be split.\n" -"// And now without"; + StringRef LotsOfSpaces = "// This are more spaces " + "than the ColumnLimit, what now?\n" + "\n" + "// Comment\n" + "\n" + "// This is a text to split in multiple " + "lines, please. Thank you very much!\n" + "\n" + "// A comment with\n" + "// some indentation that has to be split.\n" + "// And now without"; EXPECT_EQ("// This are more spaces " "than the ColumnLimit, what now?\n" "\n" @@ -3688,7 +3688,7 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { "// that has to be\n" "// split.\n" "// And now without", -format(AShitloadOfSpaces, Style)); +format(LotsOfSpaces, Style)); Style.SpacesInLineCommentPrefix = {0, 0}; EXPECT_EQ("//This are more\n" @@ -3709,7 +3709,7 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { "// that has to be\n" "// split.\n" "//And now without", -format(AShitloadOfSpaces, Style)); +format(LotsOfSpaces, Style)); Style.SpacesInLineCommentPrefix = {3, 3}; EXPECT_EQ("// This are more\n" @@ -3731,7 +3731,7 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { "// that has to\n" "// be split.\n" "// And now without", -format(AShitloadOfSpaces, Style)); +format(LotsOfSpaces, Style)); Style.SpacesInLineCommentPrefix = {30, -1u}; EXPECT_EQ("// This are more spaces than the " @@ -3746,7 +3746,7 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { "//some indentation that has to be " "split.\n" "// And now without", -format(AShitloadOfSpaces, Style)); +format(LotsOfSpaces, Style)); Style.SpacesInLineCommentPrefix = {2, 4}; EXPECT_EQ("// A Comment to be\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 25282bd - [clang-format] Handle PointerAlignment in `if` and `switch` statements with initializers (C++17) the same way as in `for` loops.
Author: Marek Kurdej Date: 2022-02-13T21:36:58+01:00 New Revision: 25282bd6c4bf54a21c0f8dbf00db6e70922c02fa URL: https://github.com/llvm/llvm-project/commit/25282bd6c4bf54a21c0f8dbf00db6e70922c02fa DIFF: https://github.com/llvm/llvm-project/commit/25282bd6c4bf54a21c0f8dbf00db6e70922c02fa.diff LOG: [clang-format] Handle PointerAlignment in `if` and `switch` statements with initializers (C++17) the same way as in `for` loops. Reviewed By: MyDeveloperDay, owenpan Differential Revision: https://reviews.llvm.org/D119650 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index f1db5224fc55b..a6c6ddcad117b 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -26,6 +26,13 @@ namespace format { namespace { +/// Returns \c true if the line starts with a token that can start a statement +/// with an initializer. +static bool startsWithInitStatement(const AnnotatedLine ) { + return Line.startsWith(tok::kw_for) || Line.startsWith(tok::kw_if) || + Line.startsWith(tok::kw_switch); +} + /// Returns \c true if the token can be used as an identifier in /// an Objective-C \c \@selector, \c false otherwise. /// @@ -1135,7 +1142,7 @@ class AnnotatingParser { else if (Contexts.back().InInheritanceList) Tok->setType(TT_InheritanceComma); else if (Contexts.back().FirstStartOfName && - (Contexts.size() == 1 || Line.startsWith(tok::kw_for))) { + (Contexts.size() == 1 || startsWithInitStatement(Line))) { Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true; Line.IsMultiVariableDeclStmt = true; } @@ -3090,7 +3097,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine , FormatStyle::PAS_Left || (Line.IsMultiVariableDeclStmt && (Left.NestingLevel == 0 || - (Left.NestingLevel == 1 && Line.First->is(tok::kw_for); + (Left.NestingLevel == 1 && startsWithInitStatement(Line); } if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) && (!Left.is(TT_PointerOrReference) || diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 40de29e58737f..fc2b121faee02 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -8396,6 +8396,12 @@ TEST_F(FormatTest, DeclarationsOfMultipleVariables) { Style); verifyFormat("vector a, b;", Style); verifyFormat("for (int *p, *q; p != q; p = p->next) {\n}", Style); + verifyFormat("/*comment*/ for (int *p, *q; p != q; p = p->next) {\n}", Style); + verifyFormat("if (int *p, *q; p != q) {\n p = p->next;\n}", Style); + verifyFormat("/*comment*/ if (int *p, *q; p != q) {\n p = p->next;\n}", + Style); + verifyFormat("switch (int *p, *q; p != q) {\n default:\nbreak;\n}", Style); + verifyFormat("/*comment*/ switch (int *p, *q; p != q) {\n default:\n break;\n}", Style); } TEST_F(FormatTest, ConditionalExpressionsInBrackets) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 9cb9445 - [clang-format] Correctly format loops and `if` statements even if preceded with comments.
Author: Marek Kurdej Date: 2022-02-13T21:22:17+01:00 New Revision: 9cb944597907458ce9c2f6bd0ecc9723b674b77f URL: https://github.com/llvm/llvm-project/commit/9cb944597907458ce9c2f6bd0ecc9723b674b77f DIFF: https://github.com/llvm/llvm-project/commit/9cb944597907458ce9c2f6bd0ecc9723b674b77f.diff LOG: [clang-format] Correctly format loops and `if` statements even if preceded with comments. Fixes https://github.com/llvm/llvm-project/issues/53758. Braces in loops and in `if` statements with leading (block) comments were formatted according to `BraceWrapping.AfterFunction` and not `AllowShortBlocksOnASingleLine`/`AllowShortLoopsOnASingleLine`/`AllowShortIfStatementsOnASingleLine`. Previously, the code: ``` while (true) { f(); } /*comment*/ while (true) { f(); } ``` was incorrectly formatted to: ``` while (true) { f(); } /*comment*/ while (true) { f(); } ``` when using config: ``` BasedOnStyle: LLVM BreakBeforeBraces: Custom BraceWrapping: AfterFunction: false AllowShortBlocksOnASingleLine: false AllowShortLoopsOnASingleLine: false ``` and it was (correctly but by chance) formatted to: ``` while (true) { f(); } /*comment*/ while (true) { f(); } ``` when using enabling brace wrapping after functions: ``` BasedOnStyle: LLVM BreakBeforeBraces: Custom BraceWrapping: AfterFunction: true AllowShortBlocksOnASingleLine: false AllowShortLoopsOnASingleLine: false ``` Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D119649 Added: Modified: clang/lib/Format/UnwrappedLineFormatter.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 88efda487eeb6..883030cb3dc16 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -319,6 +319,15 @@ class LineJoiner { bool MergeShortFunctions = ShouldMergeShortFunctions(); +const FormatToken *FirstNonComment = TheLine->First; +if (FirstNonComment->is(tok::comment)) { + FirstNonComment = FirstNonComment->getNextNonComment(); + if (!FirstNonComment) +return 0; +} +// FIXME: There are probably cases where we should use FirstNonComment +// instead of TheLine->First. + if (Style.CompactNamespaces) { if (auto nsToken = TheLine->First->getNamespaceToken()) { int i = 0; @@ -358,9 +367,9 @@ class LineJoiner { if (TheLine->Last->is(TT_FunctionLBrace) && TheLine->First != TheLine->Last) return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0; // Try to merge a control statement block with left brace unwrapped. -if (TheLine->Last->is(tok::l_brace) && TheLine->First != TheLine->Last && -TheLine->First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for, -TT_ForEachMacro)) { +if (TheLine->Last->is(tok::l_brace) && FirstNonComment != TheLine->Last && +FirstNonComment->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for, + TT_ForEachMacro)) { return Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never ? tryMergeSimpleBlock(I, E, Limit) : 0; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 0d315734bc951..40de29e58737f 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -1520,6 +1520,36 @@ TEST_F(FormatTest, FormatLoopsWithoutCompoundStatement) { TEST_F(FormatTest, FormatShortBracedStatements) { FormatStyle AllowSimpleBracedStatements = getLLVMStyle(); + EXPECT_EQ(AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine, false); + EXPECT_EQ(AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine, +FormatStyle::SIS_Never); + EXPECT_EQ(AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine, false); + EXPECT_EQ(AllowSimpleBracedStatements.BraceWrapping.AfterFunction, false); + verifyFormat("for (;;) {\n" + " f();\n" + "}"); + verifyFormat("/*comment*/ for (;;) {\n" + " f();\n" + "}"); + verifyFormat("BOOST_FOREACH (int v, vec) {\n" + " f();\n" + "}"); + verifyFormat("/*comment*/ BOOST_FOREACH (int v, vec) {\n" + " f();\n" + "}"); + verifyFormat("while (true) {\n" + " f();\n" + "}"); + verifyFormat("/*comment*/ while (true) {\n" + " f();\n" + "}"); + verifyFormat("if (true) {\n" + " f();\n" + "}"); + verifyFormat("/*comment*/ if (true) {\n" + " f();\n" + "}"); + AllowSimpleBracedStatements.IfMacros.push_back("MYIF"); // Where line-lengths matter, a 2-letter synonym that
[clang] 7d5062c - [clang-format] Remove unnecessary parentheses in return statements. NFC.
Author: Marek Kurdej Date: 2022-02-12T21:25:52+01:00 New Revision: 7d5062c6ac868537605dd0860b2714aba9ece90d URL: https://github.com/llvm/llvm-project/commit/7d5062c6ac868537605dd0860b2714aba9ece90d DIFF: https://github.com/llvm/llvm-project/commit/7d5062c6ac868537605dd0860b2714aba9ece90d.diff LOG: [clang-format] Remove unnecessary parentheses in return statements. NFC. Added: Modified: clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/FormatTokenLexer.cpp clang/lib/Format/NamespaceEndCommentsFixer.cpp clang/lib/Format/TokenAnnotator.cpp Removed: diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 42c3d2e4326b9..23892be8e9e8e 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -331,7 +331,7 @@ bool ContinuationIndenter::mustBreak(const LineState ) { if (Style.BraceWrapping.BeforeLambdaBody && Current.CanBreakBefore && Current.is(TT_LambdaLBrace) && Previous.isNot(TT_LineComment)) { auto LambdaBodyLength = getLengthToMatchingParen(Current, State.Stack); -return (LambdaBodyLength > getColumnLimit(State)); +return LambdaBodyLength > getColumnLimit(State); } if (Current.MustBreakBefore || Current.is(TT_InlineASMColon)) return true; @@ -1234,7 +1234,7 @@ static bool hasNestedBlockInlined(const FormatToken *Previous, return true; // Also a nested block if contains a lambda inside function with 1 parameter - return (Style.BraceWrapping.BeforeLambdaBody && Current.is(TT_LambdaLSquare)); + return Style.BraceWrapping.BeforeLambdaBody && Current.is(TT_LambdaLSquare); } unsigned ContinuationIndenter::moveStateToNextToken(LineState , diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index 0ecae6af4c46b..1540c14686faa 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -500,7 +500,7 @@ bool FormatTokenLexer::canPrecedeRegexLiteral(FormatToken *Prev) { // `!` is an unary prefix operator, but also a post-fix operator that casts // away nullability, so the same check applies. if (Prev->isOneOf(tok::plusplus, tok::minusminus, tok::exclaim)) -return (Tokens.size() < 3 || precedesOperand(Tokens[Tokens.size() - 3])); +return Tokens.size() < 3 || precedesOperand(Tokens[Tokens.size() - 3]); // The previous token must introduce an operand location where regex // literals can occur. diff --git a/clang/lib/Format/NamespaceEndCommentsFixer.cpp b/clang/lib/Format/NamespaceEndCommentsFixer.cpp index 00d161890906f..65f965548da37 100644 --- a/clang/lib/Format/NamespaceEndCommentsFixer.cpp +++ b/clang/lib/Format/NamespaceEndCommentsFixer.cpp @@ -136,7 +136,7 @@ bool validEndComment(const FormatToken *RBraceTok, StringRef NamespaceName, return false; NamespaceNameInComment = Groups.size() > 2 ? Groups[2] : ""; - return (NamespaceNameInComment == NamespaceName); + return NamespaceNameInComment == NamespaceName; } void addEndComment(const FormatToken *RBraceTok, StringRef EndCommentText, diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index dabecbf9c74ab..f1db5224fc55b 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1615,10 +1615,10 @@ class AnnotatingParser { PriorLeadingIdentifier->is(tok::kw_explicit)) PriorLeadingIdentifier = PriorLeadingIdentifier->Previous; - return (PriorLeadingIdentifier && - (PriorLeadingIdentifier->is(TT_TemplateCloser) || - PriorLeadingIdentifier->ClosesRequiresClause) && - LeadingIdentifier->TokenText == Current.Next->TokenText); + return PriorLeadingIdentifier && + (PriorLeadingIdentifier->is(TT_TemplateCloser) || + PriorLeadingIdentifier->ClosesRequiresClause) && + LeadingIdentifier->TokenText == Current.Next->TokenText; } } } @@ -1868,7 +1868,7 @@ class AnnotatingParser { return true; // const a = in JavaScript. -return (Style.isJavaScript() && PreviousNotConst->is(tok::kw_const)); +return Style.isJavaScript() && PreviousNotConst->is(tok::kw_const); } /// Determine whether ')' is ending a cast. @@ -3085,12 +3085,12 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine , Right.Next->Next->is(TT_RangeBasedForLoopColon)) return getTokenPointerOrReferenceAlignment(Right) != FormatStyle::PAS_Left; -return ( -(!Left.isOneOf(TT_PointerOrReference, tok::l_paren) && - (getTokenPointerOrReferenceAlignment(Right) != FormatStyle::PAS_Left || - (Line.IsMultiVariableDeclStmt && - (Left.NestingLevel == 0 || -(Left.NestingLevel ==
[clang] 0104f5e - [clang-format] Mark FormatToken::getNextNonComment() nodiscard. NFC.
Author: Marek Kurdej Date: 2022-02-11T15:20:11+01:00 New Revision: 0104f5efede22890c356810f992162a84cd615dd URL: https://github.com/llvm/llvm-project/commit/0104f5efede22890c356810f992162a84cd615dd DIFF: https://github.com/llvm/llvm-project/commit/0104f5efede22890c356810f992162a84cd615dd.diff LOG: [clang-format] Mark FormatToken::getNextNonComment() nodiscard. NFC. Added: Modified: clang/lib/Format/FormatToken.h Removed: diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 6586ababd1e7b..4c03f436dde3e 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -687,7 +687,7 @@ struct FormatToken { } /// Returns the next token ignoring comments. - const FormatToken *getNextNonComment() const { + LLVM_NODISCARD const FormatToken *getNextNonComment() const { const FormatToken *Tok = Next; while (Tok && Tok->is(tok::comment)) Tok = Tok->Next; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 23f2785 - [clang-format] Avoid multiple calls to FormatToken::getNextNonComment(). NFC.
Author: Marek Kurdej Date: 2022-02-11T15:20:11+01:00 New Revision: 23f27850b1e00e66ba19fc844ad8f2bd70268536 URL: https://github.com/llvm/llvm-project/commit/23f27850b1e00e66ba19fc844ad8f2bd70268536 DIFF: https://github.com/llvm/llvm-project/commit/23f27850b1e00e66ba19fc844ad8f2bd70268536.diff LOG: [clang-format] Avoid multiple calls to FormatToken::getNextNonComment(). NFC. Added: Modified: clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineFormatter.cpp Removed: diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 871194f93f20..93d409118128 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -1221,10 +1221,17 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState , if (Current.is(TT_ArraySubscriptLSquare) && State.Stack.back().StartOfArraySubscripts == 0) State.Stack.back().StartOfArraySubscripts = State.Column; - if (Current.is(TT_ConditionalExpr) && Current.is(tok::question) && - ((Current.MustBreakBefore) || - (Current.getNextNonComment() && -Current.getNextNonComment()->MustBreakBefore))) + + auto IsWrappedConditional = [](const FormatToken ) { +if (!(Tok.is(TT_ConditionalExpr) && Tok.is(tok::question))) + return false; +if (Tok.MustBreakBefore) + return true; + +const FormatToken *Next = Tok.getNextNonComment(); +return Next && Next->MustBreakBefore; + }; + if (IsWrappedConditional(Current)) State.Stack.back().IsWrappedConditional = true; if (Style.BreakBeforeTernaryOperators && Current.is(tok::question)) State.Stack.back().QuestionColumn = State.Column; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index ef4ce3483fcf..70f92c26fa8d 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3598,7 +3598,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine , if (Right.is(tok::colon)) { if (Line.First->isOneOf(tok::kw_default, tok::kw_case)) return Style.SpaceBeforeCaseColon; -if (!Right.getNextNonComment() || Right.getNextNonComment()->is(tok::semi)) +const FormatToken *Next = Right.getNextNonComment(); +if (!Next || Next->is(tok::semi)) return false; if (Right.is(TT_ObjCMethodExpr)) return false; diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 9f49410f741a..88efda487eeb 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -700,9 +700,13 @@ class LineJoiner { if (Line.Last->is(tok::l_brace)) { FormatToken *Tok = I[1]->First; - if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore && - (Tok->getNextNonComment() == nullptr || - Tok->getNextNonComment()->is(tok::semi))) { + auto ShouldMerge = [Tok]() { +if (Tok->isNot(tok::r_brace) || Tok->MustBreakBefore) + return false; +const FormatToken *Next = Tok->getNextNonComment(); +return !Next || Next->is(tok::semi); + }; + if (ShouldMerge()) { // We merge empty blocks even if the line exceeds the column limit. Tok->SpacesRequiredBefore = Style.SpaceInEmptyBlock ? 1 : 0; Tok->CanBreakBefore = true; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] fd16eee - [clang-format] Assert default style instead of commenting. NFC.
Author: Marek Kurdej Date: 2022-02-11T12:01:25+01:00 New Revision: fd16eeea9d16150e35cadae1d77cee831b8cf510 URL: https://github.com/llvm/llvm-project/commit/fd16eeea9d16150e35cadae1d77cee831b8cf510 DIFF: https://github.com/llvm/llvm-project/commit/fd16eeea9d16150e35cadae1d77cee831b8cf510.diff LOG: [clang-format] Assert default style instead of commenting. NFC. Added: Modified: clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index aa50d73499d0..06b2fe5c650c 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -1975,9 +1975,8 @@ TEST_F(FormatTest, ElseIf) { TEST_F(FormatTest, SeparatePointerReferenceAlignment) { FormatStyle Style = getLLVMStyle(); - // Check first the default LLVM style - // Style.PointerAlignment = FormatStyle::PAS_Right; - // Style.ReferenceAlignment = FormatStyle::RAS_Pointer; + EXPECT_EQ(Style.PointerAlignment, FormatStyle::PAS_Right); + EXPECT_EQ(Style.ReferenceAlignment, FormatStyle::RAS_Pointer); verifyFormat("int *f1(int *a, int , int &);", Style); verifyFormat("int (int &, int *a, int );", Style); verifyFormat("int &(int , int &, int *a);", Style); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 326cb51 - [clang-format] Simplify conditions in spaceRequiredBetween. NFC.
Author: Marek Kurdej Date: 2022-02-11T12:01:24+01:00 New Revision: 326cb51b147a1de17ba0157c41c37243d3cbc0ff URL: https://github.com/llvm/llvm-project/commit/326cb51b147a1de17ba0157c41c37243d3cbc0ff DIFF: https://github.com/llvm/llvm-project/commit/326cb51b147a1de17ba0157c41c37243d3cbc0ff.diff LOG: [clang-format] Simplify conditions in spaceRequiredBetween. NFC. Added: Modified: clang/lib/Format/TokenAnnotator.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 28b244b9c59f1..ef4ce3483fcff 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3093,14 +3093,15 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine , Right.Next->is(TT_RangeBasedForLoopColon)) return getTokenPointerOrReferenceAlignment(Left) != FormatStyle::PAS_Right; -return !Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare, - tok::l_paren) && - (getTokenPointerOrReferenceAlignment(Left) != -FormatStyle::PAS_Right && -!Line.IsMultiVariableDeclStmt) && - Left.Previous && - !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon, - tok::l_square); +if (Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare, + tok::l_paren)) + return false; +if (getTokenPointerOrReferenceAlignment(Left) == FormatStyle::PAS_Right) + return false; +if (Line.IsMultiVariableDeclStmt) + return false; +return Left.Previous && !Left.Previous->isOneOf( +tok::l_paren, tok::coloncolon, tok::l_square); } // Ensure right pointer alignment with ellipsis e.g. int *...P if (Left.is(tok::ellipsis) && Left.Previous && ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] a218706 - [clang-format] Add tests for spacing between ref-qualifier and `noexcept`. NFC.
Author: Marek Kurdej Date: 2022-02-11T10:50:05+01:00 New Revision: a218706cba90248be0c60bd6a8f10dbcf0270955 URL: https://github.com/llvm/llvm-project/commit/a218706cba90248be0c60bd6a8f10dbcf0270955 DIFF: https://github.com/llvm/llvm-project/commit/a218706cba90248be0c60bd6a8f10dbcf0270955.diff LOG: [clang-format] Add tests for spacing between ref-qualifier and `noexcept`. NFC. Cf. https://github.com/llvm/llvm-project/issues/44542. Cf. https://github.com/llvm/llvm-project/commit/ae1b7859cbd61d2284d9690bc53482d0b6a46f63. Added: Modified: clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 8639a72eceb12..aa50d73499d04 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9589,8 +9589,11 @@ TEST_F(FormatTest, UnderstandsOverloadedOperators) { } TEST_F(FormatTest, UnderstandsFunctionRefQualification) { + verifyFormat("void A::b() && {}"); + verifyFormat("void A::b() & {}"); verifyFormat("Deleted =(const Deleted &) & = default;"); verifyFormat("Deleted =(const Deleted &) && = delete;"); + verifyFormat("Deleted =(const Deleted &) = default;"); verifyFormat("SomeType MemberFunction(const Deleted &) & = delete;"); verifyFormat("SomeType MemberFunction(const Deleted &) && = delete;"); verifyFormat("Deleted =(const Deleted &) &;"); @@ -9600,8 +9603,10 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { verifyFormat("SomeType MemberFunction(const Deleted &) && {}"); verifyFormat("SomeType MemberFunction(const Deleted &) && final {}"); verifyFormat("SomeType MemberFunction(const Deleted &) && override {}"); + verifyFormat("SomeType MemberFunction(const Deleted &) & {}"); verifyFormat("void Fn(T const &) const &;"); verifyFormat("void Fn(T const volatile &&) const volatile &&;"); + verifyFormat("void Fn(T const volatile &&) const volatile &"); verifyFormat("template \n" "void F(T) && = delete;", getGoogleStyle()); @@ -9609,7 +9614,10 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { FormatStyle AlignLeft = getLLVMStyle(); AlignLeft.PointerAlignment = FormatStyle::PAS_Left; verifyFormat("void A::b() && {}", AlignLeft); + verifyFormat("void A::b() && noexcept {}", AlignLeft); verifyFormat("Deleted& operator=(const Deleted&) & = default;", AlignLeft); + verifyFormat("Deleted& operator=(const Deleted&) & noexcept = default;", + AlignLeft); verifyFormat("SomeType MemberFunction(const Deleted&) & = delete;", AlignLeft); verifyFormat("Deleted& operator=(const Deleted&) &;", AlignLeft); @@ -9620,6 +9628,29 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { verifyFormat("auto Function(T) & -> void;", AlignLeft); verifyFormat("void Fn(T const&) const&;", AlignLeft); verifyFormat("void Fn(T const volatile&&) const volatile&&;", AlignLeft); + verifyFormat("void Fn(T const volatile&&) const volatile&& noexcept;", + AlignLeft); + + FormatStyle AlignMiddle = getLLVMStyle(); + AlignMiddle.PointerAlignment = FormatStyle::PAS_Middle; + verifyFormat("void A::b() && {}", AlignMiddle); + verifyFormat("void A::b() && noexcept {}", AlignMiddle); + verifyFormat("Deleted & operator=(const Deleted &) & = default;", + AlignMiddle); + verifyFormat("Deleted & operator=(const Deleted &) & noexcept = default;", + AlignMiddle); + verifyFormat("SomeType MemberFunction(const Deleted &) & = delete;", + AlignMiddle); + verifyFormat("Deleted & operator=(const Deleted &) &;", AlignMiddle); + verifyFormat("SomeType MemberFunction(const Deleted &) &;", AlignMiddle); + verifyFormat("auto Function(T t) & -> void {}", AlignMiddle); + verifyFormat("auto Function(T... t) & -> void {}", AlignMiddle); + verifyFormat("auto Function(T) & -> void {}", AlignMiddle); + verifyFormat("auto Function(T) & -> void;", AlignMiddle); + verifyFormat("void Fn(T const &) const &;", AlignMiddle); + verifyFormat("void Fn(T const volatile &&) const volatile &&;", AlignMiddle); + verifyFormat("void Fn(T const volatile &&) const volatile && noexcept;", + AlignMiddle); FormatStyle Spaces = getLLVMStyle(); Spaces.SpacesInCStyleCastParentheses = true; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 6c7e6fc - [clang-format] Do not remove required spaces when aligning tokens.
Author: Marek Kurdej Date: 2022-02-10T19:15:27+01:00 New Revision: 6c7e6fc7b6654b7ecd364f352f8ffd6dfecbf77b URL: https://github.com/llvm/llvm-project/commit/6c7e6fc7b6654b7ecd364f352f8ffd6dfecbf77b DIFF: https://github.com/llvm/llvm-project/commit/6c7e6fc7b6654b7ecd364f352f8ffd6dfecbf77b.diff LOG: [clang-format] Do not remove required spaces when aligning tokens. Fixes https://github.com/llvm/llvm-project/issues/44292. Fixes https://github.com/llvm/llvm-project/issues/45874. Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D119419 Added: Modified: clang/lib/Format/WhitespaceManager.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 1d639275b1d59..758dc5860888e 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -331,6 +331,12 @@ AlignTokenSequence(const FormatStyle , unsigned Start, unsigned End, FoundMatchOnLine = true; Shift = Column - Changes[i].StartOfTokenColumn; Changes[i].Spaces += Shift; + // FIXME: This is a workaround that should be removed when we fix + // http://llvm.org/PR53699. An assertion later below verifies this. + if (Changes[i].NewlinesBefore == 0) +Changes[i].Spaces = +std::max(Changes[i].Spaces, + static_cast(Changes[i].Tok->SpacesRequiredBefore)); } // This is for function parameters that are split across multiple lines, @@ -399,6 +405,12 @@ AlignTokenSequence(const FormatStyle , unsigned Start, unsigned End, if (ContinuedStringLiteral) Changes[i].Spaces += Shift; +// We should not remove required spaces unless we break the line before. +assert(Changes[i].NewlinesBefore > 0 || + Changes[i].Spaces >= + static_cast(Changes[i].Tok->SpacesRequiredBefore) || + Changes[i].Tok->is(tok::eof)); + Changes[i].StartOfTokenColumn += Shift; if (i + 1 != Changes.size()) Changes[i + 1].PreviousEndOfTokenColumn += Shift; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index c7516427c2f45..8639a72eceb12 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -17277,6 +17277,31 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { "const unsigned g;\n" "Const unsigned h;", Alignment); + + // See PR46529 + FormatStyle BracedAlign = getLLVMStyle(); + BracedAlign.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; + verifyFormat("const auto result{[]() {\n" + " const auto something = 1;\n" + " return 2;\n" + "}};", + BracedAlign); + verifyFormat("int foo{[]() {\n" + " int bar{0};\n" + " return 0;\n" + "}()};", + BracedAlign); + BracedAlign.Cpp11BracedListStyle = false; + verifyFormat("const auto result{ []() {\n" + " const auto something = 1;\n" + " return 2;\n" + "} };", + BracedAlign); + verifyFormat("int foo{ []() {\n" + " int bar{ 0 };\n" + " return 0;\n" + "}() };", + BracedAlign); } TEST_F(FormatTest, AlignWithLineBreaks) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 4efde1e - [clang-format] Move FormatToken::opensBlockOrBlockTypeList to source file. NFC.
Author: Marek Kurdej Date: 2022-02-10T10:51:03+01:00 New Revision: 4efde1e554cce3f017b3d1ce700bd1860eed2ccd URL: https://github.com/llvm/llvm-project/commit/4efde1e554cce3f017b3d1ce700bd1860eed2ccd DIFF: https://github.com/llvm/llvm-project/commit/4efde1e554cce3f017b3d1ce700bd1860eed2ccd.diff LOG: [clang-format] Move FormatToken::opensBlockOrBlockTypeList to source file. NFC. Added: Modified: clang/lib/Format/FormatToken.cpp clang/lib/Format/FormatToken.h Removed: diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp index 40aa8f5cacb25..5577918d70927 100644 --- a/clang/lib/Format/FormatToken.cpp +++ b/clang/lib/Format/FormatToken.cpp @@ -74,6 +74,20 @@ bool FormatToken::isTypeOrIdentifier() const { return isSimpleTypeSpecifier() || Tok.isOneOf(tok::kw_auto, tok::identifier); } +bool FormatToken::opensBlockOrBlockTypeList(const FormatStyle ) const { + // C# Does not indent object initialisers as continuations. + if (is(tok::l_brace) && getBlockKind() == BK_BracedInit && Style.isCSharp()) +return true; + if (is(TT_TemplateString) && opensScope()) +return true; + return is(TT_ArrayInitializerLSquare) || is(TT_ProtoExtensionLSquare) || + (is(tok::l_brace) && + (getBlockKind() == BK_Block || is(TT_DictLiteral) || + (!Style.Cpp11BracedListStyle && NestingLevel == 0))) || + (is(tok::less) && (Style.Language == FormatStyle::LK_Proto || +Style.Language == FormatStyle::LK_TextProto)); +} + TokenRole::~TokenRole() {} void TokenRole::precomputeFormattingInfos(const FormatToken *Token) {} diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index f116a89ac6440..6586ababd1e7b 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -696,19 +696,7 @@ struct FormatToken { /// Returns \c true if this tokens starts a block-type list, i.e. a /// list that should be indented with a block indent. - bool opensBlockOrBlockTypeList(const FormatStyle ) const { -// C# Does not indent object initialisers as continuations. -if (is(tok::l_brace) && getBlockKind() == BK_BracedInit && Style.isCSharp()) - return true; -if (is(TT_TemplateString) && opensScope()) - return true; -return is(TT_ArrayInitializerLSquare) || is(TT_ProtoExtensionLSquare) || - (is(tok::l_brace) && -(getBlockKind() == BK_Block || is(TT_DictLiteral) || - (!Style.Cpp11BracedListStyle && NestingLevel == 0))) || - (is(tok::less) && (Style.Language == FormatStyle::LK_Proto || - Style.Language == FormatStyle::LK_TextProto)); - } + LLVM_NODISCARD bool opensBlockOrBlockTypeList(const FormatStyle ) const; /// Returns whether the token is the left square bracket of a C++ /// structured binding declaration. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] a7b5e5b - [clang-format] Fix formatting of macro definitions with a leading comment.
Author: Marek Kurdej Date: 2022-02-09T22:39:59+01:00 New Revision: a7b5e5b413bd1654e8e96b9c7842c7c1ab0db58a URL: https://github.com/llvm/llvm-project/commit/a7b5e5b413bd1654e8e96b9c7842c7c1ab0db58a DIFF: https://github.com/llvm/llvm-project/commit/a7b5e5b413bd1654e8e96b9c7842c7c1ab0db58a.diff LOG: [clang-format] Fix formatting of macro definitions with a leading comment. Fixes https://github.com/llvm/llvm-project/issues/43206. Reviewed By: HazardyKnusperkeks Differential Revision: https://reviews.llvm.org/D118924 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 97a2cf367e80..0686aeb253ad 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3551,6 +3551,8 @@ void UnwrappedLineParser::distributeComments( void UnwrappedLineParser::readToken(int LevelDifference) { SmallVector Comments; + bool PreviousWasComment = false; + bool FirstNonCommentOnLine = false; do { FormatTok = Tokens->getNextToken(); assert(FormatTok); @@ -3567,8 +3569,26 @@ void UnwrappedLineParser::readToken(int LevelDifference) { FormatTok->MustBreakBefore = true; } +auto IsFirstNonCommentOnLine = [](bool FirstNonCommentOnLine, + const FormatToken , + bool PreviousWasComment) { + auto IsFirstOnLine = [](const FormatToken ) { +return Tok.HasUnescapedNewline || Tok.IsFirst; + }; + + // Consider preprocessor directives preceded by block comments as first + // on line. + if (PreviousWasComment) +return FirstNonCommentOnLine || IsFirstOnLine(Tok); + return IsFirstOnLine(Tok); +}; + +FirstNonCommentOnLine = IsFirstNonCommentOnLine( +FirstNonCommentOnLine, *FormatTok, PreviousWasComment); +PreviousWasComment = FormatTok->Tok.is(tok::comment); + while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) && - (FormatTok->HasUnescapedNewline || FormatTok->IsFirst)) { + FirstNonCommentOnLine) { distributeComments(Comments, FormatTok); Comments.clear(); // If there is an unfinished unwrapped line, we flush the preprocessor @@ -3587,6 +3607,9 @@ void UnwrappedLineParser::readToken(int LevelDifference) { Line->Level += PPBranchLevel; flushComments(isOnNewLine(*FormatTok)); parsePPDirective(); + PreviousWasComment = FormatTok->Tok.is(tok::comment); + FirstNonCommentOnLine = IsFirstNonCommentOnLine( + FirstNonCommentOnLine, *FormatTok, PreviousWasComment); } if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) && diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 6f76a0c62edf..c7516427c2f4 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -1797,6 +1797,17 @@ TEST_F(FormatTest, FormatShortBracedStatements) { TEST_F(FormatTest, UnderstandsMacros) { verifyFormat("#define A (parentheses)"); + verifyFormat("/* comment */ #define A (parentheses)"); + verifyFormat("/* comment */ /* another comment */ #define A (parentheses)"); + // Even the partial code should never be merged. + EXPECT_EQ("/* comment */ #define A (parentheses)\n" +"#", +format("/* comment */ #define A (parentheses)\n" + "#")); + verifyFormat("/* comment */ #define A (parentheses)\n" + "#\n"); + verifyFormat("/* comment */ #define A (parentheses)\n" + "#define B (parentheses)"); verifyFormat("#define true ((int)1)"); verifyFormat("#define and(x)"); verifyFormat("#define if(x) x"); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] a77c67f - [clang-format] Fix formatting of the array form of delete.
Author: Marek Kurdej Date: 2022-02-09T22:36:13+01:00 New Revision: a77c67f93917596f9eded9edaced4a9d355a4e1c URL: https://github.com/llvm/llvm-project/commit/a77c67f93917596f9eded9edaced4a9d355a4e1c DIFF: https://github.com/llvm/llvm-project/commit/a77c67f93917596f9eded9edaced4a9d355a4e1c.diff LOG: [clang-format] Fix formatting of the array form of delete. Fixes https://github.com/llvm/llvm-project/issues/53576. There was an inconsistency in formatting of delete expressions. Before: ``` delete (void*)a; delete[](void*) a; ``` After this patch: ``` delete (void*)a; delete[] (void*)a; ``` Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D119117 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 76f623147d3a4..28b244b9c59f1 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1883,6 +1883,25 @@ class AnnotatingParser { LeftOfParens = LeftOfParens->MatchingParen->Previous; } + if (LeftOfParens->is(tok::r_square)) { +// delete[] (void *)ptr; +auto MayBeArrayDelete = [](FormatToken *Tok) -> FormatToken * { + if (Tok->isNot(tok::r_square)) +return nullptr; + + Tok = Tok->getPreviousNonComment(); + if (!Tok || Tok->isNot(tok::l_square)) +return nullptr; + + Tok = Tok->getPreviousNonComment(); + if (!Tok || Tok->isNot(tok::kw_delete)) +return nullptr; + return Tok; +}; +if (FormatToken *MaybeDelete = MayBeArrayDelete(LeftOfParens)) + LeftOfParens = MaybeDelete; + } + // The Condition directly below this one will see the operator arguments // as a (void *foo) cast. // void operator delete(void *foo) ATTRIB; @@ -3227,7 +3246,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine , if (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) return Style.SpaceBeforeParensOptions.AfterControlStatements || spaceRequiredBeforeParens(Right); - if (Left.isOneOf(tok::kw_new, tok::kw_delete)) + if (Left.isOneOf(tok::kw_new, tok::kw_delete) || + (Left.is(tok::r_square) && Left.MatchingParen && + Left.MatchingParen->Previous && + Left.MatchingParen->Previous->is(tok::kw_delete))) return Style.SpaceBeforeParens != FormatStyle::SBPO_Never || spaceRequiredBeforeParens(Right); } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 14942d1ba420e..6f76a0c62edf9 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -9744,6 +9744,7 @@ TEST_F(FormatTest, UnderstandsNewAndDelete) { "new (aa(aaa))\n" "typename ();"); verifyFormat("delete[] h->p;"); + verifyFormat("delete[] (void *)p;"); verifyFormat("void operator delete(void *foo) ATTRIB;"); verifyFormat("void operator new(void *foo) ATTRIB;"); diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 88deee974bbf5..acb7386a89df9 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -97,6 +97,28 @@ TEST_F(TokenAnnotatorTest, UnderstandsLBracesInMacroDefinition) { EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_Unknown); } +TEST_F(TokenAnnotatorTest, UnderstandsDelete) { + auto Tokens = annotate("delete (void *)p;"); + EXPECT_EQ(Tokens.size(), 8u) << Tokens; + EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_CastRParen); + + Tokens = annotate("delete[] (void *)p;"); + EXPECT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_CastRParen); + + Tokens = annotate("delete[] /*comment*/ (void *)p;"); + EXPECT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen); + + Tokens = annotate("delete[/*comment*/] (void *)p;"); + EXPECT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen); + + Tokens = annotate("delete/*comment*/[] (void *)p;"); + EXPECT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen); +} + } // namespace } // namespace format } // namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e329b58 - [clang-format] Honour "// clang-format off" when using QualifierOrder.
Author: Marek Kurdej Date: 2022-02-09T22:15:20+01:00 New Revision: e329b5866f1732f5c24cf2ae96479971f7101914 URL: https://github.com/llvm/llvm-project/commit/e329b5866f1732f5c24cf2ae96479971f7101914 DIFF: https://github.com/llvm/llvm-project/commit/e329b5866f1732f5c24cf2ae96479971f7101914.diff LOG: [clang-format] Honour "// clang-format off" when using QualifierOrder. Fixes https://github.com/llvm/llvm-project/issues/53643. Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D119218 Added: Modified: clang/lib/Format/QualifierAlignmentFixer.cpp clang/unittests/Format/QualifierFixerTest.cpp Removed: diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp index 13af32a9f4f47..233b081a95f6d 100644 --- a/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -390,6 +390,10 @@ LeftRightQualifierAlignmentFixer::analyze( for (AnnotatedLine *Line : AnnotatedLines) { FormatToken *First = Line->First; +assert(First); +if (First->Finalized) + continue; + const auto *Last = Line->Last; for (const auto *Tok = First; Tok && Tok != Last && Tok->Next; diff --git a/clang/unittests/Format/QualifierFixerTest.cpp b/clang/unittests/Format/QualifierFixerTest.cpp index 0517de2820d9d..14f09d875e6be 100755 --- a/clang/unittests/Format/QualifierFixerTest.cpp +++ b/clang/unittests/Format/QualifierFixerTest.cpp @@ -858,5 +858,27 @@ TEST_F(QualifierFixerTest, QualifierTemplates) { Style); } +TEST_F(QualifierFixerTest, DisableRegions) { + FormatStyle Style = getLLVMStyle(); + Style.QualifierAlignment = FormatStyle::QAS_Custom; + Style.QualifierOrder = {"inline", "static", "const", "type"}; + + ReplacementCount = 0; + verifyFormat("// clang-format off\n" + "int const inline static a = 0;\n" + "// clang-format on\n", + Style); + EXPECT_EQ(ReplacementCount, 0); + verifyFormat("// clang-format off\n" + "int const inline static a = 0;\n" + "// clang-format on\n" + "inline static const int a = 0;\n", + "// clang-format off\n" + "int const inline static a = 0;\n" + "// clang-format on\n" + "int const inline static a = 0;\n", + Style); +} + } // namespace format } // namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 06e4259 - [clang-format] Comment unused parameters. NFC.
Author: Marek Kurdej Date: 2022-02-08T09:33:55+01:00 New Revision: 06e42590a5275fb8f6f7f225968620b5efe5b6f5 URL: https://github.com/llvm/llvm-project/commit/06e42590a5275fb8f6f7f225968620b5efe5b6f5 DIFF: https://github.com/llvm/llvm-project/commit/06e42590a5275fb8f6f7f225968620b5efe5b6f5.diff LOG: [clang-format] Comment unused parameters. NFC. Added: Modified: clang/lib/Format/QualifierAlignmentFixer.cpp Removed: diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp index 1a0f743a9cba..13af32a9f4f4 100644 --- a/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -59,8 +59,9 @@ QualifierAlignmentFixer::QualifierAlignmentFixer( } std::pair QualifierAlignmentFixer::analyze( -TokenAnnotator , SmallVectorImpl , -FormatTokenLexer ) { +TokenAnnotator & /*Annotator*/, +SmallVectorImpl & /*AnnotatedLines*/, +FormatTokenLexer & /*Tokens*/) { auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn, NextStartColumn, LastStartColumn); if (!Env) @@ -376,7 +377,8 @@ LeftRightQualifierAlignmentFixer::LeftRightQualifierAlignmentFixer( std::pair LeftRightQualifierAlignmentFixer::analyze( -TokenAnnotator , SmallVectorImpl , +TokenAnnotator & /*Annotator*/, +SmallVectorImpl , FormatTokenLexer ) { tooling::Replacements Fixes; const AdditionalKeywords = Tokens.getKeywords(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7d63973 - [clang-format] Fix typo. NFC.
Author: Marek Kurdej Date: 2022-02-08T09:33:54+01:00 New Revision: 7d6397348e453a0c941bca0f3a30087680d2f14c URL: https://github.com/llvm/llvm-project/commit/7d6397348e453a0c941bca0f3a30087680d2f14c DIFF: https://github.com/llvm/llvm-project/commit/7d6397348e453a0c941bca0f3a30087680d2f14c.diff LOG: [clang-format] Fix typo. NFC. Added: Modified: clang/lib/Format/QualifierAlignmentFixer.cpp Removed: diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp index aeec8da951827..1a0f743a9cbaf 100644 --- a/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -37,7 +37,7 @@ QualifierAlignmentFixer::QualifierAlignmentFixer( PrepareLeftRightOrdering(Style.QualifierOrder, LeftOrder, RightOrder, ConfiguredQualifierTokens); - // Handle the left and right Alignment Seperately + // Handle the left and right alignment separately. for (const auto : LeftOrder) { Passes.emplace_back( [&, Qualifier, ConfiguredQualifierTokens](const Environment ) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] ca0d970 - [clang-format] Avoid merging macro definitions.
Author: Marek Kurdej Date: 2022-02-03T18:54:46+01:00 New Revision: ca0d97072e79f8d7159c50db616647eeb1b094b8 URL: https://github.com/llvm/llvm-project/commit/ca0d97072e79f8d7159c50db616647eeb1b094b8 DIFF: https://github.com/llvm/llvm-project/commit/ca0d97072e79f8d7159c50db616647eeb1b094b8.diff LOG: [clang-format] Avoid merging macro definitions. Fixes https://github.com/llvm/llvm-project/issues/42087. Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D118879 Added: Modified: clang/lib/Format/UnwrappedLineFormatter.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 08ba442b5f0e..f7d26b813f4f 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -621,6 +621,10 @@ class LineJoiner { tryMergeSimpleBlock(SmallVectorImpl::const_iterator I, SmallVectorImpl::const_iterator E, unsigned Limit) { +// Don't merge with a preprocessor directive. +if (I[1]->Type == LT_PreprocessorDirective) + return 0; + AnnotatedLine = **I; // Don't merge ObjC @ keywords and methods. diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 3d9e38616450..094b9142aa10 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -1805,6 +1805,21 @@ TEST_F(FormatTest, UnderstandsMacros) { verifyFormat("#define xor(x) (^(x))"); verifyFormat("#define __except(x)"); verifyFormat("#define __try(x)"); + + FormatStyle Style = getLLVMStyle(); + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterFunction = true; + // Test that a macro definition never gets merged with the following + // definition. + // FIXME: The AAA macro definition probably should not be split into 3 lines. + verifyFormat("#define AAA " + "\\\n" + " N " + "\\\n" + " {\n" + "#define BBB }\n", + Style); + // verifyFormat("#define AAA N { //\n", Style); } TEST_F(FormatTest, ShortBlocksInMacrosDontMergeWithCodeAfterMacro) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 529aa4b - [clang-format] Avoid adding space after the name of a function-like macro when the name is a keyword.
Author: Marek Kurdej Date: 2022-02-03T18:45:51+01:00 New Revision: 529aa4b011c4ae808d658022ef643c44dd9b2c9c URL: https://github.com/llvm/llvm-project/commit/529aa4b011c4ae808d658022ef643c44dd9b2c9c DIFF: https://github.com/llvm/llvm-project/commit/529aa4b011c4ae808d658022ef643c44dd9b2c9c.diff LOG: [clang-format] Avoid adding space after the name of a function-like macro when the name is a keyword. Fixes https://github.com/llvm/llvm-project/issues/31086. Before the code: ``` #define if(x) ``` was erroneously formatted to: ``` #define if (x) ``` Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D118844 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index c43c8da6f3984..37fad4d9f49de 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1007,6 +1007,12 @@ void UnwrappedLineParser::parsePPDefine() { } } + // In the context of a define, even keywords should be treated as normal + // identifiers. Setting the kind to identifier is not enough, because we need + // to treat additional keywords like __except as well, which are already + // identifiers. + FormatTok->Tok.setKind(tok::identifier); + FormatTok->Tok.setIdentifierInfo(nullptr); nextToken(); if (FormatTok->Tok.getKind() == tok::l_paren && !FormatTok->hasWhitespaceBefore()) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 720c6e9b6b2f1..3d9e38616450c 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -1795,6 +1795,18 @@ TEST_F(FormatTest, FormatShortBracedStatements) { AllowSimpleBracedStatements); } +TEST_F(FormatTest, UnderstandsMacros) { + verifyFormat("#define A (parentheses)"); + verifyFormat("#define true ((int)1)"); + verifyFormat("#define and(x)"); + verifyFormat("#define if(x) x"); + verifyFormat("#define return(x) (x)"); + verifyFormat("#define while(x) for (; x;)"); + verifyFormat("#define xor(x) (^(x))"); + verifyFormat("#define __except(x)"); + verifyFormat("#define __try(x)"); +} + TEST_F(FormatTest, ShortBlocksInMacrosDontMergeWithCodeAfterMacro) { FormatStyle Style = getLLVMStyleWithColumns(60); Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 768a619 - [clang-format] Reserve vectors when the number of items is known beforehand. NFC.
Author: Marek Kurdej Date: 2022-02-03T10:38:23+01:00 New Revision: 768a6192dfc680c0c941e713c824b9046429538d URL: https://github.com/llvm/llvm-project/commit/768a6192dfc680c0c941e713c824b9046429538d DIFF: https://github.com/llvm/llvm-project/commit/768a6192dfc680c0c941e713c824b9046429538d.diff LOG: [clang-format] Reserve vectors when the number of items is known beforehand. NFC. Added: Modified: clang/lib/Format/FormatToken.cpp clang/lib/Format/TokenAnalyzer.cpp Removed: diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp index 59d6f29bb54d2..40aa8f5cacb25 100644 --- a/clang/lib/Format/FormatToken.cpp +++ b/clang/lib/Format/FormatToken.cpp @@ -186,6 +186,9 @@ void CommaSeparatedList::precomputeFormattingInfos(const FormatToken *Token) { // The lengths of an item if it is put at the end of the line. This includes // trailing comments which are otherwise ignored for column alignment. SmallVector EndOfLineItemLength; + MustBreakBeforeItem.reserve(Commas.size() + 1); + EndOfLineItemLength.reserve(Commas.size() + 1); + ItemLengths.reserve(Commas.size() + 1); bool HasSeparatingComment = false; for (unsigned i = 0, e = Commas.size() + 1; i != e; ++i) { diff --git a/clang/lib/Format/TokenAnalyzer.cpp b/clang/lib/Format/TokenAnalyzer.cpp index 348da1f03f299..0a775c0a87eda 100644 --- a/clang/lib/Format/TokenAnalyzer.cpp +++ b/clang/lib/Format/TokenAnalyzer.cpp @@ -116,6 +116,7 @@ std::pair TokenAnalyzer::process() { const auto = UnwrappedLines[Run]; LLVM_DEBUG(llvm::dbgs() << "Run " << Run << "...\n"); SmallVector AnnotatedLines; +AnnotatedLines.reserve(Lines.size()); TokenAnnotator Annotator(Style, Lex.getKeywords()); for (const UnwrappedLine : Lines) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7cc3e02 - [clang-format] Use back() instead of rbegin(). NFC.
Author: Marek Kurdej Date: 2022-02-03T10:07:02+01:00 New Revision: 7cc3e0204210a8c9c12f29fddbfec9dfe786e931 URL: https://github.com/llvm/llvm-project/commit/7cc3e0204210a8c9c12f29fddbfec9dfe786e931 DIFF: https://github.com/llvm/llvm-project/commit/7cc3e0204210a8c9c12f29fddbfec9dfe786e931.diff LOG: [clang-format] Use back() instead of rbegin(). NFC. Added: Modified: clang/lib/Format/TokenAnalyzer.cpp Removed: diff --git a/clang/lib/Format/TokenAnalyzer.cpp b/clang/lib/Format/TokenAnalyzer.cpp index 2bd5a1fd6230..348da1f03f29 100644 --- a/clang/lib/Format/TokenAnalyzer.cpp +++ b/clang/lib/Format/TokenAnalyzer.cpp @@ -110,7 +110,7 @@ std::pair TokenAnalyzer::process() { UnwrappedLineParser Parser(Style, Lex.getKeywords(), Env.getFirstStartColumn(), Tokens, *this); Parser.parse(); - assert(UnwrappedLines.rbegin()->empty()); + assert(UnwrappedLines.back().empty()); unsigned Penalty = 0; for (unsigned Run = 0, RunE = UnwrappedLines.size(); Run + 1 != RunE; ++Run) { const auto = UnwrappedLines[Run]; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] bb1b53d - [clang-format] Remove unnecessary non-null check and assert instead. NFC.
Author: Marek Kurdej Date: 2022-02-03T09:50:36+01:00 New Revision: bb1b53da6eeb90d3c101719f569abce1d689a959 URL: https://github.com/llvm/llvm-project/commit/bb1b53da6eeb90d3c101719f569abce1d689a959 DIFF: https://github.com/llvm/llvm-project/commit/bb1b53da6eeb90d3c101719f569abce1d689a959.diff LOG: [clang-format] Remove unnecessary non-null check and assert instead. NFC. After a non-eof token, there is at least an eof token. Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 8d06277caba37..cdc2740ba9642 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -514,9 +514,10 @@ bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace, IfStmtKind *IfKind) { FormatToken *Next; do { Next = Tokens->getNextToken(); +assert(Next); } while (Next->is(tok::comment)); FormatTok = Tokens->setPosition(StoredPosition); - if (Next && Next->isNot(tok::colon)) { + if (Next->isNot(tok::colon)) { // default not followed by ':' is not a case label; treat it like // an identifier. parseStructuralElement(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] d079995 - [clang-format] Elide unnecessary braces. NFC.
Author: Marek Kurdej Date: 2022-02-02T15:28:53+01:00 New Revision: d079995dd032e991bac295fb1a879efd32f20460 URL: https://github.com/llvm/llvm-project/commit/d079995dd032e991bac295fb1a879efd32f20460 DIFF: https://github.com/llvm/llvm-project/commit/d079995dd032e991bac295fb1a879efd32f20460.diff LOG: [clang-format] Elide unnecessary braces. NFC. Added: Modified: clang/lib/Format/BreakableToken.cpp clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/DefinitionBlockSeparator.cpp clang/lib/Format/Format.cpp clang/lib/Format/FormatTokenLexer.cpp clang/lib/Format/NamespaceEndCommentsFixer.cpp clang/lib/Format/QualifierAlignmentFixer.cpp clang/lib/Format/SortJavaScriptImports.cpp clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineFormatter.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/lib/Format/WhitespaceManager.cpp Removed: diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 78b23e952fab..7cdbbbd5dd7f 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -95,9 +95,8 @@ getCommentSplit(StringRef Text, unsigned ContentStartColumn, StringRef::size_type SpaceOffset = Text.find_first_of(Blanks, MaxSplitBytes); if (SpaceOffset != StringRef::npos && SpaceOffset + 1 < Text.size() && -Text[SpaceOffset + 1] == '{') { +Text[SpaceOffset + 1] == '{') MaxSplitBytes = SpaceOffset + 1; -} } StringRef::size_type SpaceOffset = Text.find_last_of(Blanks, MaxSplitBytes); @@ -397,9 +396,8 @@ BreakableBlockComment::BreakableBlockComment( // ** blah blah blah // */ if (Lines.size() >= 2 && Content[1].startswith("**") && - static_cast(ContentColumn[1]) == StartColumn) { + static_cast(ContentColumn[1]) == StartColumn) DecorationColumn = StartColumn; - } Decoration = "* "; if (Lines.size() == 1 && !FirstInLine) { @@ -431,9 +429,8 @@ BreakableBlockComment::BreakableBlockComment( // correctly indented. LastLineNeedsDecoration = false; // Align the star in the last '*/' with the stars on the previous lines. -if (e >= 2 && !Decoration.empty()) { +if (e >= 2 && !Decoration.empty()) ContentColumn[i] = DecorationColumn; -} } else if (Decoration.empty()) { // For all other lines, set the start column to 0 if they're empty, so // we do not insert trailing whitespace anywhere. @@ -449,9 +446,8 @@ BreakableBlockComment::BreakableBlockComment( unsigned DecorationSize = Decoration.startswith(Content[i]) ? Content[i].size() : Decoration.size(); -if (DecorationSize) { +if (DecorationSize) ContentColumn[i] = DecorationColumn + DecorationSize; -} Content[i] = Content[i].substr(DecorationSize); if (!Decoration.startswith(Content[i])) IndentAtLineBreak = @@ -480,11 +476,10 @@ BreakableBlockComment::BreakableBlockComment( LLVM_DEBUG({ llvm::dbgs() << "IndentAtLineBreak " << IndentAtLineBreak << "\n"; llvm::dbgs() << "DelimitersOnNewline " << DelimitersOnNewline << "\n"; -for (size_t i = 0; i < Lines.size(); ++i) { +for (size_t i = 0; i < Lines.size(); ++i) llvm::dbgs() << i << " |" << Content[i] << "| " << "CC=" << ContentColumn[i] << "| " << "IN=" << (Content[i].data() - Lines[i].data()) << "\n"; -} }); } @@ -584,9 +579,8 @@ unsigned BreakableBlockComment::getContentIndent(unsigned LineIndex) const { // /** line 0 */ // is "* line 0", so we need to skip over the decoration in that case. StringRef ContentWithNoDecoration = Content[LineIndex]; - if (LineIndex == 0 && ContentWithNoDecoration.startswith("*")) { + if (LineIndex == 0 && ContentWithNoDecoration.startswith("*")) ContentWithNoDecoration = ContentWithNoDecoration.substr(1).ltrim(Blanks); - } StringRef FirstWord = ContentWithNoDecoration.substr( 0, ContentWithNoDecoration.find_first_of(Blanks)); if (ContentIndentingJavadocAnnotations.find(FirstWord) != @@ -739,9 +733,8 @@ bool BreakableBlockComment::mayReflow( // Content[LineIndex] may exclude the indent after the '*' decoration. In that // case, we compute the start of the comment pragma manually. StringRef IndentContent = Content[LineIndex]; - if (Lines[LineIndex].ltrim(Blanks).startswith("*")) { + if (Lines[LineIndex].ltrim(Blanks).startswith("*")) IndentContent = Lines[LineIndex].ltrim(Blanks).substr(1); - } return LineIndex > 0 && !CommentPragmasRegex.match(IndentContent) && mayReflowContent(Content[LineIndex]) && !Tok.Finalized && !switchesFormatting(tokenAt(LineIndex)); @@ -1001,9 +994,8 @@ void BreakableLineCommentSection::adaptStartOfLine( } void
[clang] 630c736 - [clang-format] Elide unnecessary braces. NFC.
Author: Marek Kurdej Date: 2022-02-02T14:36:01+01:00 New Revision: 630c736047a3191a5d3150bcc825064ab84e9fb5 URL: https://github.com/llvm/llvm-project/commit/630c736047a3191a5d3150bcc825064ab84e9fb5 DIFF: https://github.com/llvm/llvm-project/commit/630c736047a3191a5d3150bcc825064ab84e9fb5.diff LOG: [clang-format] Elide unnecessary braces. NFC. Added: Modified: clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/Format.cpp clang/lib/Format/MacroExpander.cpp clang/lib/Format/TokenAnnotator.cpp Removed: diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 45a4d23557f7..95cf0a0c2da4 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -197,12 +197,10 @@ RawStringFormatStyleManager::RawStringFormatStyleManager( LanguageStyle = PredefinedStyle; } LanguageStyle->ColumnLimit = CodeStyle.ColumnLimit; -for (StringRef Delimiter : RawStringFormat.Delimiters) { +for (StringRef Delimiter : RawStringFormat.Delimiters) DelimiterStyle.insert({Delimiter, *LanguageStyle}); -} -for (StringRef EnclosingFunction : RawStringFormat.EnclosingFunctions) { +for (StringRef EnclosingFunction : RawStringFormat.EnclosingFunctions) EnclosingFunctionStyle.insert({EnclosingFunction, *LanguageStyle}); -} } } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 3abe569f8770..128196a24df6 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -2092,9 +2092,8 @@ class Cleaner : public TokenAnalyzer { private: void cleanupLine(AnnotatedLine *Line) { -for (auto *Child : Line->Children) { +for (auto *Child : Line->Children) cleanupLine(Child); -} if (Line->Affected) { cleanupRight(Line->First, tok::comma, tok::comma); @@ -2120,9 +2119,8 @@ class Cleaner : public TokenAnalyzer { std::set DeletedLines; for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { auto = *AnnotatedLines[i]; - if (Line.startsWithNamespace()) { + if (Line.startsWithNamespace()) checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines); - } } for (auto Line : DeletedLines) { @@ -2184,9 +2182,8 @@ class Cleaner : public TokenAnalyzer { AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc( return false; -for (unsigned i = InitLine; i <= CurrentLine; ++i) { +for (unsigned i = InitLine; i <= CurrentLine; ++i) DeletedLines.insert(i); -} return true; } diff --git a/clang/lib/Format/MacroExpander.cpp b/clang/lib/Format/MacroExpander.cpp index de96cb24ba1f..9c6bcb8764f4 100644 --- a/clang/lib/Format/MacroExpander.cpp +++ b/clang/lib/Format/MacroExpander.cpp @@ -125,9 +125,8 @@ MacroExpander::MacroExpander( IdentifierTable ) : SourceMgr(SourceMgr), Style(Style), Allocator(Allocator), IdentTable(IdentTable) { - for (const std::string : Macros) { + for (const std::string : Macros) parseDefinition(Macro); - } } MacroExpander::~MacroExpander() = default; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 9d130dbb02eb..0bd6dfa5926d 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1388,9 +1388,8 @@ class AnnotatingParser { } for (const auto : Contexts) { - if (ctx.InStructArrayInitializer) { + if (ctx.InStructArrayInitializer) return LT_ArrayOfStructInitializer; - } } return LT_Other; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b3af2ef - [clang-format] Factor out loop variable. NFC.
Author: Marek Kurdej Date: 2022-02-02T14:36:00+01:00 New Revision: b3af2ef963b1c94ab40d940c5e2774a2ac9ec230 URL: https://github.com/llvm/llvm-project/commit/b3af2ef963b1c94ab40d940c5e2774a2ac9ec230 DIFF: https://github.com/llvm/llvm-project/commit/b3af2ef963b1c94ab40d940c5e2774a2ac9ec230.diff LOG: [clang-format] Factor out loop variable. NFC. * Break on the size of the used variable Content instead of Lines (even though both should have the same size). Added: Modified: clang/lib/Format/BreakableToken.cpp Removed: diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 417fada35119..78b23e952fab 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -410,13 +410,14 @@ BreakableBlockComment::BreakableBlockComment( // now we just wrap them without stars. Decoration = ""; } - for (size_t i = 1, e = Lines.size(); i < e && !Decoration.empty(); ++i) { + for (size_t i = 1, e = Content.size(); i < e && !Decoration.empty(); ++i) { +const StringRef = Content[i]; // If the last line is empty, the closing "*/" will have a star. -if (i + 1 == e && Content[i].empty()) +if (i + 1 == e && Text.empty()) break; -if (!Content[i].empty() && i + 1 != e && Decoration.startswith(Content[i])) +if (!Text.empty() && i + 1 != e && Decoration.startswith(Text)) continue; -while (!Content[i].startswith(Decoration)) +while (!Text.startswith(Decoration)) Decoration = Decoration.drop_back(1); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 10243d0 - [clang-format] Simplify use of StringRef::substr(). NFC.
Author: Marek Kurdej Date: 2022-02-02T14:36:00+01:00 New Revision: 10243d0dfd36b0fb912276b2686a038b952e03c8 URL: https://github.com/llvm/llvm-project/commit/10243d0dfd36b0fb912276b2686a038b952e03c8 DIFF: https://github.com/llvm/llvm-project/commit/10243d0dfd36b0fb912276b2686a038b952e03c8.diff LOG: [clang-format] Simplify use of StringRef::substr(). NFC. Added: Modified: clang/lib/Format/BreakableToken.cpp clang/lib/Format/FormatTokenLexer.cpp Removed: diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index f68d802c1f95f..417fada35119f 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -417,7 +417,7 @@ BreakableBlockComment::BreakableBlockComment( if (!Content[i].empty() && i + 1 != e && Decoration.startswith(Content[i])) continue; while (!Content[i].startswith(Decoration)) - Decoration = Decoration.substr(0, Decoration.size() - 1); + Decoration = Decoration.drop_back(1); } LastLineNeedsDecoration = true; diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index c9166f4b17aab..638b490773e71 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -621,9 +621,9 @@ void FormatTokenLexer::handleCSharpVerbatimAndInterpolatedStrings() { if (LastBreak != StringRef::npos) { CSharpStringLiteral->IsMultiline = true; unsigned StartColumn = 0; -CSharpStringLiteral->LastLineColumnWidth = encoding::columnWidthWithTabs( -LiteralText.substr(LastBreak + 1, LiteralText.size()), StartColumn, -Style.TabWidth, Encoding); +CSharpStringLiteral->LastLineColumnWidth = +encoding::columnWidthWithTabs(LiteralText.substr(LastBreak + 1), + StartColumn, Style.TabWidth, Encoding); } SourceLocation loc = Offset < Lex->getBuffer().end() @@ -688,9 +688,9 @@ void FormatTokenLexer::handleTemplateStrings() { if (LastBreak != StringRef::npos) { BacktickToken->IsMultiline = true; unsigned StartColumn = 0; // The template tail spans the entire line. -BacktickToken->LastLineColumnWidth = encoding::columnWidthWithTabs( -LiteralText.substr(LastBreak + 1, LiteralText.size()), StartColumn, -Style.TabWidth, Encoding); +BacktickToken->LastLineColumnWidth = +encoding::columnWidthWithTabs(LiteralText.substr(LastBreak + 1), + StartColumn, Style.TabWidth, Encoding); } SourceLocation loc = Offset < Lex->getBuffer().end() ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 574ad2a - [clang-format] Use prefix operator--. NFC.
Author: Marek Kurdej Date: 2022-02-02T14:01:48+01:00 New Revision: 574ad2a84626ffb0e7a64559e9862f20aadc013a URL: https://github.com/llvm/llvm-project/commit/574ad2a84626ffb0e7a64559e9862f20aadc013a DIFF: https://github.com/llvm/llvm-project/commit/574ad2a84626ffb0e7a64559e9862f20aadc013a.diff LOG: [clang-format] Use prefix operator--. NFC. Added: Modified: clang/lib/Format/UnwrappedLineFormatter.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 01c151fec132..270b498fe471 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -330,7 +330,7 @@ class LineJoiner { nsToken->TokenText == getNamespaceTokenText(I[i + 1]) && closingLine == I[i + 1]->MatchingClosingBlockLineIndex && I[i + 1]->Last->TotalLength < Limit; - i++, closingLine--) { + i++, --closingLine) { // No extra indent for compacted namespaces IndentTracker.skipLine(*I[i + 1]); @@ -346,7 +346,7 @@ class LineJoiner { nsToken->TokenText == getMatchingNamespaceTokenText(I[i + 1], AnnotatedLines) && openingLine == I[i + 1]->MatchingOpeningBlockLineIndex; - i++, openingLine--) { + i++, --openingLine) { // No space between consecutive braces I[i + 1]->First->SpacesRequiredBefore = !I[i]->Last->is(tok::r_brace); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 61f09bc - [clang-format] Use llvm::seq instead of std::iota. NFC.
Author: Marek Kurdej Date: 2022-02-02T14:00:50+01:00 New Revision: 61f09bcf11dee028ba47f4756910b25b043505e1 URL: https://github.com/llvm/llvm-project/commit/61f09bcf11dee028ba47f4756910b25b043505e1 DIFF: https://github.com/llvm/llvm-project/commit/61f09bcf11dee028ba47f4756910b25b043505e1.diff LOG: [clang-format] Use llvm::seq instead of std::iota. NFC. Added: Modified: clang/lib/Format/Format.cpp Removed: diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index d9952f5d5d6d9..3abe569f8770a 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -34,6 +34,7 @@ #include "clang/Lex/Lexer.h" #include "clang/Tooling/Inclusions/HeaderIncludes.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Sequence.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Debug.h" @@ -44,7 +45,6 @@ #include #include #include -#include #include #include @@ -2521,9 +2521,8 @@ static void sortCppIncludes(const FormatStyle , unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset; if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset)) return; - SmallVector Indices; - Indices.resize(Includes.size()); - std::iota(Indices.begin(), Indices.end(), 0); + SmallVector Indices = + llvm::to_vector<16>(llvm::seq(0, Includes.size())); if (Style.SortIncludes == FormatStyle::SI_CaseInsensitive) { llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) { @@ -2750,10 +2749,8 @@ static void sortJavaImports(const FormatStyle , if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset)) return; - SmallVector Indices; - Indices.resize(Imports.size()); - std::iota(Indices.begin(), Indices.end(), 0); - + SmallVector Indices = + llvm::to_vector<16>(llvm::seq(0, Imports.size())); SmallVector JavaImportGroups; JavaImportGroups.reserve(Imports.size()); for (const JavaImportDirective : Imports) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] bc40b76 - [clang-format] Correctly parse C99 digraphs: "<:", ":>", "<%", "%>", "%:", "%:%:".
Author: Marek Kurdej Date: 2022-02-02T10:25:24+01:00 New Revision: bc40b76b5b95837e27217de6a446eeeace695f34 URL: https://github.com/llvm/llvm-project/commit/bc40b76b5b95837e27217de6a446eeeace695f34 DIFF: https://github.com/llvm/llvm-project/commit/bc40b76b5b95837e27217de6a446eeeace695f34.diff LOG: [clang-format] Correctly parse C99 digraphs: "<:", ":>", "<%", "%>", "%:", "%:%:". Fixes https://github.com/llvm/llvm-project/issues/31592. This commits enables lexing of digraphs in C++11 and onwards. Enabling them in C++03 is error-prone, as it would unconditionally treat sequences like "<:" as digraphs, even if they are followed by a single colon, e.g. "<::" would be treated as "[:" instead of "<" followed by "::". Lexing in C++11 doesn't have this problem as it looks ahead the following token. The relevant excerpt from Lexer::LexTokenInternal: ``` // C++0x [lex.pptoken]p3: // Otherwise, if the next three characters are <:: and the subsequent // character is neither : nor >, the < is treated as a preprocessor // token by itself and not as the first character of the alternative // token <:. ``` Also, note that both clang and gcc turn on digraphs by default (-fdigraphs), so clang-format should match this behaviour. Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D118706 Added: Modified: clang/lib/Format/Format.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index dd4755c2227e1..d9952f5d5d6d9 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3242,6 +3242,10 @@ LangOptions getFormattingLangOpts(const FormatStyle ) { LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp17; LangOpts.CPlusPlus20 = LexingStd >= FormatStyle::LS_Cpp20; LangOpts.Char8 = LexingStd >= FormatStyle::LS_Cpp20; + // Turning on digraphs in standards before C++0x is error-prone, because e.g. + // the sequence "<::" will be unconditionally treated as "[:". + // Cf. Lexer::LexTokenInternal. + LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11; LangOpts.LineComment = 1; bool AlternativeOperators = Style.isCpp(); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 005e2d6a7b559..866847a531355 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -24219,6 +24219,16 @@ TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentForStatement) { Style); } +TEST_F(FormatTest, UnderstandsDigraphs) { + verifyFormat("int arr<:5:> = {};"); + verifyFormat("int arr[5] = <%%>;"); + verifyFormat("int arr<:::qualified_variable:> = {};"); + verifyFormat("int arr[::qualified_variable] = <%%>;"); + verifyFormat("%:include "); + verifyFormat("%:define A x##y"); + verifyFormat("#define A x%:%:y"); +} + } // namespace } // namespace format } // namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] af8f1db - [clang-format] Use std::iota and reserve when sorting Java imports. NFC.
Author: Marek Kurdej Date: 2022-02-01T14:29:31+01:00 New Revision: af8f1dbb43bc1a6267ea0b760c7b0fae635938ff URL: https://github.com/llvm/llvm-project/commit/af8f1dbb43bc1a6267ea0b760c7b0fae635938ff DIFF: https://github.com/llvm/llvm-project/commit/af8f1dbb43bc1a6267ea0b760c7b0fae635938ff.diff LOG: [clang-format] Use std::iota and reserve when sorting Java imports. NFC. This way we have at most 1 allocation even if the number of includes is greater than the on-stack size of the small vector. Added: Modified: clang/lib/Format/Format.cpp Removed: diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 9611e4ae33f8..dd4755c2227e 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -2749,13 +2749,16 @@ static void sortJavaImports(const FormatStyle , unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset; if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset)) return; + SmallVector Indices; + Indices.resize(Imports.size()); + std::iota(Indices.begin(), Indices.end(), 0); + SmallVector JavaImportGroups; - for (unsigned i = 0, e = Imports.size(); i != e; ++i) { -Indices.push_back(i); -JavaImportGroups.push_back( -findJavaImportGroup(Style, Imports[i].Identifier)); - } + JavaImportGroups.reserve(Imports.size()); + for (const JavaImportDirective : Imports) +JavaImportGroups.push_back(findJavaImportGroup(Style, Import.Identifier)); + bool StaticImportAfterNormalImport = Style.SortJavaStaticImport == FormatStyle::SJSIO_After; llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e75a342 - [clang-format] Use std::iota and reserve. NFC.
Author: Marek Kurdej Date: 2022-02-01T14:24:01+01:00 New Revision: e75a3428a92016b2689d5efb7ac95ae91761949d URL: https://github.com/llvm/llvm-project/commit/e75a3428a92016b2689d5efb7ac95ae91761949d DIFF: https://github.com/llvm/llvm-project/commit/e75a3428a92016b2689d5efb7ac95ae91761949d.diff LOG: [clang-format] Use std::iota and reserve. NFC. This way we have at most 1 allocation even if the number of includes is greater than the on-stack size of the small vector. Added: Modified: clang/lib/Format/Format.cpp Removed: diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 70c7d4d3acee..9611e4ae33f8 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -2521,8 +2522,8 @@ static void sortCppIncludes(const FormatStyle , if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset)) return; SmallVector Indices; - for (unsigned i = 0, e = Includes.size(); i != e; ++i) -Indices.push_back(i); + Indices.resize(Includes.size()); + std::iota(Indices.begin(), Indices.end(), 0); if (Style.SortIncludes == FormatStyle::SI_CaseInsensitive) { llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 34b4f00 - [clang-format] De-pessimize appending newlines. NFC.
Author: Marek Kurdej Date: 2022-02-01T14:10:48+01:00 New Revision: 34b4f00686ffa030fb0fed3bdd24b5e8588dae89 URL: https://github.com/llvm/llvm-project/commit/34b4f00686ffa030fb0fed3bdd24b5e8588dae89 DIFF: https://github.com/llvm/llvm-project/commit/34b4f00686ffa030fb0fed3bdd24b5e8588dae89.diff LOG: [clang-format] De-pessimize appending newlines. NFC. * Avoid repeatedly calling std::string::append(char) in a loop. * Reserve before calling std::string::append(const char *) in a loop. Added: Modified: clang/lib/Format/WhitespaceManager.cpp Removed: diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 7709fe814864..4c130abd83c3 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -1347,8 +1347,13 @@ void WhitespaceManager::storeReplacement(SourceRange Range, StringRef Text) { void WhitespaceManager::appendNewlineText(std::string , unsigned Newlines) { - for (unsigned i = 0; i < Newlines; ++i) -Text.append(UseCRLF ? "\r\n" : "\n"); + if (UseCRLF) { +Text.reserve(Text.size() + 2 * Newlines); +for (unsigned i = 0; i < Newlines; ++i) + Text.append("\r\n"); + } else { +Text.append(Newlines, '\n'); + } } void WhitespaceManager::appendEscapedNewlineText( ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 545317c - [clang-format] Use ranged for loops. NFC.
Author: Marek Kurdej Date: 2022-02-01T14:10:48+01:00 New Revision: 545317cb8eb96947ae20b432525f5667f816df49 URL: https://github.com/llvm/llvm-project/commit/545317cb8eb96947ae20b432525f5667f816df49 DIFF: https://github.com/llvm/llvm-project/commit/545317cb8eb96947ae20b432525f5667f816df49.diff LOG: [clang-format] Use ranged for loops. NFC. Added: Modified: clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/Format.cpp clang/lib/Format/NamespaceEndCommentsFixer.cpp clang/lib/Format/TokenAnalyzer.cpp clang/lib/Format/TokenAnnotator.h clang/lib/Format/UnwrappedLineParser.cpp clang/lib/Format/UsingDeclarationsSorter.cpp clang/lib/Format/WhitespaceManager.cpp Removed: diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index b66584652bc82..45a4d23557f76 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -1817,8 +1817,8 @@ unsigned ContinuationIndenter::reformatRawStringLiteral( ContentStartsOnNewline || (NewCode->find('\n') != std::string::npos); if (IsMultiline) { // Break before further function parameters on all levels. -for (unsigned i = 0, e = State.Stack.size(); i != e; ++i) - State.Stack[i].BreakBeforeParameter = true; +for (ParenState : State.Stack) + Paren.BreakBeforeParameter = true; } return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter; } @@ -1826,8 +1826,8 @@ unsigned ContinuationIndenter::reformatRawStringLiteral( unsigned ContinuationIndenter::addMultilineToken(const FormatToken , LineState ) { // Break before further function parameters on all levels. - for (unsigned i = 0, e = State.Stack.size(); i != e; ++i) -State.Stack[i].BreakBeforeParameter = true; + for (ParenState : State.Stack) +Paren.BreakBeforeParameter = true; unsigned ColumnsUsed = State.Column; // We can only affect layout of the first and the last line, so the penalty @@ -2380,8 +2380,8 @@ ContinuationIndenter::breakProtrudingToken(const FormatToken , // the next parameter on all levels, so that the next parameter is clearly // visible. Line comments already introduce a break. if (Current.isNot(TT_LineComment)) { - for (unsigned i = 0, e = State.Stack.size(); i != e; ++i) -State.Stack[i].BreakBeforeParameter = true; + for (ParenState : State.Stack) +Paren.BreakBeforeParameter = true; } if (Current.is(TT_BlockComment)) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index baf9c6885a86b..70c7d4d3aceef 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -532,11 +532,9 @@ template <> struct MappingTraits { IO.mapOptional("Language", Style.Language); if (IO.outputting()) { - StringRef StylesArray[] = {"LLVM", "Google", "Chromium", "Mozilla", - "WebKit", "GNU","Microsoft"}; - ArrayRef Styles(StylesArray); - for (size_t i = 0, e = Styles.size(); i < e; ++i) { -StringRef StyleName(Styles[i]); + StringRef Styles[] = {"LLVM", "Google", "Chromium", "Mozilla", +"WebKit", "GNU","Microsoft"}; + for (StringRef StyleName : Styles) { FormatStyle PredefinedStyle; if (getPredefinedStyle(StyleName, Style.Language, ) && Style == PredefinedStyle) { @@ -1681,10 +1679,10 @@ std::error_code parseConfiguration(llvm::MemoryBufferRef Config, // configuration (which can only be at slot 0) after it. FormatStyle::FormatStyleSet StyleSet; bool LanguageFound = false; - for (int i = Styles.size() - 1; i >= 0; --i) { -if (Styles[i].Language != FormatStyle::LK_None) - StyleSet.Add(Styles[i]); -if (Styles[i].Language == Language) + for (const FormatStyle : llvm::reverse(Styles)) { +if (Style.Language != FormatStyle::LK_None) + StyleSet.Add(Style); +if (Style.Language == Language) LanguageFound = true; } if (!LanguageFound) { @@ -1890,9 +1888,8 @@ class Formatter : public TokenAnalyzer { tooling::Replacements Result; deriveLocalStyle(AnnotatedLines); AffectedRangeMgr.computeAffectedLines(AnnotatedLines); -for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { - Annotator.calculateFormattingInformation(*AnnotatedLines[i]); -} +for (AnnotatedLine *Line : AnnotatedLines) + Annotator.calculateFormattingInformation(*Line); Annotator.setCommentLineLevels(AnnotatedLines); WhitespaceManager Whitespaces( @@ -1962,10 +1959,10 @@ class Formatter : public TokenAnalyzer { deriveLocalStyle(const SmallVectorImpl ) { bool HasBinPackedFunction = false; bool HasOnePerLineFunction = false; -for (unsigned i = 0, e = AnnotatedLines.size();
[clang] fd33cca - [clang-format] Fix AlignConsecutiveAssignments breaking lambda formatting.
Author: Marek Kurdej Date: 2022-02-01T09:17:59+01:00 New Revision: fd33cca762fac265d28abbb080eec57f011f7cb4 URL: https://github.com/llvm/llvm-project/commit/fd33cca762fac265d28abbb080eec57f011f7cb4 DIFF: https://github.com/llvm/llvm-project/commit/fd33cca762fac265d28abbb080eec57f011f7cb4.diff LOG: [clang-format] Fix AlignConsecutiveAssignments breaking lambda formatting. Fixes https://github.com/llvm/llvm-project/issues/52772. This patch fixes the formatting of the code: ``` auto a = {}; auto b = g([] { return; }); ``` which should be left as is, but before this patch was formatted to: ``` auto a = {}; auto b = g([] { return; }); ``` Reviewed By: MyDeveloperDay, HazardyKnusperkeks Differential Revision: https://reviews.llvm.org/D115972 Added: Modified: clang/lib/Format/WhitespaceManager.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 0d2e507ac587..f868c9d5752f 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -344,6 +344,10 @@ AlignTokenSequence(const FormatStyle , unsigned Start, unsigned End, if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName)) return true; +// Lambda. +if (Changes[ScopeStart - 1].Tok->is(TT_LambdaLBrace)) + return false; + // Continued function declaration if (ScopeStart > Start + 1 && Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) @@ -352,8 +356,13 @@ AlignTokenSequence(const FormatStyle , unsigned Start, unsigned End, // Continued function call if (ScopeStart > Start + 1 && Changes[ScopeStart - 2].Tok->is(tok::identifier) && -Changes[ScopeStart - 1].Tok->is(tok::l_paren)) +Changes[ScopeStart - 1].Tok->is(tok::l_paren) && +Changes[ScopeStart].Tok->isNot(TT_LambdaLSquare)) { + if (Changes[i].Tok->MatchingParen && + Changes[i].Tok->MatchingParen->is(TT_LambdaLBrace)) +return false; return Style.BinPackArguments; +} // Ternary operator if (Changes[i].Tok->is(TT_ConditionalExpr)) @@ -372,8 +381,15 @@ AlignTokenSequence(const FormatStyle , unsigned Start, unsigned End, if (ScopeStart > Start + 1 && Changes[ScopeStart - 2].Tok->isNot(tok::identifier) && Changes[ScopeStart - 1].Tok->is(tok::l_brace) && -Changes[i].Tok->isNot(tok::r_brace)) +Changes[i].Tok->isNot(tok::r_brace)) { + for (unsigned OuterScopeStart : llvm::reverse(ScopeStack)) { +// Lambda. +if (OuterScopeStart > Start && +Changes[OuterScopeStart - 1].Tok->is(TT_LambdaLBrace)) + return false; + } return true; +} return false; }; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index bbe3f53807e6..005e2d6a7b55 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -16571,6 +16571,43 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) { "int yy = 1; ///specificlennospace\n" "int zzz = 2;\n", Alignment)); + + verifyFormat("auto a = {};\n" + "auto b = [] {\n" + " f();\n" + " return;\n" + "};", + Alignment); + verifyFormat("auto a = {};\n" + "auto b = g([] {\n" + " f();\n" + " return;\n" + "});", + Alignment); + verifyFormat("auto a = {};\n" + "auto b = g(param, [] {\n" + " f();\n" + " return;\n" + "});", + Alignment); + verifyFormat("auto a = {};\n" + "auto b = [] {\n" + " if (condition) {\n" + "return;\n" + " }\n" + "};", + Alignment); + + verifyFormat("auto b = f(a,\n" + " ccc ? a : b,\n" + " dd);", + Alignment); + // FIXME: https://llvm.org/PR53497 + // verifyFormat("auto = f();\n" + // "auto b= f(a,\n" + // "ccc ? a : b,\n" + // "dd);", + // Alignment); } TEST_F(FormatTest,
[clang] 95bf0a9 - [clang-format] Don't break block comments when sorting includes.
Author: Marek Kurdej Date: 2022-02-01T08:51:10+01:00 New Revision: 95bf0a9ebdb4ee6f78699e20751602c8c3c5733f URL: https://github.com/llvm/llvm-project/commit/95bf0a9ebdb4ee6f78699e20751602c8c3c5733f DIFF: https://github.com/llvm/llvm-project/commit/95bf0a9ebdb4ee6f78699e20751602c8c3c5733f.diff LOG: [clang-format] Don't break block comments when sorting includes. Fixes https://github.com/llvm/llvm-project/issues/34626. Before, the include sorter would break the code: ``` #include #include /* long comment */ ``` and change it into: ``` #include /* long #include comment */ ``` This commit handles only the most basic case of a single block comment on an include line, but does not try to handle all the possible edge cases with multiple comments. Reviewed By: HazardyKnusperkeks Differential Revision: https://reviews.llvm.org/D118627 Added: Modified: clang/lib/Format/Format.cpp clang/unittests/Format/SortIncludesTest.cpp Removed: diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 04e2915e3af69..baf9c6885a86b 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -2678,6 +2678,15 @@ tooling::Replacements sortCppIncludes(const FormatStyle , StringRef Code, if (!FormattingOff && !MergeWithNextLine) { if (IncludeRegex.match(Line, )) { StringRef IncludeName = Matches[2]; +if (Line.contains("/*") && !Line.contains("*/")) { + // #include with a start of a block comment, but without the end. + // Need to keep all the lines until the end of the comment together. + // FIXME: This is somehow simplified check that probably does not work + // correctly if there are multiple comments on a line. + Pos = Code.find("*/", SearchFrom); + Line = Code.substr( + Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev); +} int Category = Categories.getIncludePriority( IncludeName, /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock); diff --git a/clang/unittests/Format/SortIncludesTest.cpp b/clang/unittests/Format/SortIncludesTest.cpp index 1d215af715382..b0ee6bfc35979 100644 --- a/clang/unittests/Format/SortIncludesTest.cpp +++ b/clang/unittests/Format/SortIncludesTest.cpp @@ -70,6 +70,21 @@ TEST_F(SortIncludesTest, BasicSorting) { {tooling::Range(25, 1)})); } +TEST_F(SortIncludesTest, TrailingComments) { + EXPECT_EQ("#include \"a.h\"\n" +"#include \"b.h\" /* long\n" +" * long\n" +" * comment*/\n" +"#include \"c.h\"\n" +"#include \"d.h\"\n", +sort("#include \"a.h\"\n" + "#include \"c.h\"\n" + "#include \"b.h\" /* long\n" + " * long\n" + " * comment*/\n" + "#include \"d.h\"\n")); +} + TEST_F(SortIncludesTest, SortedIncludesUsingSortPriorityAttribute) { FmtStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; FmtStyle.IncludeStyle.IncludeCategories = { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 438f0e1 - [clang-format] Use EXPECT_EQ instead of setting style to a default value. NFC.
Author: Marek Kurdej Date: 2022-01-31T09:06:00+01:00 New Revision: 438f0e1f00ada4827d8138dd236e850b26c4141f URL: https://github.com/llvm/llvm-project/commit/438f0e1f00ada4827d8138dd236e850b26c4141f DIFF: https://github.com/llvm/llvm-project/commit/438f0e1f00ada4827d8138dd236e850b26c4141f.diff LOG: [clang-format] Use EXPECT_EQ instead of setting style to a default value. NFC. Added: Modified: clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index cf20a70e6cdf3..bbe3f53807e62 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -16562,7 +16562,7 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) { "y = 1;\n", Alignment); - Alignment.ReflowComments = true; + EXPECT_EQ(Alignment.ReflowComments, true); Alignment.ColumnLimit = 50; EXPECT_EQ("int x = 0;\n" "int yy = 1; /// specificlennospace\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] d1aed48 - [clang-format] Handle C variables with name that matches c++ access specifier
Author: Philip Sigillito Date: 2022-01-30T20:56:50+01:00 New Revision: d1aed486efc6d35a81ca4acbabb4203c4b91cda9 URL: https://github.com/llvm/llvm-project/commit/d1aed486efc6d35a81ca4acbabb4203c4b91cda9 DIFF: https://github.com/llvm/llvm-project/commit/d1aed486efc6d35a81ca4acbabb4203c4b91cda9.diff LOG: [clang-format] Handle C variables with name that matches c++ access specifier Reviewed By: MyDeveloperDay, curdeius, HazardyKnusperkeks Differential Revision: https://reviews.llvm.org/D117416 Added: Modified: clang/lib/Format/FormatToken.h clang/lib/Format/UnwrappedLineFormatter.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index a64329802ee32..f116a89ac6440 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -123,6 +123,34 @@ namespace format { TYPE(CSharpGenericTypeConstraintComma) \ TYPE(Unknown) +/// Sorted operators that can follow a C variable. +static const std::vector COperatorsFollowingVar = [] { + std::vector ReturnVal = { + tok::l_square, tok::r_square, + tok::l_paren, tok::r_paren, + tok::r_brace, tok::period, + tok::ellipsis, tok::ampamp, + tok::ampequal, tok::star, + tok::starequal,tok::plus, + tok::plusplus, tok::plusequal, + tok::minus,tok::arrow, + tok::minusminus, tok::minusequal, + tok::exclaim, tok::exclaimequal, + tok::slash,tok::slashequal, + tok::percent, tok::percentequal, + tok::less, tok::lessless, + tok::lessequal,tok::lesslessequal, + tok::greater, tok::greatergreater, + tok::greaterequal, tok::greatergreaterequal, + tok::caret,tok::caretequal, + tok::pipe, tok::pipepipe, + tok::pipeequal,tok::question, + tok::semi, tok::equal, + tok::equalequal, tok::comma}; + assert(std::is_sorted(ReturnVal.begin(), ReturnVal.end())); + return ReturnVal; +}(); + /// Determines the semantic type of a syntactic token, e.g. whether "<" is a /// template opener or binary operator. enum TokenType : uint8_t { diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 0172a224335c8..01c151fec132c 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -100,10 +100,27 @@ class LevelIndentTracker { if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript() || Style.isCSharp()) return 0; -if (RootToken.isAccessSpecifier(false) || -RootToken.isObjCAccessSpecifier() || -(RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) && - RootToken.Next && RootToken.Next->is(tok::colon))) { + +auto IsAccessModifier = [this, ]() { + if (RootToken.isAccessSpecifier(Style.isCpp())) +return true; + else if (RootToken.isObjCAccessSpecifier()) +return true; + // Handle Qt signals. + else if ((RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) && +RootToken.Next && RootToken.Next->is(tok::colon))) +return true; + else if (RootToken.Next && + RootToken.Next->isOneOf(Keywords.kw_slots, Keywords.kw_qslots) && + RootToken.Next->Next && RootToken.Next->Next->is(tok::colon)) +return true; + // Handle malformed access specifier e.g. 'private' without trailing ':'. + else if (!RootToken.Next && RootToken.isAccessSpecifier(false)) +return true; + return false; +}; + +if (IsAccessModifier()) { // The AccessModifierOffset may be overridden by IndentAccessModifiers, // in which case we take a negative value of the IndentWidth to simulate // the upper indent level. diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 35be2fa3eb62f..2297d98850103 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2708,14 +2708,25 @@ void UnwrappedLineParser::parseSwitch() { } void UnwrappedLineParser::parseAccessSpecifier() { + FormatToken *AccessSpecifierCandidate = FormatTok; nextToken(); // Understand Qt's slots. if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots)) nextToken(); // Otherwise, we don't know what it is, and we'd better keep the next token. - if (FormatTok->Tok.is(tok::colon)) + if (FormatTok->Tok.is(tok::colon)) { nextToken(); - addUnwrappedLine(); +addUnwrappedLine(); + } else if (!FormatTok->Tok.is(tok::coloncolon) && + !std::binary_search(COperatorsFollowingVar.begin(), +
[clang] 64df516 - [clang-format] Fix misaligned trailing comments in the presence of an empty block comment.
Author: Marek Kurdej Date: 2022-01-28T22:28:48+01:00 New Revision: 64df51624f08f3b8d7370f820ab3545b1de98a0e URL: https://github.com/llvm/llvm-project/commit/64df51624f08f3b8d7370f820ab3545b1de98a0e DIFF: https://github.com/llvm/llvm-project/commit/64df51624f08f3b8d7370f820ab3545b1de98a0e.diff LOG: [clang-format] Fix misaligned trailing comments in the presence of an empty block comment. Fixes https://github.com/llvm/llvm-project/issues/53441. Expected code: ``` /**/ // int a; // ``` was before misformatted to: ``` /**/ // int a; // ``` Because the "remaining length" (after the starting `/*`) of an empty block comment `/**/` was computed to be 0 instead of 2. Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D118475 Added: Modified: clang/lib/Format/BreakableToken.cpp clang/unittests/Format/FormatTestComments.cpp Removed: diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 085713b5c81ca..f68d802c1f95f 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -555,7 +555,9 @@ unsigned BreakableBlockComment::getRemainingLength(unsigned LineIndex, // We never need a decoration when breaking just the trailing "*/" postfix. bool HasRemainingText = Offset < Content[LineIndex].size(); if (!HasRemainingText) { - LineLength -= Decoration.size(); + bool HasDecoration = Lines[LineIndex].ltrim().startswith(Decoration); + if (HasDecoration) +LineLength -= Decoration.size(); } } return LineLength; diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index b5db353d4ae0a..b487440a06a3b 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -2842,6 +2842,12 @@ TEST_F(FormatTestComments, AlignTrailingComments) { "#define FOO_NODELOCAL 4 // Loopback\n\n" "} // namespace m\n", getLLVMStyleWithColumns(80))); + + // https://llvm.org/PR53441 + verifyFormat("/* */ //\n" + "int a; //\n"); + verifyFormat("/**/ //\n" + "int a; //\n"); } TEST_F(FormatTestComments, AlignsBlockCommentDecorations) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f4d5195 - [clang-format] Move irrelevant code from getRangeLength to getRemainingLength. NFC.
Author: Marek Kurdej Date: 2022-01-28T12:01:02+01:00 New Revision: f4d5195d2fff06e2e3daad136f909143324d0485 URL: https://github.com/llvm/llvm-project/commit/f4d5195d2fff06e2e3daad136f909143324d0485 DIFF: https://github.com/llvm/llvm-project/commit/f4d5195d2fff06e2e3daad136f909143324d0485.diff LOG: [clang-format] Move irrelevant code from getRangeLength to getRemainingLength. NFC. Added: Modified: clang/lib/Format/BreakableToken.cpp clang/unittests/Format/FormatTestJS.cpp Removed: diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index a91860faf74ec..085713b5c81ca 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -539,31 +539,28 @@ unsigned BreakableBlockComment::getRangeLength(unsigned LineIndex, unsigned Offset, StringRef::size_type Length, unsigned StartColumn) const { + return encoding::columnWidthWithTabs( + Content[LineIndex].substr(Offset, Length), StartColumn, Style.TabWidth, + Encoding); +} + +unsigned BreakableBlockComment::getRemainingLength(unsigned LineIndex, + unsigned Offset, + unsigned StartColumn) const { unsigned LineLength = - encoding::columnWidthWithTabs(Content[LineIndex].substr(Offset, Length), -StartColumn, Style.TabWidth, Encoding); - // FIXME: This should go into getRemainingLength instead, but we currently - // break tests when putting it there. Investigate how to fix those tests. - // The last line gets a "*/" postfix. + UnbreakableTailLength + + getRangeLength(LineIndex, Offset, StringRef::npos, StartColumn); if (LineIndex + 1 == Lines.size()) { LineLength += 2; // We never need a decoration when breaking just the trailing "*/" postfix. -// Note that checking that Length == 0 is not enough, since Length could -// also be StringRef::npos. -if (Content[LineIndex].substr(Offset).empty()) { +bool HasRemainingText = Offset < Content[LineIndex].size(); +if (!HasRemainingText) { LineLength -= Decoration.size(); } } return LineLength; } -unsigned BreakableBlockComment::getRemainingLength(unsigned LineIndex, - unsigned Offset, - unsigned StartColumn) const { - return UnbreakableTailLength + - getRangeLength(LineIndex, Offset, StringRef::npos, StartColumn); -} - unsigned BreakableBlockComment::getContentStartColumn(unsigned LineIndex, bool Break) const { if (Break) diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index 7b7bccda0805d..d84533e8a2b03 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -195,7 +195,7 @@ TEST_F(FormatTestJS, JSDocComments) { getGoogleJSStyleWithColumns(20))); // FIXME: this overcounts the */ as a continuation of the 12 when breaking. - // Related to the FIXME in BreakableBlockComment::getRangeLength. + // Cf. BreakableBlockComment::getRemainingLength. EXPECT_EQ("/**\n" " * @returns {string}\n" " * jsdoc line line\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 249a21a - [clang-format] Remove useless npos parameter from substr. NFC.
Author: Marek Kurdej Date: 2022-01-28T11:23:29+01:00 New Revision: 249a21ab188419b019adea21716f5c779c063de3 URL: https://github.com/llvm/llvm-project/commit/249a21ab188419b019adea21716f5c779c063de3 DIFF: https://github.com/llvm/llvm-project/commit/249a21ab188419b019adea21716f5c779c063de3.diff LOG: [clang-format] Remove useless npos parameter from substr. NFC. Added: Modified: clang/lib/Format/BreakableToken.cpp Removed: diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 5d03c9811e1b7..a91860faf74ec 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -254,8 +254,8 @@ unsigned BreakableStringLiteral::getRemainingLength(unsigned LineIndex, unsigned Offset, unsigned StartColumn) const { return UnbreakableTailLength + Postfix.size() + - encoding::columnWidthWithTabs(Line.substr(Offset, StringRef::npos), - StartColumn, Style.TabWidth, Encoding); + encoding::columnWidthWithTabs(Line.substr(Offset), StartColumn, + Style.TabWidth, Encoding); } unsigned BreakableStringLiteral::getContentStartColumn(unsigned LineIndex, @@ -550,7 +550,7 @@ unsigned BreakableBlockComment::getRangeLength(unsigned LineIndex, // We never need a decoration when breaking just the trailing "*/" postfix. // Note that checking that Length == 0 is not enough, since Length could // also be StringRef::npos. -if (Content[LineIndex].substr(Offset, StringRef::npos).empty()) { +if (Content[LineIndex].substr(Offset).empty()) { LineLength -= Decoration.size(); } } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 36622c4 - [clang-format] Fix AllowShortFunctionsOnASingleLine: InlineOnly with wrapping after record.
Author: Marek Kurdej Date: 2022-01-27T18:06:31+01:00 New Revision: 36622c4e1a48cd02209524592abb9d929fff1e22 URL: https://github.com/llvm/llvm-project/commit/36622c4e1a48cd02209524592abb9d929fff1e22 DIFF: https://github.com/llvm/llvm-project/commit/36622c4e1a48cd02209524592abb9d929fff1e22.diff LOG: [clang-format] Fix AllowShortFunctionsOnASingleLine: InlineOnly with wrapping after record. Fixes https://github.com/llvm/llvm-project/issues/53430. Initially, I had a quick and dirty approach, but it led to a myriad of special cases handling comments (that may add unwrapped lines). So I added TT_RecordLBrace type annotations and it seems like a much nicer solution. I think that in the future it will allow us to clean up some convoluted code that detects records. Reviewed By: MyDeveloperDay, HazardyKnusperkeks Differential Revision: https://reviews.llvm.org/D118337 Added: Modified: clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineFormatter.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 7cc090cb77de..a64329802ee3 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -96,6 +96,7 @@ namespace format { TYPE(PointerOrReference) \ TYPE(PureVirtualSpecifier) \ TYPE(RangeBasedForLoopColon) \ + TYPE(RecordLBrace) \ TYPE(RegexLiteral) \ TYPE(SelectorName) \ TYPE(StartOfName) \ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a8cd1e30f74e..9d130dbb02eb 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1423,7 +1423,8 @@ class AnnotatingParser { TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator, TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral, TT_UntouchableMacroFunc, TT_ConstraintJunctions, -TT_StatementAttributeLikeMacro, TT_FunctionLikeOrFreestandingMacro)) +TT_StatementAttributeLikeMacro, TT_FunctionLikeOrFreestandingMacro, +TT_RecordLBrace)) CurrentToken->setType(TT_Unknown); CurrentToken->Role.reset(); CurrentToken->MatchingParen = nullptr; diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 293a693fd481..0172a224335c 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -276,6 +276,9 @@ class LineJoiner { FormatStyle::SFS_InlineOnly) { // Just checking TheLine->Level != 0 is not enough, because it // provokes treating functions inside indented namespaces as short. +if (Style.isJavaScript() && (*I)->Last->is(TT_FunctionLBrace)) + return true; + if ((*I)->Level != 0) { if (I == B) return false; @@ -288,23 +291,10 @@ class LineJoiner { break; // Check if the found line starts a record. - auto *RecordTok = (*J)->First; - while (RecordTok) { -// TODO: Refactor to isRecord(RecordTok). -if (RecordTok->isOneOf(tok::kw_class, tok::kw_struct)) - return true; -if (Style.isCpp() && RecordTok->is(tok::kw_union)) - return true; -if (Style.isCSharp() && RecordTok->is(Keywords.kw_interface)) - return true; -if (Style.Language == FormatStyle::LK_Java && -RecordTok->is(tok::kw_enum)) - return true; -if (Style.isJavaScript() && RecordTok->is(Keywords.kw_function)) - return true; - -RecordTok = RecordTok->Next; - } + for (const FormatToken *RecordTok = (*J)->Last; RecordTok; + RecordTok = RecordTok->Previous) +if (RecordTok->is(tok::l_brace)) + return RecordTok->is(TT_RecordLBrace); return false; } diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index b0588d92ab00..35be2fa3eb62 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2482,7 +2482,8 @@ void
[clang] 93948c5 - [clang-format] Correctly format lambdas with variadic template parameters.
Author: Marek Kurdej Date: 2022-01-26T16:10:52+01:00 New Revision: 93948c5299d7ee446aa707221751a0af2b87c12b URL: https://github.com/llvm/llvm-project/commit/93948c5299d7ee446aa707221751a0af2b87c12b DIFF: https://github.com/llvm/llvm-project/commit/93948c5299d7ee446aa707221751a0af2b87c12b.diff LOG: [clang-format] Correctly format lambdas with variadic template parameters. Fixes https://github.com/llvm/llvm-project/issues/53405. Reviewed By: MyDeveloperDay, owenpan Differential Revision: https://reviews.llvm.org/D118220 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index ff3e791822c47..b0588d92ab001 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1856,6 +1856,7 @@ bool UnwrappedLineParser::tryToParseLambda() { return false; bool SeenArrow = false; + bool InTemplateParameterList = false; while (FormatTok->isNot(tok::l_brace)) { if (FormatTok->isSimpleTypeSpecifier()) { @@ -1871,6 +1872,14 @@ bool UnwrappedLineParser::tryToParseLambda() { case tok::l_square: parseSquare(); break; +case tok::kw_class: +case tok::kw_template: +case tok::kw_typename: + assert(FormatTok->Previous); + if (FormatTok->Previous->is(tok::less)) +InTemplateParameterList = true; + nextToken(); + break; case tok::amp: case tok::star: case tok::kw_const: @@ -1880,11 +1889,8 @@ bool UnwrappedLineParser::tryToParseLambda() { case tok::identifier: case tok::numeric_constant: case tok::coloncolon: -case tok::kw_class: case tok::kw_mutable: case tok::kw_noexcept: -case tok::kw_template: -case tok::kw_typename: nextToken(); break; // Specialization of a template with an integer parameter can contain @@ -1921,7 +1927,7 @@ bool UnwrappedLineParser::tryToParseLambda() { case tok::ellipsis: case tok::kw_true: case tok::kw_false: - if (SeenArrow) { + if (SeenArrow || InTemplateParameterList) { nextToken(); break; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index c45869f16ad29..9185de023ccf9 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -20560,6 +20560,36 @@ TEST_F(FormatTest, FormatsLambdas) { // Lambdas with explicit template argument lists. verifyFormat( "auto L = [] class T, class U>(T &) {};\n"); + verifyFormat("auto L = [](T) {\n" + " {\n" + "f();\n" + "g();\n" + " }\n" + "};\n"); + verifyFormat("auto L = [](T...) {\n" + " {\n" + "f();\n" + "g();\n" + " }\n" + "};\n"); + verifyFormat("auto L = [](T...) {\n" + " {\n" + "f();\n" + "g();\n" + " }\n" + "};\n"); + verifyFormat("auto L = [] class T>(T...) {\n" + " {\n" + "f();\n" + "g();\n" + " }\n" + "};\n"); + verifyFormat("auto L = [](T...) {\n" + " {\n" + "f();\n" + "g();\n" + " }\n" + "};\n"); // Multiple lambdas in the same parentheses change indentation rules. These // lambdas are forced to start on new lines. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 72e29ca - [clang-format] Fix regression in parsing pointers to arrays.
Author: Marek Kurdej Date: 2022-01-26T09:27:38+01:00 New Revision: 72e29caf039fd81bc6948e16d6f71d1581615469 URL: https://github.com/llvm/llvm-project/commit/72e29caf039fd81bc6948e16d6f71d1581615469 DIFF: https://github.com/llvm/llvm-project/commit/72e29caf039fd81bc6948e16d6f71d1581615469.diff LOG: [clang-format] Fix regression in parsing pointers to arrays. Fixes https://github.com/llvm/llvm-project/issues/53293. After commit 5c2e7c9, the code: ``` template <> struct S : Template {}; ``` was misformatted as: ``` template <> struct S : Template{}; ``` Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D118106 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp Removed: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 96d227b7fe763..ff3e791822c47 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3081,8 +3081,15 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { if (!tryToParseBracedList()) break; } - if (FormatTok->is(tok::l_square) && !tryToParseLambda()) -break; + if (FormatTok->is(tok::l_square)) { +FormatToken *Previous = FormatTok->Previous; +if (!Previous || Previous->isNot(tok::r_paren)) { + // Don't try parsing a lambda if we had a closing parenthesis before, + // it was probably a pointer to an array: int (*)[]. + if (!tryToParseLambda()) +break; +} + } if (FormatTok->Tok.is(tok::semi)) return; if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) { diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index c4e0e14ce5bcd..c45869f16ad29 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -23483,6 +23483,8 @@ TEST_F(FormatTest, EmptyShortBlock) { TEST_F(FormatTest, ShortTemplatedArgumentLists) { auto Style = getLLVMStyle(); + verifyFormat("template <> struct S : Template {};\n", Style); + verifyFormat("template <> struct S : Template {};\n", Style); verifyFormat("struct Y : X<[] { return 0; }> {};", Style); verifyFormat("struct Y<[] { return 0; }> {};", Style); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits