[clang] [clang-format] Improve BlockIndent at ColumnLimit (PR #93140)
@@ -803,6 +803,46 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, tok::kw_switch); }; + // Detecting functions is brittle. It would be better if we could annotate + // the LParen type of functions/calls. + const auto IsFunctionDeclParen = [&](const FormatToken ) { +return Tok.is(tok::l_paren) && Tok.Previous && + (Tok.Previous->is(TT_FunctionDeclarationName) || +(Tok.Previous->Previous && + Tok.Previous->Previous->is(tok::coloncolon) && + Tok.Previous->Previous->Previous && + Tok.Previous->Previous->Previous->is(TT_FunctionDeclarationName))); + }; + const auto IsFunctionCallParen = [&](const FormatToken ) { +return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous && + Tok.Previous->is(tok::identifier); + }; + const auto IsInTemplateString = [&](const FormatToken ) { +if (!Style.isJavaScript()) + return false; +for (const FormatToken *Prev = Prev; Prev = Prev->Previous) { + if (Prev->is(TT_TemplateString) && Prev->opensScope()) +return true; + if (Prev->is(TT_TemplateString) && Prev->closesScope()) +break; +} +return false; + }; + const auto IsNotSimpleFunction = [&](const FormatToken ) { gedare wrote: sure, I just used the wording from the comment that was already there. https://github.com/llvm/llvm-project/pull/93140 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Improve BlockIndent at ColumnLimit (PR #93140)
@@ -803,6 +803,46 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, tok::kw_switch); }; + // Detecting functions is brittle. It would be better if we could annotate + // the LParen type of functions/calls. + const auto IsFunctionDeclParen = [&](const FormatToken ) { +return Tok.is(tok::l_paren) && Tok.Previous && + (Tok.Previous->is(TT_FunctionDeclarationName) || +(Tok.Previous->Previous && + Tok.Previous->Previous->is(tok::coloncolon) && + Tok.Previous->Previous->Previous && + Tok.Previous->Previous->Previous->is(TT_FunctionDeclarationName))); + }; + const auto IsFunctionCallParen = [&](const FormatToken ) { +return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous && + Tok.Previous->is(tok::identifier); gedare wrote: good question. although not reported, it turns out that lambdas are also affected by this bug. I have added a test case and a fix. https://github.com/llvm/llvm-project/pull/93140 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Improve BlockIndent at ColumnLimit (PR #93140)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/93140 >From 27a2da876926d2157ea9f18c5fd71a2e81e097fc Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 21 May 2024 22:21:59 -0600 Subject: [PATCH 1/3] [clang-format] Improve BlockIndent at ColumnLimit Fixes #55731 Fixes #73584 The reported formatting problems were related to ignoring deep nesting of "simple" functions (causing #54808) and to allowing the trailing annotation to become separated from the closing parens, which allowed a break to occur between the closing parens and the trailing annotation. The fix for the nesting of "simple" functions is to detect them more carefully. "Simple" was defined in a comment as being a single non-expression argument. I tried to stay as close to the original intent of the implementation while fixing the various bad formatting reports. In the process of fixing these bugs, some latent bugs were discovered related to how JavaScript Template Strings are handled. Those are also fixed here. --- clang/lib/Format/ContinuationIndenter.cpp | 47 +-- clang/lib/Format/TokenAnnotator.cpp | 6 +++ clang/unittests/Format/FormatTest.cpp | 22 +++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 6b9fbfe0ebf53..b0a232e97b314 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -803,6 +803,46 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, tok::kw_switch); }; + // Detecting functions is brittle. It would be better if we could annotate + // the LParen type of functions/calls. + const auto IsFunctionDeclParen = [&](const FormatToken ) { +return Tok.is(tok::l_paren) && Tok.Previous && + (Tok.Previous->is(TT_FunctionDeclarationName) || +(Tok.Previous->Previous && + Tok.Previous->Previous->is(tok::coloncolon) && + Tok.Previous->Previous->Previous && + Tok.Previous->Previous->Previous->is(TT_FunctionDeclarationName))); + }; + const auto IsFunctionCallParen = [&](const FormatToken ) { +return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous && + Tok.Previous->is(tok::identifier); + }; + const auto IsInTemplateString = [&](const FormatToken ) { +if (!Style.isJavaScript()) + return false; +for (const FormatToken *Prev = Prev; Prev = Prev->Previous) { + if (Prev->is(TT_TemplateString) && Prev->opensScope()) +return true; + if (Prev->is(TT_TemplateString) && Prev->closesScope()) +break; +} +return false; + }; + const auto IsNotSimpleFunction = [&](const FormatToken ) { +const auto *Previous = Tok.Previous; +const auto *Next = Tok.Next; +if (Tok.FakeLParens.size() > 0 && Tok.FakeLParens.back() > prec::Unknown) + return true; +if (Previous && +(IsFunctionDeclParen(*Previous) || IsFunctionCallParen(*Previous))) { + if (!IsOpeningBracket(Tok) && Next && !Next->isMemberAccess() && + !IsInTemplateString(Tok) && !IsFunctionDeclParen(*Next) && + !IsFunctionCallParen(*Next)) { +return true; + } +} +return false; + }; if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak || Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) && IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) && @@ -813,10 +853,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, // cll( // cll( // caaall(aa, a; - Current.FakeLParens.size() > 0 && - Current.FakeLParens.back() > prec::Unknown) { + IsNotSimpleFunction(Current)) { CurrentState.NoLineBreak = true; } + if (Previous.is(TT_TemplateString) && Previous.opensScope()) CurrentState.NoLineBreak = true; @@ -831,7 +871,8 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, Previous.isNot(TT_TableGenDAGArgOpenerToBreak) && !(Current.MacroParent && Previous.MacroParent) && (Current.isNot(TT_LineComment) || - Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen))) { + Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen)) && + !IsInTemplateString(Current)) { CurrentState.Indent = State.Column + Spaces; CurrentState.IsAligned = true; } diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 7c4c76a91f2c5..094e87db2426a 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -6157,6 +6157,12 @@ bool TokenAnnotator::canBreakBefore(const
[clang] [clang-format] Improve BlockIndent at ColumnLimit (PR #93140)
@@ -6157,6 +6157,12 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine , return !(Previous && (Previous->is(tok::kw_for) || Previous->isIf())); } + if (Left.isOneOf(tok::r_paren, TT_TrailingAnnotation) && gedare wrote: yes, it is part of the problems reported in #55731 https://github.com/llvm/llvm-project/pull/93140 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpacesInParensOption for filtering repeated parens (PR #77522)
gedare wrote: I had to rebase for merge conflicts, so I also cleaned up the commit history a bit. This seems to be working fine and tests pass. https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpacesInParensOption for filtering repeated parens (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From a2c2ad9cfdb2edcd2facaef00a7ff9e032d0111b Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 1/3] Add SpaceInParensOption ExceptDoubleParentheses This change allows finer control over addition of spaces between a pair of consecutive opening parentheses with a pair of closing parentheses. --- clang/docs/ClangFormatStyleOptions.rst | 28 +- clang/docs/ReleaseNotes.rst| 3 + clang/include/clang/Format/Format.h| 40 ++- clang/lib/Format/Format.cpp| 5 +- clang/lib/Format/TokenAnnotator.cpp| 70 +++-- clang/unittests/Format/ConfigParseTest.cpp | 21 +- clang/unittests/Format/FormatTest.cpp | 314 + 7 files changed, 441 insertions(+), 40 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 1a7d0e6a05e31..2b76f3c244b8a 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -6214,6 +6214,7 @@ the configuration (without a prefix: ``Auto``). # Example of usage: SpacesInParens: Custom SpacesInParensOptions: + ExceptDoubleParentheses: false InConditionalStatements: true InEmptyParentheses: true @@ -6226,9 +6227,23 @@ the configuration (without a prefix: ``Auto``). # Should be declared this way: SpacesInParens: Custom SpacesInParensOptions: + ExceptDoubleParentheses: false InConditionalStatements: true Other: true + * ``bool ExceptDoubleParentheses`` Override any of the following options to prevent addition of space +between the first two parentheses in situations where a pair of +parentheses have been used. + +.. code-block:: c++ + + true: + __attribute__(( noreturn )) + __decltype__(( x )) + if (( a = b )) + false: + Uses the applicable option. + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). @@ -6242,8 +6257,9 @@ the configuration (without a prefix: ``Auto``). .. code-block:: c++ - true: false: - x = ( int32 )y vs. x = (int32)y + true: false: + x = ( int32 )y vs.x = (int32)y + y = (( int (*)(int) )foo)(x); y = ((int (*)(int))foo)(x); * ``bool InEmptyParentheses`` Put a space in parentheses only if the parentheses are empty i.e. '()' @@ -6261,8 +6277,12 @@ the configuration (without a prefix: ``Auto``). .. code-block:: c++ - true: false: - t f( Deleted & ) & = delete; vs. t f(Deleted &) & = delete; + true: false: + t f( Deleted & ) & = delete;vs. t f(Deleted &) & = delete; + decltype( ( x ) ) decltype((x)) + x = ( (int32)y ) x = ((int32))y + y = ( (int ( * )( int ))foo )( x ); y = ((int (*)(int))foo)(x); + __attribute__( ( noreturn ) )__attribute__((noreturn)) .. _SpacesInParentheses: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 22b4dc172c840..6714f20b4f876 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -990,6 +990,9 @@ clang-format - Adds ``AllowShortCaseExpressionOnASingleLine`` option. - Adds ``AlignCaseArrows`` suboption to ``AlignConsecutiveShortCaseStatements``. - Adds ``LeftWithLastLine`` suboption to ``AlignEscapedNewlines``. +- Add ``ExceptDoubleParentheses`` sub-option for ``SpacesInParensOptions`` + to override addition of spaces between multiple, non-redundant parentheses + similar to the rules used for ``RemoveParentheses``. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index eb6647038403d..880581edbbd3f 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4650,10 +4650,23 @@ struct FormatStyle { /// # Should be declared this way: /// SpacesInParens: Custom /// SpacesInParensOptions: + /// ExceptDoubleParentheses: false /// InConditionalStatements: true /// Other: true /// \endcode struct SpacesInParensCustom { +/// Override any of the following options to prevent addition of space +/// between the first two parentheses in situations where a pair of +/// parentheses have been used. +/// \code +/// true: +/// __attribute__(( noreturn )) +/// __decltype__(( x )) +/// if (( a = b )) +/// \endcode +/// false: +///Uses the applicable option. +bool ExceptDoubleParentheses; /// Put a space in parentheses only inside conditional statements ///
[clang] Code implementing SpacesInParensOptions.ExceptDoubleParentheses logic (PR #93439)
gedare wrote: I'll try this out in the next few days. https://github.com/llvm/llvm-project/pull/93439 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/92617 >From b4a8c06b79ec10ed2f53a7410bd847ecfa9e8450 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Fri, 17 May 2024 17:18:59 -0600 Subject: [PATCH 1/6] [clang-format]: Annotate colons found in inline assembly Short-circuit the parsing of tok::colon to label colons found within lines starting with asm as InlineASMColon. Fixes #92616. --- clang/lib/Format/TokenAnnotator.cpp | 2 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 20 --- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 7c4c76a91f2c5..a83f937336565 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1358,6 +1358,8 @@ class AnnotatingParser { Line.First->startsSequence(tok::kw_export, Keywords.kw_module) || Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) { Tok->setType(TT_ModulePartitionColon); + } else if (Line.First->is(tok::kw_asm)) { +Tok->setType(TT_InlineASMColon); } else if (Contexts.back().ColonIsDictLiteral || Style.isProto()) { Tok->setType(TT_DictLiteral); if (Style.Language == FormatStyle::LK_TextProto) { diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index aadfa6dc0165c..0f5f3936e0181 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1489,11 +1489,25 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" "a:\n" - "};"); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; + ": x\n" + ":};"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_InlineASMBrace); - EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_InlineASMBrace); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); + + Tokens = annotate("__asm__ volatile (\n" +"a:\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); } TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) { >From 835425caa996d63f726bf89599b49ac2ad7fa3fb Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 23 May 2024 08:37:50 -0600 Subject: [PATCH 2/6] TokenAnnotator: remove redundant TT_InlineASMColon and add more tests --- clang/lib/Format/TokenAnnotator.cpp | 9 +-- clang/unittests/Format/TokenAnnotatorTest.cpp | 69 ++- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a83f937336565..bbf791c44d775 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1428,12 +1428,9 @@ class AnnotatingParser { // the colon are passed as macro arguments. Tok->setType(TT_ObjCMethodExpr); } else if (Contexts.back().ContextKind == tok::l_paren && - !Line.InPragmaDirective) { -if (Style.isTableGen() && Contexts.back().IsTableGenDAGArg) { - Tok->setType(TT_TableGenDAGArgListColon); - break; -} -Tok->setType(TT_InlineASMColon); + !Line.InPragmaDirective && Style.isTableGen() && + Contexts.back().IsTableGenDAGArg) { +Tok->setType(TT_TableGenDAGArgListColon); } break; case tok::pipe: diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 0f5f3936e0181..f5e819f8719a6 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1488,7 +1488,7 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" - "a:\n" + "\"a\":\n" ": x\n" ":};"); ASSERT_EQ(Tokens.size(), 10u) << Tokens; @@ -1500,7 +1500,7 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); Tokens = annotate("__asm__ volatile (\n" -"a:\n" +"\"a\":\n"
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
@@ -1488,12 +1488,81 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" - "a:\n" - "};"); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; + "\"a\":\n" + ": x\n" + ":};"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_InlineASMBrace); - EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_InlineASMBrace); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); + + Tokens = annotate("__asm(\n" +"\"a\":\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + + Tokens = annotate("asm volatile (\n" +"\"a_label:\"\n" +":\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); + + Tokens = annotate("__asm__(\n" +"\"a_label:\"\n" +": x\n" +":\n" +": y);"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + + Tokens = annotate("__asm volatile (\n" +"\"a_label:\"\n" +"\"a b c(%%x)\"\n" +":\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 12u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[8], tok::colon, TT_InlineASMColon); + + Tokens = annotate("asm(\n" +"\"insn\"\n" +": \"=r\" (var1), \"=\" (value)\n" +":\n" +": \"memory\");"); + ASSERT_EQ(Tokens.size(), 19u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[13], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[14], tok::colon, TT_InlineASMColon); + + Tokens = annotate("__asm__ volatile (\n" +"\"ldr r1, [r0, %%[sym]]\"\n" +":\n" +": [sym] \"J\" (a(, ))\n" +");"); + ASSERT_EQ(Tokens.size(), 21u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); } gedare wrote: Nice. I shouldn't review comments on my phone. https://github.com/llvm/llvm-project/pull/92617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
@@ -1488,12 +1488,81 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" - "a:\n" - "};"); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; + "\"a\":\n" + ": x\n" + ":};"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_InlineASMBrace); - EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_InlineASMBrace); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); + + Tokens = annotate("__asm(\n" +"\"a\":\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + + Tokens = annotate("asm volatile (\n" +"\"a_label:\"\n" +":\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); + + Tokens = annotate("__asm__(\n" +"\"a_label:\"\n" +": x\n" +":\n" +": y);"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + + Tokens = annotate("__asm volatile (\n" +"\"a_label:\"\n" +"\"a b c(%%x)\"\n" +":\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 12u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[8], tok::colon, TT_InlineASMColon); + + Tokens = annotate("asm(\n" +"\"insn\"\n" +": \"=r\" (var1), \"=\" (value)\n" +":\n" +": \"memory\");"); + ASSERT_EQ(Tokens.size(), 19u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[13], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[14], tok::colon, TT_InlineASMColon); + + Tokens = annotate("__asm__ volatile (\n" +"\"ldr r1, [r0, %%[sym]]\"\n" +":\n" +": [sym] \"J\" (a(, ))\n" +");"); + ASSERT_EQ(Tokens.size(), 21u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); } gedare wrote: There is no third colon in this test. https://github.com/llvm/llvm-project/pull/92617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
gedare wrote: > It seems that you used 5 different assembly snippets and repeated each 3-6 > times. Instead, we can have something like the following: > > ``` > asm{Snippet 1}; > > __asm(Snippet 2); > > __asm__(Snippet 3); > > asm volatile (Snippet 4); > > __asm volatile (Snippet 5); > ``` > > Also, no space between `tok::asm` (i.e. `asm`, `__asm`, or `__asm__`) and `(`. done, thanks for the clarification https://github.com/llvm/llvm-project/pull/92617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
@@ -1488,12 +1488,247 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" - "a:\n" - "};"); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; + "\"a\":\n" + ": x\n" + ":};"); gedare wrote: AFAIK it's not valid, unless `a` is a CPP string. https://github.com/llvm/llvm-project/pull/92617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/92617 >From b4a8c06b79ec10ed2f53a7410bd847ecfa9e8450 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Fri, 17 May 2024 17:18:59 -0600 Subject: [PATCH 1/5] [clang-format]: Annotate colons found in inline assembly Short-circuit the parsing of tok::colon to label colons found within lines starting with asm as InlineASMColon. Fixes #92616. --- clang/lib/Format/TokenAnnotator.cpp | 2 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 20 --- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 7c4c76a91f2c5..a83f937336565 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1358,6 +1358,8 @@ class AnnotatingParser { Line.First->startsSequence(tok::kw_export, Keywords.kw_module) || Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) { Tok->setType(TT_ModulePartitionColon); + } else if (Line.First->is(tok::kw_asm)) { +Tok->setType(TT_InlineASMColon); } else if (Contexts.back().ColonIsDictLiteral || Style.isProto()) { Tok->setType(TT_DictLiteral); if (Style.Language == FormatStyle::LK_TextProto) { diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index aadfa6dc0165c..0f5f3936e0181 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1489,11 +1489,25 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" "a:\n" - "};"); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; + ": x\n" + ":};"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_InlineASMBrace); - EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_InlineASMBrace); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); + + Tokens = annotate("__asm__ volatile (\n" +"a:\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); } TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) { >From 835425caa996d63f726bf89599b49ac2ad7fa3fb Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 23 May 2024 08:37:50 -0600 Subject: [PATCH 2/5] TokenAnnotator: remove redundant TT_InlineASMColon and add more tests --- clang/lib/Format/TokenAnnotator.cpp | 9 +-- clang/unittests/Format/TokenAnnotatorTest.cpp | 69 ++- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a83f937336565..bbf791c44d775 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1428,12 +1428,9 @@ class AnnotatingParser { // the colon are passed as macro arguments. Tok->setType(TT_ObjCMethodExpr); } else if (Contexts.back().ContextKind == tok::l_paren && - !Line.InPragmaDirective) { -if (Style.isTableGen() && Contexts.back().IsTableGenDAGArg) { - Tok->setType(TT_TableGenDAGArgListColon); - break; -} -Tok->setType(TT_InlineASMColon); + !Line.InPragmaDirective && Style.isTableGen() && + Contexts.back().IsTableGenDAGArg) { +Tok->setType(TT_TableGenDAGArgListColon); } break; case tok::pipe: diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 0f5f3936e0181..f5e819f8719a6 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1488,7 +1488,7 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" - "a:\n" + "\"a\":\n" ": x\n" ":};"); ASSERT_EQ(Tokens.size(), 10u) << Tokens; @@ -1500,7 +1500,7 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); Tokens = annotate("__asm__ volatile (\n" -"a:\n" +"\"a\":\n"
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/92617 >From b4a8c06b79ec10ed2f53a7410bd847ecfa9e8450 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Fri, 17 May 2024 17:18:59 -0600 Subject: [PATCH 1/4] [clang-format]: Annotate colons found in inline assembly Short-circuit the parsing of tok::colon to label colons found within lines starting with asm as InlineASMColon. Fixes #92616. --- clang/lib/Format/TokenAnnotator.cpp | 2 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 20 --- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 7c4c76a91f2c5..a83f937336565 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1358,6 +1358,8 @@ class AnnotatingParser { Line.First->startsSequence(tok::kw_export, Keywords.kw_module) || Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) { Tok->setType(TT_ModulePartitionColon); + } else if (Line.First->is(tok::kw_asm)) { +Tok->setType(TT_InlineASMColon); } else if (Contexts.back().ColonIsDictLiteral || Style.isProto()) { Tok->setType(TT_DictLiteral); if (Style.Language == FormatStyle::LK_TextProto) { diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index aadfa6dc0165c..0f5f3936e0181 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1489,11 +1489,25 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" "a:\n" - "};"); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; + ": x\n" + ":};"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_InlineASMBrace); - EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_InlineASMBrace); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); + + Tokens = annotate("__asm__ volatile (\n" +"a:\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); } TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) { >From 835425caa996d63f726bf89599b49ac2ad7fa3fb Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 23 May 2024 08:37:50 -0600 Subject: [PATCH 2/4] TokenAnnotator: remove redundant TT_InlineASMColon and add more tests --- clang/lib/Format/TokenAnnotator.cpp | 9 +-- clang/unittests/Format/TokenAnnotatorTest.cpp | 69 ++- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a83f937336565..bbf791c44d775 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1428,12 +1428,9 @@ class AnnotatingParser { // the colon are passed as macro arguments. Tok->setType(TT_ObjCMethodExpr); } else if (Contexts.back().ContextKind == tok::l_paren && - !Line.InPragmaDirective) { -if (Style.isTableGen() && Contexts.back().IsTableGenDAGArg) { - Tok->setType(TT_TableGenDAGArgListColon); - break; -} -Tok->setType(TT_InlineASMColon); + !Line.InPragmaDirective && Style.isTableGen() && + Contexts.back().IsTableGenDAGArg) { +Tok->setType(TT_TableGenDAGArgListColon); } break; case tok::pipe: diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 0f5f3936e0181..f5e819f8719a6 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1488,7 +1488,7 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" - "a:\n" + "\"a\":\n" ": x\n" ":};"); ASSERT_EQ(Tokens.size(), 10u) << Tokens; @@ -1500,7 +1500,7 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); Tokens = annotate("__asm__ volatile (\n" -"a:\n" +"\"a\":\n"
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
@@ -1426,12 +1428,9 @@ class AnnotatingParser { // the colon are passed as macro arguments. Tok->setType(TT_ObjCMethodExpr); } else if (Contexts.back().ContextKind == tok::l_paren && - !Line.InPragmaDirective) { -if (Style.isTableGen() && Contexts.back().IsTableGenDAGArg) { - Tok->setType(TT_TableGenDAGArgListColon); - break; -} -Tok->setType(TT_InlineASMColon); + !Line.InPragmaDirective && Style.isTableGen() && + Contexts.back().IsTableGenDAGArg) { +Tok->setType(TT_TableGenDAGArgListColon); gedare wrote: done, tests pass. @hnakamura5 any objections? https://github.com/llvm/llvm-project/pull/92617/files#diff-f7c46dd11ab8379e248666096236ccfb4966e050f6494588cb9484c0e29d4e3dL1428 https://github.com/llvm/llvm-project/pull/92617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/92617 >From b4a8c06b79ec10ed2f53a7410bd847ecfa9e8450 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Fri, 17 May 2024 17:18:59 -0600 Subject: [PATCH 1/3] [clang-format]: Annotate colons found in inline assembly Short-circuit the parsing of tok::colon to label colons found within lines starting with asm as InlineASMColon. Fixes #92616. --- clang/lib/Format/TokenAnnotator.cpp | 2 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 20 --- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 7c4c76a91f2c5..a83f937336565 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1358,6 +1358,8 @@ class AnnotatingParser { Line.First->startsSequence(tok::kw_export, Keywords.kw_module) || Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) { Tok->setType(TT_ModulePartitionColon); + } else if (Line.First->is(tok::kw_asm)) { +Tok->setType(TT_InlineASMColon); } else if (Contexts.back().ColonIsDictLiteral || Style.isProto()) { Tok->setType(TT_DictLiteral); if (Style.Language == FormatStyle::LK_TextProto) { diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index aadfa6dc0165c..0f5f3936e0181 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1489,11 +1489,25 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" "a:\n" - "};"); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; + ": x\n" + ":};"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_InlineASMBrace); - EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_InlineASMBrace); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); + + Tokens = annotate("__asm__ volatile (\n" +"a:\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); } TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) { >From 835425caa996d63f726bf89599b49ac2ad7fa3fb Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 23 May 2024 08:37:50 -0600 Subject: [PATCH 2/3] TokenAnnotator: remove redundant TT_InlineASMColon and add more tests --- clang/lib/Format/TokenAnnotator.cpp | 9 +-- clang/unittests/Format/TokenAnnotatorTest.cpp | 69 ++- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a83f937336565..bbf791c44d775 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1428,12 +1428,9 @@ class AnnotatingParser { // the colon are passed as macro arguments. Tok->setType(TT_ObjCMethodExpr); } else if (Contexts.back().ContextKind == tok::l_paren && - !Line.InPragmaDirective) { -if (Style.isTableGen() && Contexts.back().IsTableGenDAGArg) { - Tok->setType(TT_TableGenDAGArgListColon); - break; -} -Tok->setType(TT_InlineASMColon); + !Line.InPragmaDirective && Style.isTableGen() && + Contexts.back().IsTableGenDAGArg) { +Tok->setType(TT_TableGenDAGArgListColon); } break; case tok::pipe: diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 0f5f3936e0181..f5e819f8719a6 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1488,7 +1488,7 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" - "a:\n" + "\"a\":\n" ": x\n" ":};"); ASSERT_EQ(Tokens.size(), 10u) << Tokens; @@ -1500,7 +1500,7 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); Tokens = annotate("__asm__ volatile (\n" -"a:\n" +"\"a\":\n"
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
@@ -1489,11 +1489,25 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" "a:\n" - "};"); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; + ": x\n" + ":};"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_InlineASMBrace); - EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_InlineASMBrace); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); + + Tokens = annotate("__asm__ volatile (\n" +"a:\n" +": x\n" +":);"); gedare wrote: added a few tests for `asm` https://github.com/llvm/llvm-project/pull/92617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
@@ -1358,6 +1358,8 @@ class AnnotatingParser { Line.First->startsSequence(tok::kw_export, Keywords.kw_module) || Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) { Tok->setType(TT_ModulePartitionColon); + } else if (Line.First->is(tok::kw_asm)) { +Tok->setType(TT_InlineASMColon); gedare wrote: Yes it appears to be redundant, I have refactored it out. https://github.com/llvm/llvm-project/pull/92617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/92617 >From b4a8c06b79ec10ed2f53a7410bd847ecfa9e8450 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Fri, 17 May 2024 17:18:59 -0600 Subject: [PATCH 1/2] [clang-format]: Annotate colons found in inline assembly Short-circuit the parsing of tok::colon to label colons found within lines starting with asm as InlineASMColon. Fixes #92616. --- clang/lib/Format/TokenAnnotator.cpp | 2 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 20 --- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 7c4c76a91f2c5..a83f937336565 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1358,6 +1358,8 @@ class AnnotatingParser { Line.First->startsSequence(tok::kw_export, Keywords.kw_module) || Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) { Tok->setType(TT_ModulePartitionColon); + } else if (Line.First->is(tok::kw_asm)) { +Tok->setType(TT_InlineASMColon); } else if (Contexts.back().ColonIsDictLiteral || Style.isProto()) { Tok->setType(TT_DictLiteral); if (Style.Language == FormatStyle::LK_TextProto) { diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index aadfa6dc0165c..0f5f3936e0181 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1489,11 +1489,25 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" "a:\n" - "};"); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; + ": x\n" + ":};"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_InlineASMBrace); - EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_InlineASMBrace); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); + + Tokens = annotate("__asm__ volatile (\n" +"a:\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); } TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) { >From 835425caa996d63f726bf89599b49ac2ad7fa3fb Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 23 May 2024 08:37:50 -0600 Subject: [PATCH 2/2] TokenAnnotator: remove redundant TT_InlineASMColon and add more tests --- clang/lib/Format/TokenAnnotator.cpp | 9 +-- clang/unittests/Format/TokenAnnotatorTest.cpp | 69 ++- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a83f937336565..bbf791c44d775 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1428,12 +1428,9 @@ class AnnotatingParser { // the colon are passed as macro arguments. Tok->setType(TT_ObjCMethodExpr); } else if (Contexts.back().ContextKind == tok::l_paren && - !Line.InPragmaDirective) { -if (Style.isTableGen() && Contexts.back().IsTableGenDAGArg) { - Tok->setType(TT_TableGenDAGArgListColon); - break; -} -Tok->setType(TT_InlineASMColon); + !Line.InPragmaDirective && Style.isTableGen() && + Contexts.back().IsTableGenDAGArg) { +Tok->setType(TT_TableGenDAGArgListColon); } break; case tok::pipe: diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 0f5f3936e0181..f5e819f8719a6 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1488,7 +1488,7 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" - "a:\n" + "\"a\":\n" ": x\n" ":};"); ASSERT_EQ(Tokens.size(), 10u) << Tokens; @@ -1500,7 +1500,7 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); Tokens = annotate("__asm__ volatile (\n" -"a:\n" +"\"a\":\n"
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
https://github.com/gedare edited https://github.com/llvm/llvm-project/pull/92617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
https://github.com/gedare edited https://github.com/llvm/llvm-project/pull/92617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
@@ -1489,11 +1489,25 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" "a:\n" - "};"); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; + ": x\n" + ":};"); gedare wrote: It's valid. The input, output, and clobber operands are a comma-separated list of C variables (or equivalently produced CPP macros), which may be empty. https://github.com/llvm/llvm-project/pull/92617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Improve BlockIndent at ColumnLimit (PR #93140)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/93140 >From 27a2da876926d2157ea9f18c5fd71a2e81e097fc Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 21 May 2024 22:21:59 -0600 Subject: [PATCH 1/2] [clang-format] Improve BlockIndent at ColumnLimit Fixes #55731 Fixes #73584 The reported formatting problems were related to ignoring deep nesting of "simple" functions (causing #54808) and to allowing the trailing annotation to become separated from the closing parens, which allowed a break to occur between the closing parens and the trailing annotation. The fix for the nesting of "simple" functions is to detect them more carefully. "Simple" was defined in a comment as being a single non-expression argument. I tried to stay as close to the original intent of the implementation while fixing the various bad formatting reports. In the process of fixing these bugs, some latent bugs were discovered related to how JavaScript Template Strings are handled. Those are also fixed here. --- clang/lib/Format/ContinuationIndenter.cpp | 47 +-- clang/lib/Format/TokenAnnotator.cpp | 6 +++ clang/unittests/Format/FormatTest.cpp | 22 +++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 6b9fbfe0ebf53..b0a232e97b314 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -803,6 +803,46 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, tok::kw_switch); }; + // Detecting functions is brittle. It would be better if we could annotate + // the LParen type of functions/calls. + const auto IsFunctionDeclParen = [&](const FormatToken ) { +return Tok.is(tok::l_paren) && Tok.Previous && + (Tok.Previous->is(TT_FunctionDeclarationName) || +(Tok.Previous->Previous && + Tok.Previous->Previous->is(tok::coloncolon) && + Tok.Previous->Previous->Previous && + Tok.Previous->Previous->Previous->is(TT_FunctionDeclarationName))); + }; + const auto IsFunctionCallParen = [&](const FormatToken ) { +return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous && + Tok.Previous->is(tok::identifier); + }; + const auto IsInTemplateString = [&](const FormatToken ) { +if (!Style.isJavaScript()) + return false; +for (const FormatToken *Prev = Prev; Prev = Prev->Previous) { + if (Prev->is(TT_TemplateString) && Prev->opensScope()) +return true; + if (Prev->is(TT_TemplateString) && Prev->closesScope()) +break; +} +return false; + }; + const auto IsNotSimpleFunction = [&](const FormatToken ) { +const auto *Previous = Tok.Previous; +const auto *Next = Tok.Next; +if (Tok.FakeLParens.size() > 0 && Tok.FakeLParens.back() > prec::Unknown) + return true; +if (Previous && +(IsFunctionDeclParen(*Previous) || IsFunctionCallParen(*Previous))) { + if (!IsOpeningBracket(Tok) && Next && !Next->isMemberAccess() && + !IsInTemplateString(Tok) && !IsFunctionDeclParen(*Next) && + !IsFunctionCallParen(*Next)) { +return true; + } +} +return false; + }; if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak || Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) && IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) && @@ -813,10 +853,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, // cll( // cll( // caaall(aa, a; - Current.FakeLParens.size() > 0 && - Current.FakeLParens.back() > prec::Unknown) { + IsNotSimpleFunction(Current)) { CurrentState.NoLineBreak = true; } + if (Previous.is(TT_TemplateString) && Previous.opensScope()) CurrentState.NoLineBreak = true; @@ -831,7 +871,8 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, Previous.isNot(TT_TableGenDAGArgOpenerToBreak) && !(Current.MacroParent && Previous.MacroParent) && (Current.isNot(TT_LineComment) || - Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen))) { + Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen)) && + !IsInTemplateString(Current)) { CurrentState.Indent = State.Column + Spaces; CurrentState.IsAligned = true; } diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 7c4c76a91f2c5..094e87db2426a 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -6157,6 +6157,12 @@ bool TokenAnnotator::canBreakBefore(const
[clang] [clang-format] Improve BlockIndent at ColumnLimit (PR #93140)
https://github.com/gedare created https://github.com/llvm/llvm-project/pull/93140 Fixes #55731 Fixes #73584 The reported formatting problems were related to ignoring deep nesting of "simple" functions (causing #54808) and to allowing the trailing annotation to become separated from the closing parens, which allowed a break to occur between the closing parens and the trailing annotation. The fix for the nesting of "simple" functions is to detect them more carefully. "Simple" was defined in a comment as being a single non-expression argument. I tried to stay as close to the original intent of the implementation while fixing the various bad formatting reports. In the process of fixing these bugs, some latent bugs were discovered related to how JavaScript Template Strings are handled. Those are also fixed here. >From 27a2da876926d2157ea9f18c5fd71a2e81e097fc Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 21 May 2024 22:21:59 -0600 Subject: [PATCH] [clang-format] Improve BlockIndent at ColumnLimit Fixes #55731 Fixes #73584 The reported formatting problems were related to ignoring deep nesting of "simple" functions (causing #54808) and to allowing the trailing annotation to become separated from the closing parens, which allowed a break to occur between the closing parens and the trailing annotation. The fix for the nesting of "simple" functions is to detect them more carefully. "Simple" was defined in a comment as being a single non-expression argument. I tried to stay as close to the original intent of the implementation while fixing the various bad formatting reports. In the process of fixing these bugs, some latent bugs were discovered related to how JavaScript Template Strings are handled. Those are also fixed here. --- clang/lib/Format/ContinuationIndenter.cpp | 47 +-- clang/lib/Format/TokenAnnotator.cpp | 6 +++ clang/unittests/Format/FormatTest.cpp | 22 +++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 6b9fbfe0ebf53..b0a232e97b314 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -803,6 +803,46 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, tok::kw_switch); }; + // Detecting functions is brittle. It would be better if we could annotate + // the LParen type of functions/calls. + const auto IsFunctionDeclParen = [&](const FormatToken ) { +return Tok.is(tok::l_paren) && Tok.Previous && + (Tok.Previous->is(TT_FunctionDeclarationName) || +(Tok.Previous->Previous && + Tok.Previous->Previous->is(tok::coloncolon) && + Tok.Previous->Previous->Previous && + Tok.Previous->Previous->Previous->is(TT_FunctionDeclarationName))); + }; + const auto IsFunctionCallParen = [&](const FormatToken ) { +return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous && + Tok.Previous->is(tok::identifier); + }; + const auto IsInTemplateString = [&](const FormatToken ) { +if (!Style.isJavaScript()) + return false; +for (const FormatToken *Prev = Prev; Prev = Prev->Previous) { + if (Prev->is(TT_TemplateString) && Prev->opensScope()) +return true; + if (Prev->is(TT_TemplateString) && Prev->closesScope()) +break; +} +return false; + }; + const auto IsNotSimpleFunction = [&](const FormatToken ) { +const auto *Previous = Tok.Previous; +const auto *Next = Tok.Next; +if (Tok.FakeLParens.size() > 0 && Tok.FakeLParens.back() > prec::Unknown) + return true; +if (Previous && +(IsFunctionDeclParen(*Previous) || IsFunctionCallParen(*Previous))) { + if (!IsOpeningBracket(Tok) && Next && !Next->isMemberAccess() && + !IsInTemplateString(Tok) && !IsFunctionDeclParen(*Next) && + !IsFunctionCallParen(*Next)) { +return true; + } +} +return false; + }; if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak || Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) && IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) && @@ -813,10 +853,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, // cll( // cll( // caaall(aa, a; - Current.FakeLParens.size() > 0 && - Current.FakeLParens.back() > prec::Unknown) { + IsNotSimpleFunction(Current)) { CurrentState.NoLineBreak = true; } + if (Previous.is(TT_TemplateString) && Previous.opensScope()) CurrentState.NoLineBreak = true; @@ -831,7 +871,8 @@ void
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
gedare wrote: With the patch: ``` $ echo " asm ( a : );" | clang-format -debug ... M=0 C=1 T=InlineASMColon S=1 F=0 B=0 BK=0 P=43 Name=colon L=7 PPK=2 FakeLParens= FakeRParens=1 II=0x0 Text=':' ... $ echo " asm { a : };" | clang-format -debug ... M=0 C=1 T=InlineASMColon S=0 F=1 B=0 BK=0 P=43 Name=colon L=7 PPK=2 FakeLParens= FakeRParens=1 II=0x0 Text=':' ``` https://github.com/llvm/llvm-project/pull/92617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Annotate colons found in inline assembly (PR #92617)
https://github.com/gedare created https://github.com/llvm/llvm-project/pull/92617 Short-circuit the parsing of tok::colon to label colons found within lines starting with asm as InlineASMColon. Fixes #92616. >From b4a8c06b79ec10ed2f53a7410bd847ecfa9e8450 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Fri, 17 May 2024 17:18:59 -0600 Subject: [PATCH] [clang-format]: Annotate colons found in inline assembly Short-circuit the parsing of tok::colon to label colons found within lines starting with asm as InlineASMColon. Fixes #92616. --- clang/lib/Format/TokenAnnotator.cpp | 2 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 20 --- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 7c4c76a91f2c5..a83f937336565 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1358,6 +1358,8 @@ class AnnotatingParser { Line.First->startsSequence(tok::kw_export, Keywords.kw_module) || Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) { Tok->setType(TT_ModulePartitionColon); + } else if (Line.First->is(tok::kw_asm)) { +Tok->setType(TT_InlineASMColon); } else if (Contexts.back().ColonIsDictLiteral || Style.isProto()) { Tok->setType(TT_DictLiteral); if (Style.Language == FormatStyle::LK_TextProto) { diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index aadfa6dc0165c..0f5f3936e0181 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1489,11 +1489,25 @@ TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) { TEST_F(TokenAnnotatorTest, UnderstandsAsm) { auto Tokens = annotate("__asm{\n" "a:\n" - "};"); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; + ": x\n" + ":};"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_InlineASMBrace); - EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_InlineASMBrace); + EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::r_brace, TT_InlineASMBrace); + + Tokens = annotate("__asm__ volatile (\n" +"a:\n" +": x\n" +":);"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); } TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpacesInParensOption for filtering repeated parens (PR #77522)
https://github.com/gedare edited https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
gedare wrote: I saw some comments on this. Looks like some were deleted maybe. This is still in my queue, but unclear when I'll get back to it. https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
gedare wrote: * Rebased to resolve conflict in ReleaseNotes. * Added `ExceptDoubleParentheses` as proposed by @owenca This seems to work reasonably well for the cases I care about, as far as I can tell. https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
gedare wrote: > > > Would `__attribute__((noreturn))`, `if ((i = j))`, `decltype((x))`, and > > > `while (((i + 1) * j - 2) * k > 3)` be formatted as `__attribute__(( > > > noreturn ))`, `if (( i = j ))`, `decltype(( x ))`, and `while ( ( ( i + 1 > > > ) * j - 2 ) * k > 3 )`, respectively? > > > > > > Almost, it would also be `if ( ( i = j ) )`, Although repeated parens are > > typically removed. So a better example is `if ( ( i = j ) && ( k > 3 ) )` > > We don't have `decltype` in our C code base. I can add support for it as an > > option if desired. > > We also have cases such as `__attribute__(( __aligned__( x ) ))` > > I'm ok with all of the above except for `if ( ( i = j ) )`, which should be > formatted as `if (( i = j ))` because the extra pair of parentheses is not > superfluous. This is similar to `decltype(( x ))`, and the`RemoveParentheses` > option doesn't strip the extra pair for either. > Yes, good point. > It seems adding a boolean sub-option that targets double pairs of parentheses > as I suggested before is feasible although a better name than > `ConsecutiveParentheses` may be needed. I'm fine to fix but request a concrete suggestion or proposal before I spend much more time on this. It might also work to suppress optionally the additional space on the first/last parenthesis pair, for these special "paired" parens. I think the way I already worked this patch is the right way to go to preserve backward compatibility while still allowing control over the repeated parentheses. Looks like it is called `MultipleParentheses` in the `RemoveParentheses` option. I should rename to that. https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Fix formatting of if statements with BlockIndent (PR #77699)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77699 >From ff055d9c064d1fb359d59eeb47cb5f8c6c422bec Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Fri, 7 Jul 2023 17:28:47 -0600 Subject: [PATCH 1/5] Fix formatting of if statements with BlockIndent A bug with BlockIndent prevents line breaks within if (and else if) clauses. While fixing this bug, it appears that AlignAfterOpenBracket is not designed to work with loop and if statements, but AlwaysBreak works on if clauses. The documentation and tests are not clear on whether or not this is intended. This patch preserves the AlwaysBreak behavior and supports BlockIndent on if clauses while fixing the bug. It may be reasonable to go the other way and create an explicit option for alignment of if (and loop) clauses intentionally. Fixes #54663. Differential Revision: https://reviews.llvm.org/D154755 --- clang/lib/Format/ContinuationIndenter.cpp | 6 ++-- clang/unittests/Format/FormatTest.cpp | 40 --- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 102504182c4505b..8b288c62473db9f 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -775,8 +775,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, Style.Cpp11BracedListStyle)) && State.Column > getNewLineColumn(State) && (!Previous.Previous || - !Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, - tok::kw_switch)) && + !(Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, +tok::kw_switch) || + (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent && + Previous.Previous->isIf( && // Don't do this for simple (no expressions) one-argument function calls // as that feels like needlessly wasting whitespace, e.g.: // diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 25ef5c680af862b..8d55e62e2558d3d 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -25889,8 +25889,8 @@ TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) { "}", Style); - verifyFormat("if (quitelongarg !=\n" - "(alsolongarg - 1)) { // ABC is a very long " + verifyFormat("if (quiteLongArg !=\n" + "(alsoLongArg - 1)) { // ABC is a very long " "comment\n" " return;\n" "}", @@ -25903,12 +25903,44 @@ TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) { "}", Style); - verifyFormat("if (quitelongarg !=\n" - "(alsolongarg - 1)) { // ABC is a very long " + verifyFormat("if (quiteLongArg !=\n" + "(alsoLongArg - 1)) { // ABC is a very long " "comment\n" " return;\n" "}", Style); + + verifyFormat("void foo() {\n" + " if (camelCaseName < alsoLongName ||\n" + " anotherEvenLongerName <=\n" + " thisReallyReallyReallyReallyReallyReallyLongerName ||" + "\n" + " otherName < thisLastName) {\n" + "return;\n" + " } else if (quiteLongName < alsoLongName ||\n" + " anotherEvenLongerName <=\n" + " thisReallyReallyReallyReallyReallyReallyLonger" + "Name ||\n" + " otherName < thisLastName) {\n" + "return;\n" + " }\n" + "}", + Style); + + Style.ContinuationIndentWidth = 2; + verifyFormat("void foo() {\n" + " if (ThisIsRatherALongIfClause && thatIExpectToBeBroken ||\n" + " ontoMultipleLines && whenFormattedCorrectly) {\n" + "if (false) {\n" + " return;\n" + "} else if (thisIsRatherALongIfClause && " + "thatIExpectToBeBroken ||\n" + " ontoMultipleLines && whenFormattedCorrectly) {\n" + " return;\n" + "}\n" + " }\n" + "}", + Style); } TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentForStatement) { >From 55cfce78dbfc87af455e6bf822b8f0a6a5f9f3d6 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Wed, 10 Jan 2024 14:44:41 -0700 Subject: [PATCH 2/5] Refactor complex conditional logic as a lambda --- clang/lib/Format/ContinuationIndenter.cpp | 25 +++ 1 file changed, 16 insertions(+), 9 deletions(-) diff --git
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
gedare wrote: > > The code is [self-hosted](https://git.rtems.org/rtems/) and [mirrored on > > GitHub](https://github.com/RTEMS/rtems) with a [documented style > > guide](https://docs.rtems.org/branches/master/eng/coding-formatting.html). > > In addition, I have been and will continue to be willing to provide bug fix > > and other maintenance support to clang-format based on the changes > > submitted to support these style needs. > > At the moment, I need to satisfy a particular style rule that requires me > > to add spaces inside of conditional and compound expressions. > > It seems the RTEMS style guide you linked above doesn't have any examples for > conditional expressions and compound expressions, and by _conditional > expressions_ I assume it means conditionals of control statements rather than > ternary [conditional > expressions](https://www.ibm.com/docs/en/zos/3.1.0?topic=operators-conditional-expressions). > Correct. Unfortunately, no one (myself) has not taken the time to thoroughly document all examples. The existing style has been inherited from the original author of our code base, as these things tend to be for older projects. > Would `__attribute__((noreturn))`, `if ((i = j))`, `decltype((x))`, and > `while (((i + 1) * j - 2) * k > 3)` be formatted as `__attribute__(( noreturn > ))`, `if (( i = j ))`, `decltype(( x ))`, and `while ( ( ( i + 1 ) * j - 2 ) > * k > 3 )`, respectively? Almost, it would also be `if ( ( i = j ) )`, Although repeated parens are typically removed. So a better example is `if ( ( i = j ) && ( k > 3 ) )` We don't have `decltype` in our C code base. I can add support for it as an option if desired. We also have cases such as `__attribute__(( __aligned__( _alignment ) ))` https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
gedare wrote: > > Covering all double parens in a single sub-option is not precise enough for > > code bases that may want to have `__attribute__(( x ))` but also allow `if > > ( ( x ) )`. > > We should not go overboard with supporting all kinds of options/suboptions > imaginable. I don't think we should support spaces between consecutive parens > in the first place, which was likely a bug. > Well, it seems to be far too late to go back and change the default behavior. > We can't just disregard the long-standing > [policy](https://clang.llvm.org/docs/ClangFormatStyleOptions.html#adding-additional-style-options) > on adding new options. If anyone thinks that policy is outdated, they should > go through the RFC process and get it updated. I have no problem with this policy. I think it is a good policy. I can advocate for my position. My patches relate to the style maintenance of a widely-used real-time operating system. The code is [self-hosted](https://git.rtems.org/rtems/) and [mirrored on GitHub](https://github.com/RTEMS/rtems) with a [documented style guide](https://docs.rtems.org/branches/master/eng/coding-formatting.html). In addition, I have been and will continue to be willing to provide bug fix and other maintenance support to clang-format based on the changes submitted to support these style needs. At the moment, I need to satisfy a particular style rule that requires me to add spaces inside of conditional and compound expressions. This support basically exists in `clang-format` but the compound expressions fall under the `SpacesInParensOption.Other` category. In order to control compound expressions separately from other uses of parens, it seems to be the easiest thing to explicitly define "everything else" and control the injection of spaces within them. Eventually, it results in a much more controlled and configurable way to manage whitespace. If this is not desired, I will need to step back to consider my options further, and probably have to take this up with the other maintainers of my code base to see what, if any, concessions we can make based on what is allowed with `clang-format`. I'm trying to get to a point where we are able to use `clang-format` on our code base with enforced CI actions. It is still a ways to go before I get there. https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From 5e5bec9fba56f34c7dd28ca866eef145035a Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 01/15] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ac9a0b70ed5daa..5dc7ad5298f83b 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5693,6 +5693,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 59732962caac65..f4e29df336b3a6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1102,6 +1102,8 @@ clang-format attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. - Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 5ffd63ee73fc36..95f15a3098044c 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4534,6 +4534,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4567,17 +4573,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ff5ed6c306f383..af4db7161be20b 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -752,6 +752,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO , FormatStyle::SpacesInParensCustom ) { +IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers); IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements",
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From 5e5bec9fba56f34c7dd28ca866eef145035a Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 01/14] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ac9a0b70ed5daa..5dc7ad5298f83b 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5693,6 +5693,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 59732962caac65..f4e29df336b3a6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1102,6 +1102,8 @@ clang-format attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. - Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 5ffd63ee73fc36..95f15a3098044c 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4534,6 +4534,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4567,17 +4573,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ff5ed6c306f383..af4db7161be20b 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -752,6 +752,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO , FormatStyle::SpacesInParensCustom ) { +IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers); IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements",
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From 5e5bec9fba56f34c7dd28ca866eef145035a Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 01/13] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ac9a0b70ed5daa..5dc7ad5298f83b 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5693,6 +5693,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 59732962caac65..f4e29df336b3a6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1102,6 +1102,8 @@ clang-format attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. - Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 5ffd63ee73fc36..95f15a3098044c 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4534,6 +4534,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4567,17 +4573,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ff5ed6c306f383..af4db7161be20b 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -752,6 +752,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO , FormatStyle::SpacesInParensCustom ) { +IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers); IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements",
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From 5e5bec9fba56f34c7dd28ca866eef145035a Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 01/12] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ac9a0b70ed5daa..5dc7ad5298f83b 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5693,6 +5693,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 59732962caac65..f4e29df336b3a6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1102,6 +1102,8 @@ clang-format attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. - Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 5ffd63ee73fc36..95f15a3098044c 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4534,6 +4534,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4567,17 +4573,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ff5ed6c306f383..af4db7161be20b 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -752,6 +752,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO , FormatStyle::SpacesInParensCustom ) { +IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers); IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements",
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From 5e5bec9fba56f34c7dd28ca866eef145035a Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 01/11] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ac9a0b70ed5daa..5dc7ad5298f83b 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5693,6 +5693,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 59732962caac65..f4e29df336b3a6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1102,6 +1102,8 @@ clang-format attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. - Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 5ffd63ee73fc36..95f15a3098044c 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4534,6 +4534,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4567,17 +4573,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ff5ed6c306f383..af4db7161be20b 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -752,6 +752,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO , FormatStyle::SpacesInParensCustom ) { +IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers); IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements",
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
gedare wrote: > > The __attribute((specifier-list)) currently is formatted based on the > > SpacesInParensOptions.Other (previously, SpacesInParentheses). This change > > allows finer control over addition of spaces between the consecutive > > parens, and between the inner parens and the list of attribute specifiers. > > Differential Revision: https://reviews.llvm.org/D155529 > > This is migrated from Phabricator, see more discussion there. > > I expressed my opinion there: > > > I would have no problem if this new option is extended to handle all double > > parens, e.g. if (( i = j )), decltype(( x )), etc. > > So I still prefer that we have a boolean suboption (e.g. > `ConsecutiveParentheses`) that covers all double parens. Please have a look, I have moved this PR more toward this direction providing fine-grained controls over double parens. Someone will have to add the decltype understanding in order to make `decltype(( x ))` work without having to enable `Other.NonConsecutive`. https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpacesInParensOption for attributes and filtering for repeated parens (PR #77522)
https://github.com/gedare edited https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From 5e5bec9fba56f34c7dd28ca866eef145035a Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 01/10] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ac9a0b70ed5daa..5dc7ad5298f83b 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5693,6 +5693,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 59732962caac65..f4e29df336b3a6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1102,6 +1102,8 @@ clang-format attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. - Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 5ffd63ee73fc36..95f15a3098044c 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4534,6 +4534,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4567,17 +4573,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ff5ed6c306f383..af4db7161be20b 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -752,6 +752,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO , FormatStyle::SpacesInParensCustom ) { +IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers); IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements",
[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From 5e5bec9fba56f34c7dd28ca866eef145035a Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 1/6] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ac9a0b70ed5daa..5dc7ad5298f83b 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5693,6 +5693,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 59732962caac65..f4e29df336b3a6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1102,6 +1102,8 @@ clang-format attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. - Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 5ffd63ee73fc36..95f15a3098044c 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4534,6 +4534,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4567,17 +4573,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ff5ed6c306f383..af4db7161be20b 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -752,6 +752,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO , FormatStyle::SpacesInParensCustom ) { +IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers); IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements",
[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)
gedare wrote: I'm still making changes on this. Not sure how to mark that in GH. Need to add test cases for double parens, and get it working for the newly added suboptions. https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From 5e5bec9fba56f34c7dd28ca866eef145035a Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 1/5] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index ac9a0b70ed5daa..5dc7ad5298f83b 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5693,6 +5693,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 59732962caac65..f4e29df336b3a6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1102,6 +1102,8 @@ clang-format attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. - Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 5ffd63ee73fc36..95f15a3098044c 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4534,6 +4534,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4567,17 +4573,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ff5ed6c306f383..af4db7161be20b 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -752,6 +752,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO , FormatStyle::SpacesInParensCustom ) { +IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers); IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements",
[clang] [clang-format] Don't confuse initializer equal signs in for loops (PR #77712)
https://github.com/gedare approved this pull request. https://github.com/llvm/llvm-project/pull/77712 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Don't confuse initializer equal signs in for loops (PR #77712)
@@ -703,7 +703,9 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, if (Current.is(tok::equal) && (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) && - CurrentState.VariablePos == 0) { + CurrentState.VariablePos == 0 && + (!Previous.Previous || + Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) { gedare wrote: yes, see if anyone complains anyway. https://github.com/llvm/llvm-project/pull/77712 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Fix formatting of if statements with BlockIndent (PR #77699)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77699 >From ff055d9c064d1fb359d59eeb47cb5f8c6c422bec Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Fri, 7 Jul 2023 17:28:47 -0600 Subject: [PATCH 1/4] Fix formatting of if statements with BlockIndent A bug with BlockIndent prevents line breaks within if (and else if) clauses. While fixing this bug, it appears that AlignAfterOpenBracket is not designed to work with loop and if statements, but AlwaysBreak works on if clauses. The documentation and tests are not clear on whether or not this is intended. This patch preserves the AlwaysBreak behavior and supports BlockIndent on if clauses while fixing the bug. It may be reasonable to go the other way and create an explicit option for alignment of if (and loop) clauses intentionally. Fixes #54663. Differential Revision: https://reviews.llvm.org/D154755 --- clang/lib/Format/ContinuationIndenter.cpp | 6 ++-- clang/unittests/Format/FormatTest.cpp | 40 --- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 102504182c4505..8b288c62473db9 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -775,8 +775,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, Style.Cpp11BracedListStyle)) && State.Column > getNewLineColumn(State) && (!Previous.Previous || - !Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, - tok::kw_switch)) && + !(Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, +tok::kw_switch) || + (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent && + Previous.Previous->isIf( && // Don't do this for simple (no expressions) one-argument function calls // as that feels like needlessly wasting whitespace, e.g.: // diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 25ef5c680af862..8d55e62e2558d3 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -25889,8 +25889,8 @@ TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) { "}", Style); - verifyFormat("if (quitelongarg !=\n" - "(alsolongarg - 1)) { // ABC is a very long " + verifyFormat("if (quiteLongArg !=\n" + "(alsoLongArg - 1)) { // ABC is a very long " "comment\n" " return;\n" "}", @@ -25903,12 +25903,44 @@ TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) { "}", Style); - verifyFormat("if (quitelongarg !=\n" - "(alsolongarg - 1)) { // ABC is a very long " + verifyFormat("if (quiteLongArg !=\n" + "(alsoLongArg - 1)) { // ABC is a very long " "comment\n" " return;\n" "}", Style); + + verifyFormat("void foo() {\n" + " if (camelCaseName < alsoLongName ||\n" + " anotherEvenLongerName <=\n" + " thisReallyReallyReallyReallyReallyReallyLongerName ||" + "\n" + " otherName < thisLastName) {\n" + "return;\n" + " } else if (quiteLongName < alsoLongName ||\n" + " anotherEvenLongerName <=\n" + " thisReallyReallyReallyReallyReallyReallyLonger" + "Name ||\n" + " otherName < thisLastName) {\n" + "return;\n" + " }\n" + "}", + Style); + + Style.ContinuationIndentWidth = 2; + verifyFormat("void foo() {\n" + " if (ThisIsRatherALongIfClause && thatIExpectToBeBroken ||\n" + " ontoMultipleLines && whenFormattedCorrectly) {\n" + "if (false) {\n" + " return;\n" + "} else if (thisIsRatherALongIfClause && " + "thatIExpectToBeBroken ||\n" + " ontoMultipleLines && whenFormattedCorrectly) {\n" + " return;\n" + "}\n" + " }\n" + "}", + Style); } TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentForStatement) { >From 55cfce78dbfc87af455e6bf822b8f0a6a5f9f3d6 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Wed, 10 Jan 2024 14:44:41 -0700 Subject: [PATCH 2/4] Refactor complex conditional logic as a lambda --- clang/lib/Format/ContinuationIndenter.cpp | 25 +++ 1 file changed, 16 insertions(+), 9 deletions(-) diff --git
[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)
gedare wrote: > > The __attribute((specifier-list)) currently is formatted based on the > > SpacesInParensOptions.Other (previously, SpacesInParentheses). This change > > allows finer control over addition of spaces between the consecutive > > parens, and between the inner parens and the list of attribute specifiers. > > Differential Revision: https://reviews.llvm.org/D155529 > > This is migrated from Phabricator, see more discussion there. > > I expressed my opinion there: > > > I would have no problem if this new option is extended to handle all double > > parens, e.g. if (( i = j )), decltype(( x )), etc. > > So I still prefer that we have a boolean suboption (e.g. > `ConsecutiveParentheses`) that covers all double parens. I will provide something shortly along these lines by duplicating the logic I used for this `InAttributeSpecifiers` to apply to the other suboptions of `SpacesInParensOptions`. Covering all double parens in a single sub-option is not precise enough for code bases that may want to have `__attribute__(( x ))` but also allow `if ( ( x ) )`. https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Fix formatting of if statements with BlockIndent (PR #77699)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77699 >From ff055d9c064d1fb359d59eeb47cb5f8c6c422bec Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Fri, 7 Jul 2023 17:28:47 -0600 Subject: [PATCH 1/3] Fix formatting of if statements with BlockIndent A bug with BlockIndent prevents line breaks within if (and else if) clauses. While fixing this bug, it appears that AlignAfterOpenBracket is not designed to work with loop and if statements, but AlwaysBreak works on if clauses. The documentation and tests are not clear on whether or not this is intended. This patch preserves the AlwaysBreak behavior and supports BlockIndent on if clauses while fixing the bug. It may be reasonable to go the other way and create an explicit option for alignment of if (and loop) clauses intentionally. Fixes #54663. Differential Revision: https://reviews.llvm.org/D154755 --- clang/lib/Format/ContinuationIndenter.cpp | 6 ++-- clang/unittests/Format/FormatTest.cpp | 40 --- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 102504182c4505..8b288c62473db9 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -775,8 +775,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, Style.Cpp11BracedListStyle)) && State.Column > getNewLineColumn(State) && (!Previous.Previous || - !Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, - tok::kw_switch)) && + !(Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, +tok::kw_switch) || + (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent && + Previous.Previous->isIf( && // Don't do this for simple (no expressions) one-argument function calls // as that feels like needlessly wasting whitespace, e.g.: // diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 25ef5c680af862..8d55e62e2558d3 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -25889,8 +25889,8 @@ TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) { "}", Style); - verifyFormat("if (quitelongarg !=\n" - "(alsolongarg - 1)) { // ABC is a very long " + verifyFormat("if (quiteLongArg !=\n" + "(alsoLongArg - 1)) { // ABC is a very long " "comment\n" " return;\n" "}", @@ -25903,12 +25903,44 @@ TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) { "}", Style); - verifyFormat("if (quitelongarg !=\n" - "(alsolongarg - 1)) { // ABC is a very long " + verifyFormat("if (quiteLongArg !=\n" + "(alsoLongArg - 1)) { // ABC is a very long " "comment\n" " return;\n" "}", Style); + + verifyFormat("void foo() {\n" + " if (camelCaseName < alsoLongName ||\n" + " anotherEvenLongerName <=\n" + " thisReallyReallyReallyReallyReallyReallyLongerName ||" + "\n" + " otherName < thisLastName) {\n" + "return;\n" + " } else if (quiteLongName < alsoLongName ||\n" + " anotherEvenLongerName <=\n" + " thisReallyReallyReallyReallyReallyReallyLonger" + "Name ||\n" + " otherName < thisLastName) {\n" + "return;\n" + " }\n" + "}", + Style); + + Style.ContinuationIndentWidth = 2; + verifyFormat("void foo() {\n" + " if (ThisIsRatherALongIfClause && thatIExpectToBeBroken ||\n" + " ontoMultipleLines && whenFormattedCorrectly) {\n" + "if (false) {\n" + " return;\n" + "} else if (thisIsRatherALongIfClause && " + "thatIExpectToBeBroken ||\n" + " ontoMultipleLines && whenFormattedCorrectly) {\n" + " return;\n" + "}\n" + " }\n" + "}", + Style); } TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentForStatement) { >From 55cfce78dbfc87af455e6bf822b8f0a6a5f9f3d6 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Wed, 10 Jan 2024 14:44:41 -0700 Subject: [PATCH 2/3] Refactor complex conditional logic as a lambda --- clang/lib/Format/ContinuationIndenter.cpp | 25 +++ 1 file changed, 16 insertions(+), 9 deletions(-) diff --git
[clang] [clang-format] Don't confuse initializer equal signs in for loops (PR #77712)
@@ -703,7 +703,9 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, if (Current.is(tok::equal) && (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) && - CurrentState.VariablePos == 0) { + CurrentState.VariablePos == 0 && + (!Previous.Previous || + Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) { gedare wrote: not a for loop, but similar code should be possible in a for loop initialization https://github.com/llvm/llvm-project/pull/77712 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Don't confuse initializer equal signs in for loops (PR #77712)
@@ -703,7 +703,9 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, if (Current.is(tok::equal) && (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) && - CurrentState.VariablePos == 0) { + CurrentState.VariablePos == 0 && + (!Previous.Previous || + Previous.Previous->isNot(TT_DesignatedInitializerPeriod))) { gedare wrote: Might need to search further back if the element being initialized is an array. ` struct { int x[2]; } a[] = { [0].x = {1,1}, [1].x[0] = 42};` https://github.com/llvm/llvm-project/pull/77712 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Fix formatting of if statements with BlockIndent (PR #77699)
https://github.com/gedare created https://github.com/llvm/llvm-project/pull/77699 A bug with BlockIndent prevents line breaks within if (and else if) clauses. While fixing this bug, it appears that AlignAfterOpenBracket is not designed to work with loop and if statements, but AlwaysBreak works on if clauses. The documentation and tests are not clear on whether or not this behavior is intended. This PR preserves the `AlwaysBreak` behavior on `if` clauses without supporting `BlockIndent` on `if` clauses to avoid regressions while fixing the bug. It may be reasonable to create an explicit option for alignment of if (and loop) clauses intentionally for both `AlwaysBreak` and `BlockIndent` Fixes #54663. Migrated from Differential Revision: https://reviews.llvm.org/D154755 See more discussion there. Addressed last open comment from the rev about refactoring the complex conditional logic involved with the `AlignAfterOpenBracket` line break behavior. >From ff055d9c064d1fb359d59eeb47cb5f8c6c422bec Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Fri, 7 Jul 2023 17:28:47 -0600 Subject: [PATCH 1/2] Fix formatting of if statements with BlockIndent A bug with BlockIndent prevents line breaks within if (and else if) clauses. While fixing this bug, it appears that AlignAfterOpenBracket is not designed to work with loop and if statements, but AlwaysBreak works on if clauses. The documentation and tests are not clear on whether or not this is intended. This patch preserves the AlwaysBreak behavior and supports BlockIndent on if clauses while fixing the bug. It may be reasonable to go the other way and create an explicit option for alignment of if (and loop) clauses intentionally. Fixes #54663. Differential Revision: https://reviews.llvm.org/D154755 --- clang/lib/Format/ContinuationIndenter.cpp | 6 ++-- clang/unittests/Format/FormatTest.cpp | 40 --- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 102504182c4505..8b288c62473db9 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -775,8 +775,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState , bool DryRun, Style.Cpp11BracedListStyle)) && State.Column > getNewLineColumn(State) && (!Previous.Previous || - !Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, - tok::kw_switch)) && + !(Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, +tok::kw_switch) || + (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent && + Previous.Previous->isIf( && // Don't do this for simple (no expressions) one-argument function calls // as that feels like needlessly wasting whitespace, e.g.: // diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 25ef5c680af862..8d55e62e2558d3 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -25889,8 +25889,8 @@ TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) { "}", Style); - verifyFormat("if (quitelongarg !=\n" - "(alsolongarg - 1)) { // ABC is a very long " + verifyFormat("if (quiteLongArg !=\n" + "(alsoLongArg - 1)) { // ABC is a very long " "comment\n" " return;\n" "}", @@ -25903,12 +25903,44 @@ TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) { "}", Style); - verifyFormat("if (quitelongarg !=\n" - "(alsolongarg - 1)) { // ABC is a very long " + verifyFormat("if (quiteLongArg !=\n" + "(alsoLongArg - 1)) { // ABC is a very long " "comment\n" " return;\n" "}", Style); + + verifyFormat("void foo() {\n" + " if (camelCaseName < alsoLongName ||\n" + " anotherEvenLongerName <=\n" + " thisReallyReallyReallyReallyReallyReallyLongerName ||" + "\n" + " otherName < thisLastName) {\n" + "return;\n" + " } else if (quiteLongName < alsoLongName ||\n" + " anotherEvenLongerName <=\n" + " thisReallyReallyReallyReallyReallyReallyLonger" + "Name ||\n" + " otherName < thisLastName) {\n" + "return;\n" + " }\n" + "}", + Style); + + Style.ContinuationIndentWidth = 2; + verifyFormat("void foo() {\n" + " if (ThisIsRatherALongIfClause && thatIExpectToBeBroken
[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From 80d04b253933496d6e6c016f09f0bb987f29b2d4 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 1/5] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 3d42571e82d8a0..bfd393eb033459 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5625,6 +5625,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ddeb1186d65ac8..4a23286c2b61a7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1079,6 +1079,8 @@ clang-format - Add ``ObjCPropertyAttributeOrder`` which can be used to sort ObjC property attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 8604dea689f937..c9f0617711157d 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4515,6 +4515,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4548,17 +4554,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index f798d555bf9929..97a457f2733ade 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -753,6 +753,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO , FormatStyle::SpacesInParensCustom ) { +IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers); IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements",
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/69340 >From b4c8809a948799be51a35b10e4d9d303b78a98db Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 9 Nov 2023 09:30:24 -0700 Subject: [PATCH 01/10] Revert "Revert "[clang-format] Fix align consecutive declarations over function pointers"" This reverts commit 7bc1031c474ebb2216a5432273dafe4d1490fbce. --- clang/lib/Format/WhitespaceManager.cpp | 2 +- clang/unittests/Format/FormatTest.cpp | 10 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 3bc6915b8df0a7..4bf4699756f77d 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -979,7 +979,7 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { -if (C.Tok->is(TT_FunctionDeclarationName)) +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) return false; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 25ef5c680af862..73ed6ee0f67bb2 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2050,6 +2050,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int \n" "const unsigned int \n" + "int*f1(int *a, int , int &);\n" + "double *(*f2)(int *a, double &);\n" "const unsigned&\n" "Const unsigned h;", Style); @@ -2095,6 +2097,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int* a, int& b, int&& c);\n" + "double* (*f2)(int* a, double&& b);\n" "const unsigned&&g;\n" "Const unsigned h;", Style); @@ -2120,6 +2124,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int *a, int& b, int&& c);\n" + "double *(*f2)(int *a, double&& b);\n" "const unsigned g;\n" "Const unsigned h;", Style); @@ -2160,6 +2166,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int & e;\n" "const unsigned int & f;\n" + "int* f1(int* a, int & b, int && c);\n" + "double* (*f2)(int* a, double && b);\n" "const unsigned &&g;\n" "Const unsigned h;", Style); @@ -2185,6 +2193,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int * d;\n" "Const unsigned int \n" "const unsigned int \n" + "int *f1(int * a, int , int &);\n" + "double * (*f2)(int * a, double &);\n" "const unsigned &\n" "Const unsigned h;", Style); >From e5bcaf5f1062ab8a6f800a6473e544f0505accfc Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH 02/10] Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 3 +++ clang/unittests/Format/FormatTest.cpp | 9 + 2 files changed, 12 insertions(+) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 4bf4699756f77d..d210d4cfb0c6a6 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -979,6 +979,9 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { +for
[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From 80d04b253933496d6e6c016f09f0bb987f29b2d4 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 1/4] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 3d42571e82d8a0..bfd393eb033459 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5625,6 +5625,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ddeb1186d65ac8..4a23286c2b61a7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1079,6 +1079,8 @@ clang-format - Add ``ObjCPropertyAttributeOrder`` which can be used to sort ObjC property attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 8604dea689f937..c9f0617711157d 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4515,6 +4515,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4548,17 +4554,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index f798d555bf9929..97a457f2733ade 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -753,6 +753,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO , FormatStyle::SpacesInParensCustom ) { +IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers); IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements",
[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)
https://github.com/gedare edited https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/77522 >From 80d04b253933496d6e6c016f09f0bb987f29b2d4 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH 1/2] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 3d42571e82d8a0..bfd393eb033459 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5625,6 +5625,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ddeb1186d65ac8..4a23286c2b61a7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1079,6 +1079,8 @@ clang-format - Add ``ObjCPropertyAttributeOrder`` which can be used to sort ObjC property attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 8604dea689f937..c9f0617711157d 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4515,6 +4515,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4548,17 +4554,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index f798d555bf9929..97a457f2733ade 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -753,6 +753,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO , FormatStyle::SpacesInParensCustom ) { +IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers); IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements",
[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)
gedare wrote: > This is migrated from Phabricator, see more discussion there. I will next > provide an option for SpacesInParensOptions.Doubled to control (and override) > injection of spaces within doubled parens `(( ))`. Actually, spaces in double parens might not work out well. It will not allow separation of multiple parens in some contexts such as conditional blocks or function calls. It may be better to provide a sub-option to this `InAttributeSpecifiers` instead. https://github.com/llvm/llvm-project/pull/77522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add SpaceInParensOption for __attribute__ keyword (PR #77522)
https://github.com/gedare created https://github.com/llvm/llvm-project/pull/77522 The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 This is migrated from Phabricator, see more discussion there. I will next provide an option for SpacesInParensOptions.Doubled to control (and override) injection of spaces within doubled parens `(( ))`. >From 80d04b253933496d6e6c016f09f0bb987f29b2d4 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Mon, 17 Jul 2023 18:24:30 -0600 Subject: [PATCH] Add SpaceInParensOption for __attribute__ keyword The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529 --- clang/docs/ClangFormatStyleOptions.rst | 7 +++ clang/docs/ReleaseNotes.rst| 2 ++ clang/include/clang/Format/Format.h| 19 ++- clang/lib/Format/Format.cpp| 2 ++ clang/lib/Format/TokenAnnotator.cpp| 16 clang/unittests/Format/ConfigParseTest.cpp | 13 + clang/unittests/Format/FormatTest.cpp | 7 +++ 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 3d42571e82d8a0..bfd393eb033459 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5625,6 +5625,13 @@ the configuration (without a prefix: ``Auto``). InConditionalStatements: true Other: true + * ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers. + +.. code-block:: c++ + + true: false: + __attribute__( ( noreturn ) )vs. __attribute__((noreturn)) + * ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements (``for/if/while/switch...``). diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ddeb1186d65ac8..4a23286c2b61a7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1079,6 +1079,8 @@ clang-format - Add ``ObjCPropertyAttributeOrder`` which can be used to sort ObjC property attributes (like ``nonatomic, strong, nullable``). - Add ``.clang-format-ignore`` files. +- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` + to control addition of spaces after the ``__attribute__`` keyword. libclang diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 8604dea689f937..c9f0617711157d 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4515,6 +4515,12 @@ struct FormatStyle { /// Other: true /// \endcode struct SpacesInParensCustom { +/// Put a space in parentheses of attribute specifiers. +/// \code +///true: false: +///__attribute__( ( noreturn ) )vs. __attribute__((noreturn)) +/// \endcode +bool InAttributeSpecifiers; /// Put a space in parentheses only inside conditional statements /// (``for/if/while/switch...``). /// \code @@ -4548,17 +4554,20 @@ struct FormatStyle { bool Other; SpacesInParensCustom() -: InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} +: InAttributeSpecifiers(false), InConditionalStatements(false), + InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} -SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, +SpacesInParensCustom(bool InAttributeSpecifiers, + bool InConditionalStatements, bool InCStyleCasts, bool InEmptyParentheses, bool Other) -: InConditionalStatements(InConditionalStatements), +: InAttributeSpecifiers(InAttributeSpecifiers), + InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), Other(Other) {} bool operator==(const SpacesInParensCustom ) const { - return InConditionalStatements == R.InConditionalStatements && + return InAttributeSpecifiers == R.InAttributeSpecifiers && + InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; }
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
gedare wrote: > Please also update the release notes. LGTM otherwise. Fixed the comments and added a release note. https://github.com/llvm/llvm-project/pull/69340 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/69340 >From b4c8809a948799be51a35b10e4d9d303b78a98db Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 9 Nov 2023 09:30:24 -0700 Subject: [PATCH 1/9] Revert "Revert "[clang-format] Fix align consecutive declarations over function pointers"" This reverts commit 7bc1031c474ebb2216a5432273dafe4d1490fbce. --- clang/lib/Format/WhitespaceManager.cpp | 2 +- clang/unittests/Format/FormatTest.cpp | 10 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 3bc6915b8df0a7..4bf4699756f77d 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -979,7 +979,7 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { -if (C.Tok->is(TT_FunctionDeclarationName)) +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) return false; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 25ef5c680af862..73ed6ee0f67bb2 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2050,6 +2050,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int \n" "const unsigned int \n" + "int*f1(int *a, int , int &);\n" + "double *(*f2)(int *a, double &);\n" "const unsigned&\n" "Const unsigned h;", Style); @@ -2095,6 +2097,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int* a, int& b, int&& c);\n" + "double* (*f2)(int* a, double&& b);\n" "const unsigned&&g;\n" "Const unsigned h;", Style); @@ -2120,6 +2124,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int *a, int& b, int&& c);\n" + "double *(*f2)(int *a, double&& b);\n" "const unsigned g;\n" "Const unsigned h;", Style); @@ -2160,6 +2166,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int & e;\n" "const unsigned int & f;\n" + "int* f1(int* a, int & b, int && c);\n" + "double* (*f2)(int* a, double && b);\n" "const unsigned &&g;\n" "Const unsigned h;", Style); @@ -2185,6 +2193,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int * d;\n" "Const unsigned int \n" "const unsigned int \n" + "int *f1(int * a, int , int &);\n" + "double * (*f2)(int * a, double &);\n" "const unsigned &\n" "Const unsigned h;", Style); >From e5bcaf5f1062ab8a6f800a6473e544f0505accfc Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH 2/9] Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 3 +++ clang/unittests/Format/FormatTest.cpp | 9 + 2 files changed, 12 insertions(+) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 4bf4699756f77d..d210d4cfb0c6a6 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -979,6 +979,9 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { +for
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
gedare wrote: > > @owenca this waits for re-review > > Can you rebase the patch? done https://github.com/llvm/llvm-project/pull/69340 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/69340 >From 65e3a69e30810683ba76d9a233a9c408fd121120 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 9 Nov 2023 09:30:24 -0700 Subject: [PATCH 1/7] Revert "Revert "[clang-format] Fix align consecutive declarations over function pointers"" This reverts commit 7bc1031c474ebb2216a5432273dafe4d1490fbce. --- clang/lib/Format/WhitespaceManager.cpp | 2 +- clang/unittests/Format/FormatTest.cpp | 10 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 3bc6915b8df0a7..4bf4699756f77d 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -979,7 +979,7 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { -if (C.Tok->is(TT_FunctionDeclarationName)) +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) return false; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 881993ede17c3d..5eef94332e21dd 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2050,6 +2050,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int \n" "const unsigned int \n" + "int*f1(int *a, int , int &);\n" + "double *(*f2)(int *a, double &);\n" "const unsigned&\n" "Const unsigned h;", Style); @@ -2095,6 +2097,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int* a, int& b, int&& c);\n" + "double* (*f2)(int* a, double&& b);\n" "const unsigned&&g;\n" "Const unsigned h;", Style); @@ -2120,6 +2124,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int *a, int& b, int&& c);\n" + "double *(*f2)(int *a, double&& b);\n" "const unsigned g;\n" "Const unsigned h;", Style); @@ -2160,6 +2166,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int & e;\n" "const unsigned int & f;\n" + "int* f1(int* a, int & b, int && c);\n" + "double* (*f2)(int* a, double && b);\n" "const unsigned &&g;\n" "Const unsigned h;", Style); @@ -2185,6 +2193,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int * d;\n" "Const unsigned int \n" "const unsigned int \n" + "int *f1(int * a, int , int &);\n" + "double * (*f2)(int * a, double &);\n" "const unsigned &\n" "Const unsigned h;", Style); >From 72a7b92bafcffad7e3664384fa27967b1e7bc8c0 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH 2/7] Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 3 +++ clang/unittests/Format/FormatTest.cpp | 9 + 2 files changed, 12 insertions(+) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 4bf4699756f77d..d210d4cfb0c6a6 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -979,6 +979,9 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { +for
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
gedare wrote: @owenca this waits for re-review https://github.com/llvm/llvm-project/pull/69340 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/69340 >From 610d0b544d7927af93b6943078df033f154b74f8 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 9 Nov 2023 09:30:24 -0700 Subject: [PATCH 1/7] Revert "Revert "[clang-format] Fix align consecutive declarations over function pointers"" This reverts commit 7bc1031c474ebb2216a5432273dafe4d1490fbce. --- clang/lib/Format/WhitespaceManager.cpp | 2 +- clang/unittests/Format/FormatTest.cpp | 10 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index ff8b1e6e13a3f7..d4d66f0a9b2ab9 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,7 +980,7 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { -if (C.Tok->is(TT_FunctionDeclarationName)) +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) return false; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 80903e7630c807..19de60a5a4031d 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2047,6 +2047,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int \n" "const unsigned int \n" + "int*f1(int *a, int , int &);\n" + "double *(*f2)(int *a, double &);\n" "const unsigned&\n" "Const unsigned h;", Style); @@ -2092,6 +2094,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int* a, int& b, int&& c);\n" + "double* (*f2)(int* a, double&& b);\n" "const unsigned&&g;\n" "Const unsigned h;", Style); @@ -2117,6 +2121,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int *a, int& b, int&& c);\n" + "double *(*f2)(int *a, double&& b);\n" "const unsigned g;\n" "Const unsigned h;", Style); @@ -2157,6 +2163,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int & e;\n" "const unsigned int & f;\n" + "int* f1(int* a, int & b, int && c);\n" + "double* (*f2)(int* a, double && b);\n" "const unsigned &&g;\n" "Const unsigned h;", Style); @@ -2182,6 +2190,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int * d;\n" "Const unsigned int \n" "const unsigned int \n" + "int *f1(int * a, int , int &);\n" + "double * (*f2)(int * a, double &);\n" "const unsigned &\n" "Const unsigned h;", Style); >From bb386b5e912686fb292fb0de89e124fa54076aa7 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH 2/7] Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 3 +++ clang/unittests/Format/FormatTest.cpp | 9 + 2 files changed, 12 insertions(+) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index d4d66f0a9b2ab9..294a87a6759212 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,6 +980,9 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { +for
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/69340 >From 610d0b544d7927af93b6943078df033f154b74f8 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 9 Nov 2023 09:30:24 -0700 Subject: [PATCH 1/6] Revert "Revert "[clang-format] Fix align consecutive declarations over function pointers"" This reverts commit 7bc1031c474ebb2216a5432273dafe4d1490fbce. --- clang/lib/Format/WhitespaceManager.cpp | 2 +- clang/unittests/Format/FormatTest.cpp | 10 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index ff8b1e6e13a3f7..d4d66f0a9b2ab9 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,7 +980,7 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { -if (C.Tok->is(TT_FunctionDeclarationName)) +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) return false; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 80903e7630c807..19de60a5a4031d 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2047,6 +2047,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int \n" "const unsigned int \n" + "int*f1(int *a, int , int &);\n" + "double *(*f2)(int *a, double &);\n" "const unsigned&\n" "Const unsigned h;", Style); @@ -2092,6 +2094,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int* a, int& b, int&& c);\n" + "double* (*f2)(int* a, double&& b);\n" "const unsigned&&g;\n" "Const unsigned h;", Style); @@ -2117,6 +2121,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int *a, int& b, int&& c);\n" + "double *(*f2)(int *a, double&& b);\n" "const unsigned g;\n" "Const unsigned h;", Style); @@ -2157,6 +2163,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int & e;\n" "const unsigned int & f;\n" + "int* f1(int* a, int & b, int && c);\n" + "double* (*f2)(int* a, double && b);\n" "const unsigned &&g;\n" "Const unsigned h;", Style); @@ -2182,6 +2190,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int * d;\n" "Const unsigned int \n" "const unsigned int \n" + "int *f1(int * a, int , int &);\n" + "double * (*f2)(int * a, double &);\n" "const unsigned &\n" "Const unsigned h;", Style); >From bb386b5e912686fb292fb0de89e124fa54076aa7 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH 2/6] Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 3 +++ clang/unittests/Format/FormatTest.cpp | 9 + 2 files changed, 12 insertions(+) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index d4d66f0a9b2ab9..294a87a6759212 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,6 +980,9 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { +for
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/69340 >From 610d0b544d7927af93b6943078df033f154b74f8 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 9 Nov 2023 09:30:24 -0700 Subject: [PATCH 1/5] Revert "Revert "[clang-format] Fix align consecutive declarations over function pointers"" This reverts commit 7bc1031c474ebb2216a5432273dafe4d1490fbce. --- clang/lib/Format/WhitespaceManager.cpp | 2 +- clang/unittests/Format/FormatTest.cpp | 10 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index ff8b1e6e13a3f7..d4d66f0a9b2ab9 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,7 +980,7 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { -if (C.Tok->is(TT_FunctionDeclarationName)) +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) return false; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 80903e7630c807..19de60a5a4031d 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2047,6 +2047,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int \n" "const unsigned int \n" + "int*f1(int *a, int , int &);\n" + "double *(*f2)(int *a, double &);\n" "const unsigned&\n" "Const unsigned h;", Style); @@ -2092,6 +2094,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int* a, int& b, int&& c);\n" + "double* (*f2)(int* a, double&& b);\n" "const unsigned&&g;\n" "Const unsigned h;", Style); @@ -2117,6 +2121,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int *a, int& b, int&& c);\n" + "double *(*f2)(int *a, double&& b);\n" "const unsigned g;\n" "Const unsigned h;", Style); @@ -2157,6 +2163,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int & e;\n" "const unsigned int & f;\n" + "int* f1(int* a, int & b, int && c);\n" + "double* (*f2)(int* a, double && b);\n" "const unsigned &&g;\n" "Const unsigned h;", Style); @@ -2182,6 +2190,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int * d;\n" "Const unsigned int \n" "const unsigned int \n" + "int *f1(int * a, int , int &);\n" + "double * (*f2)(int * a, double &);\n" "const unsigned &\n" "Const unsigned h;", Style); >From bb386b5e912686fb292fb0de89e124fa54076aa7 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH 2/5] Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 3 +++ clang/unittests/Format/FormatTest.cpp | 9 + 2 files changed, 12 insertions(+) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index d4d66f0a9b2ab9..294a87a6759212 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,6 +980,9 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { +for
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/69340 >From 610d0b544d7927af93b6943078df033f154b74f8 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 9 Nov 2023 09:30:24 -0700 Subject: [PATCH 1/4] Revert "Revert "[clang-format] Fix align consecutive declarations over function pointers"" This reverts commit 7bc1031c474ebb2216a5432273dafe4d1490fbce. --- clang/lib/Format/WhitespaceManager.cpp | 2 +- clang/unittests/Format/FormatTest.cpp | 10 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index ff8b1e6e13a3f7..d4d66f0a9b2ab9 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,7 +980,7 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { -if (C.Tok->is(TT_FunctionDeclarationName)) +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) return false; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 80903e7630c807..19de60a5a4031d 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2047,6 +2047,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int \n" "const unsigned int \n" + "int*f1(int *a, int , int &);\n" + "double *(*f2)(int *a, double &);\n" "const unsigned&\n" "Const unsigned h;", Style); @@ -2092,6 +2094,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int* a, int& b, int&& c);\n" + "double* (*f2)(int* a, double&& b);\n" "const unsigned&&g;\n" "Const unsigned h;", Style); @@ -2117,6 +2121,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int *a, int& b, int&& c);\n" + "double *(*f2)(int *a, double&& b);\n" "const unsigned g;\n" "Const unsigned h;", Style); @@ -2157,6 +2163,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int & e;\n" "const unsigned int & f;\n" + "int* f1(int* a, int & b, int && c);\n" + "double* (*f2)(int* a, double && b);\n" "const unsigned &&g;\n" "Const unsigned h;", Style); @@ -2182,6 +2190,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int * d;\n" "Const unsigned int \n" "const unsigned int \n" + "int *f1(int * a, int , int &);\n" + "double * (*f2)(int * a, double &);\n" "const unsigned &\n" "Const unsigned h;", Style); >From bb386b5e912686fb292fb0de89e124fa54076aa7 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH 2/4] Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 3 +++ clang/unittests/Format/FormatTest.cpp | 9 + 2 files changed, 12 insertions(+) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index d4d66f0a9b2ab9..294a87a6759212 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,6 +980,9 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { +for
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
gedare wrote: > See [#66857 > (comment)](https://github.com/llvm/llvm-project/issues/66857#issuecomment-1793022188). > Can you make this a suboption, e.g. `AlignFunctionPointers`? We can add > another (e.g. `AlignConstructorsDestructors`) for ctors and dtors in the > future. Yes, I will work on this. https://github.com/llvm/llvm-project/pull/69340 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/69340 >From 610d0b544d7927af93b6943078df033f154b74f8 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 9 Nov 2023 09:30:24 -0700 Subject: [PATCH 1/3] Revert "Revert "[clang-format] Fix align consecutive declarations over function pointers"" This reverts commit 7bc1031c474ebb2216a5432273dafe4d1490fbce. --- clang/lib/Format/WhitespaceManager.cpp | 2 +- clang/unittests/Format/FormatTest.cpp | 10 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index ff8b1e6e13a3f77..d4d66f0a9b2ab95 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,7 +980,7 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { -if (C.Tok->is(TT_FunctionDeclarationName)) +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) return false; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 80903e7630c8073..19de60a5a4031d0 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2047,6 +2047,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int \n" "const unsigned int \n" + "int*f1(int *a, int , int &);\n" + "double *(*f2)(int *a, double &);\n" "const unsigned&\n" "Const unsigned h;", Style); @@ -2092,6 +2094,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int* a, int& b, int&& c);\n" + "double* (*f2)(int* a, double&& b);\n" "const unsigned&&g;\n" "Const unsigned h;", Style); @@ -2117,6 +2121,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int *a, int& b, int&& c);\n" + "double *(*f2)(int *a, double&& b);\n" "const unsigned g;\n" "Const unsigned h;", Style); @@ -2157,6 +2163,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int & e;\n" "const unsigned int & f;\n" + "int* f1(int* a, int & b, int && c);\n" + "double* (*f2)(int* a, double && b);\n" "const unsigned &&g;\n" "Const unsigned h;", Style); @@ -2182,6 +2190,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int * d;\n" "Const unsigned int \n" "const unsigned int \n" + "int *f1(int * a, int , int &);\n" + "double * (*f2)(int * a, double &);\n" "const unsigned &\n" "Const unsigned h;", Style); >From bb386b5e912686fb292fb0de89e124fa54076aa7 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH 2/3] Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 3 +++ clang/unittests/Format/FormatTest.cpp | 9 + 2 files changed, 12 insertions(+) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index d4d66f0a9b2ab95..294a87a6759212c 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,6 +980,9 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { +
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
gedare wrote: force push was required to layer the revert commit correctly. https://github.com/llvm/llvm-project/pull/69340 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/69340 >From 610d0b544d7927af93b6943078df033f154b74f8 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Thu, 9 Nov 2023 09:30:24 -0700 Subject: [PATCH 1/2] Revert "Revert "[clang-format] Fix align consecutive declarations over function pointers"" This reverts commit 7bc1031c474ebb2216a5432273dafe4d1490fbce. --- clang/lib/Format/WhitespaceManager.cpp | 2 +- clang/unittests/Format/FormatTest.cpp | 10 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index ff8b1e6e13a3f77..d4d66f0a9b2ab95 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,7 +980,7 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { -if (C.Tok->is(TT_FunctionDeclarationName)) +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) return false; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 80903e7630c8073..19de60a5a4031d0 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2047,6 +2047,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int \n" "const unsigned int \n" + "int*f1(int *a, int , int &);\n" + "double *(*f2)(int *a, double &);\n" "const unsigned&\n" "Const unsigned h;", Style); @@ -2092,6 +2094,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int* a, int& b, int&& c);\n" + "double* (*f2)(int* a, double&& b);\n" "const unsigned&&g;\n" "Const unsigned h;", Style); @@ -2117,6 +2121,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int *d;\n" "Const unsigned int& e;\n" "const unsigned int& f;\n" + "int*f1(int *a, int& b, int&& c);\n" + "double *(*f2)(int *a, double&& b);\n" "const unsigned g;\n" "Const unsigned h;", Style); @@ -2157,6 +2163,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int* d;\n" "Const unsigned int & e;\n" "const unsigned int & f;\n" + "int* f1(int* a, int & b, int && c);\n" + "double* (*f2)(int* a, double && b);\n" "const unsigned &&g;\n" "Const unsigned h;", Style); @@ -2182,6 +2190,8 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) { "const unsigned int * d;\n" "Const unsigned int \n" "const unsigned int \n" + "int *f1(int * a, int , int &);\n" + "double * (*f2)(int * a, double &);\n" "const unsigned &\n" "Const unsigned h;", Style); >From bb386b5e912686fb292fb0de89e124fa54076aa7 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH 2/2] Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 3 +++ clang/unittests/Format/FormatTest.cpp | 9 + 2 files changed, 12 insertions(+) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index d4d66f0a9b2ab95..294a87a6759212c 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -980,6 +980,9 @@ void WhitespaceManager::alignConsecutiveDeclarations() { AlignTokens( Style, [](Change const ) { +
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/69340 >From c5d25f8de3de16ff3ed873446da017e9c26e0767 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH 1/3] [clang-format]: Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 43 -- clang/lib/Format/WhitespaceManager.h | 3 +- clang/unittests/Format/FormatTest.cpp | 9 ++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index dc81060671c1712..e6bc0963b40dc75 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -108,9 +108,10 @@ const tooling::Replacements ::generateReplacements() { calculateLineBreakInformation(); alignConsecutiveMacros(); alignConsecutiveShortCaseStatements(); - alignConsecutiveDeclarations(); + alignConsecutiveDeclarationsPreAssignment(); alignConsecutiveBitFields(); alignConsecutiveAssignments(); + alignConsecutiveDeclarationsPostAssignment(); alignChainedConditionals(); alignTrailingComments(); alignEscapedNewlines(); @@ -973,13 +974,51 @@ void WhitespaceManager::alignConsecutiveShortCaseStatements() { Changes); } -void WhitespaceManager::alignConsecutiveDeclarations() { +void WhitespaceManager::alignConsecutiveDeclarationsPreAssignment() { if (!Style.AlignConsecutiveDeclarations.Enabled) return; AlignTokens( Style, [](Change const ) { +for (FormatToken *Prev = C.Tok->Previous; Prev; Prev = Prev->Previous) + if (Prev->is(tok::equal)) +return false; +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) + return true; +if (C.Tok->isNot(TT_StartOfName)) + return false; +if (C.Tok->Previous && +C.Tok->Previous->is(TT_StatementAttributeLikeMacro)) + return false; +// Check if there is a subsequent name that starts the same declaration. +for (FormatToken *Next = C.Tok->Next; Next; Next = Next->Next) { + if (Next->is(tok::comment)) +continue; + if (Next->is(TT_PointerOrReference)) +return false; + if (!Next->Tok.getIdentifierInfo()) +break; + if (Next->isOneOf(TT_StartOfName, TT_FunctionDeclarationName, +tok::kw_operator)) { +return false; + } +} +return true; + }, + Changes, /*StartAt=*/0, Style.AlignConsecutiveDeclarations); +} + +void WhitespaceManager::alignConsecutiveDeclarationsPostAssignment() { + if (!Style.AlignConsecutiveDeclarations.Enabled) +return; + + AlignTokens( + Style, + [](Change const ) { +for (FormatToken *Next = C.Tok->Next; Next; Next = Next->Next) + if (Next->is(tok::equal)) +return false; if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h index df7e9add1cd446f..19bd4a3a6f7791f 100644 --- a/clang/lib/Format/WhitespaceManager.h +++ b/clang/lib/Format/WhitespaceManager.h @@ -227,7 +227,8 @@ class WhitespaceManager { void alignConsecutiveBitFields(); /// Align consecutive declarations over all \c Changes. - void alignConsecutiveDeclarations(); + void alignConsecutiveDeclarationsPreAssignment(); + void alignConsecutiveDeclarationsPostAssignment(); /// Align consecutive declarations over all \c Changes. void alignChainedConditionals(); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 963fb8f4d441618..1dc05ff9de5f0fa 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -18783,6 +18783,15 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { " \"bb\"};\n" "int bbb = 0;", Alignment); + // http://llvm.org/PR68079 + verifyFormat("using Fn = int (A::*)();\n" + "using RFn = int (A::*)() &;\n" +
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/69340 >From c5d25f8de3de16ff3ed873446da017e9c26e0767 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH 1/2] [clang-format]: Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 43 -- clang/lib/Format/WhitespaceManager.h | 3 +- clang/unittests/Format/FormatTest.cpp | 9 ++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index dc81060671c1712..e6bc0963b40dc75 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -108,9 +108,10 @@ const tooling::Replacements ::generateReplacements() { calculateLineBreakInformation(); alignConsecutiveMacros(); alignConsecutiveShortCaseStatements(); - alignConsecutiveDeclarations(); + alignConsecutiveDeclarationsPreAssignment(); alignConsecutiveBitFields(); alignConsecutiveAssignments(); + alignConsecutiveDeclarationsPostAssignment(); alignChainedConditionals(); alignTrailingComments(); alignEscapedNewlines(); @@ -973,13 +974,51 @@ void WhitespaceManager::alignConsecutiveShortCaseStatements() { Changes); } -void WhitespaceManager::alignConsecutiveDeclarations() { +void WhitespaceManager::alignConsecutiveDeclarationsPreAssignment() { if (!Style.AlignConsecutiveDeclarations.Enabled) return; AlignTokens( Style, [](Change const ) { +for (FormatToken *Prev = C.Tok->Previous; Prev; Prev = Prev->Previous) + if (Prev->is(tok::equal)) +return false; +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) + return true; +if (C.Tok->isNot(TT_StartOfName)) + return false; +if (C.Tok->Previous && +C.Tok->Previous->is(TT_StatementAttributeLikeMacro)) + return false; +// Check if there is a subsequent name that starts the same declaration. +for (FormatToken *Next = C.Tok->Next; Next; Next = Next->Next) { + if (Next->is(tok::comment)) +continue; + if (Next->is(TT_PointerOrReference)) +return false; + if (!Next->Tok.getIdentifierInfo()) +break; + if (Next->isOneOf(TT_StartOfName, TT_FunctionDeclarationName, +tok::kw_operator)) { +return false; + } +} +return true; + }, + Changes, /*StartAt=*/0, Style.AlignConsecutiveDeclarations); +} + +void WhitespaceManager::alignConsecutiveDeclarationsPostAssignment() { + if (!Style.AlignConsecutiveDeclarations.Enabled) +return; + + AlignTokens( + Style, + [](Change const ) { +for (FormatToken *Next = C.Tok->Next; Next; Next = Next->Next) + if (Next->is(tok::equal)) +return false; if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h index df7e9add1cd446f..19bd4a3a6f7791f 100644 --- a/clang/lib/Format/WhitespaceManager.h +++ b/clang/lib/Format/WhitespaceManager.h @@ -227,7 +227,8 @@ class WhitespaceManager { void alignConsecutiveBitFields(); /// Align consecutive declarations over all \c Changes. - void alignConsecutiveDeclarations(); + void alignConsecutiveDeclarationsPreAssignment(); + void alignConsecutiveDeclarationsPostAssignment(); /// Align consecutive declarations over all \c Changes. void alignChainedConditionals(); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 963fb8f4d441618..1dc05ff9de5f0fa 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -18783,6 +18783,15 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { " \"bb\"};\n" "int bbb = 0;", Alignment); + // http://llvm.org/PR68079 + verifyFormat("using Fn = int (A::*)();\n" + "using RFn = int (A::*)() &;\n" +
[clang] [clang-format]: Split alignment of declarations around assignment (PR #69340)
https://github.com/gedare created https://github.com/llvm/llvm-project/pull/69340 Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. >From c5d25f8de3de16ff3ed873446da017e9c26e0767 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 17 Oct 2023 08:21:55 -0600 Subject: [PATCH] [clang-format]: Split alignment of declarations around assignment Function pointers are detected as a type of declaration using FunctionTypeLParen. They are aligned based on rules for AlignConsecutiveDeclarations. When a function pointer is on the right-hand side of an assignment, the alignment of the function pointer can result in excessive whitespace padding due to the ordering of alignment, as the alignment processes a line from left-to-right and first aligns the declarations before and after the assignment operator, and then aligns the assignment operator. Injection of whitespace by alignment of declarations after the equal sign followed by alignment of the equal sign results in the excessive whitespace. Fixes #68079. --- clang/lib/Format/WhitespaceManager.cpp | 43 -- clang/lib/Format/WhitespaceManager.h | 3 +- clang/unittests/Format/FormatTest.cpp | 9 ++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index dc81060671c1712..e6bc0963b40dc75 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -108,9 +108,10 @@ const tooling::Replacements ::generateReplacements() { calculateLineBreakInformation(); alignConsecutiveMacros(); alignConsecutiveShortCaseStatements(); - alignConsecutiveDeclarations(); + alignConsecutiveDeclarationsPreAssignment(); alignConsecutiveBitFields(); alignConsecutiveAssignments(); + alignConsecutiveDeclarationsPostAssignment(); alignChainedConditionals(); alignTrailingComments(); alignEscapedNewlines(); @@ -973,13 +974,51 @@ void WhitespaceManager::alignConsecutiveShortCaseStatements() { Changes); } -void WhitespaceManager::alignConsecutiveDeclarations() { +void WhitespaceManager::alignConsecutiveDeclarationsPreAssignment() { if (!Style.AlignConsecutiveDeclarations.Enabled) return; AlignTokens( Style, [](Change const ) { +for (FormatToken *Prev = C.Tok->Previous; Prev; Prev = Prev->Previous) + if (Prev->is(tok::equal)) +return false; +if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) + return true; +if (C.Tok->isNot(TT_StartOfName)) + return false; +if (C.Tok->Previous && +C.Tok->Previous->is(TT_StatementAttributeLikeMacro)) + return false; +// Check if there is a subsequent name that starts the same declaration. +for (FormatToken *Next = C.Tok->Next; Next; Next = Next->Next) { + if (Next->is(tok::comment)) +continue; + if (Next->is(TT_PointerOrReference)) +return false; + if (!Next->Tok.getIdentifierInfo()) +break; + if (Next->isOneOf(TT_StartOfName, TT_FunctionDeclarationName, +tok::kw_operator)) { +return false; + } +} +return true; + }, + Changes, /*StartAt=*/0, Style.AlignConsecutiveDeclarations); +} + +void WhitespaceManager::alignConsecutiveDeclarationsPostAssignment() { + if (!Style.AlignConsecutiveDeclarations.Enabled) +return; + + AlignTokens( + Style, + [](Change const ) { +for (FormatToken *Next = C.Tok->Next; Next; Next = Next->Next) + if (Next->is(tok::equal)) +return false; if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen)) return true; if (C.Tok->isNot(TT_StartOfName)) diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h index df7e9add1cd446f..19bd4a3a6f7791f 100644 --- a/clang/lib/Format/WhitespaceManager.h +++ b/clang/lib/Format/WhitespaceManager.h @@ -227,7 +227,8 @@ class WhitespaceManager { void alignConsecutiveBitFields(); /// Align consecutive declarations over all \c Changes. - void alignConsecutiveDeclarations(); + void alignConsecutiveDeclarationsPreAssignment(); + void