https://github.com/gedare updated https://github.com/llvm/llvm-project/pull/201703
>From a58b160f6dabdf02515b46d5faca98173ee45fbb Mon Sep 17 00:00:00 2001 From: Gedare Bloom <[email protected]> Date: Thu, 4 Jun 2026 15:39:06 -0600 Subject: [PATCH 1/5] [clang-format] annotate inline assembly parens Annotate the opening and closing parens of inline assembly. This will make other improvements related to inline assembly easier. --- clang/lib/Format/FormatToken.h | 1 + clang/lib/Format/TokenAnnotator.cpp | 2 + clang/lib/Format/UnwrappedLineParser.cpp | 38 +++++++++++++++---- clang/unittests/Format/TokenAnnotatorTest.cpp | 12 ++++++ 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 556bb0f3dd0af..ed9ce435ea765 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -99,6 +99,7 @@ namespace format { TYPE(InheritanceComma) \ TYPE(InlineASMBrace) \ TYPE(InlineASMColon) \ + TYPE(InlineASMParen) \ TYPE(InlineASMSymbolicNameLSquare) \ TYPE(JavaAnnotation) \ TYPE(JsAndAndEqual) \ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index c47a512454476..f211325a3b249 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2536,6 +2536,8 @@ class AnnotatingParser { } else if (Current.is(tok::r_paren)) { if (rParenEndsCast(Current)) Current.setType(TT_CastRParen); + if (Current.MatchingParen && Current.MatchingParen->is(TT_InlineASMParen)) + Current.setType(TT_InlineASMParen); if (Current.MatchingParen && Current.Next && !Current.Next->isBinaryOperator() && Current.Next->isNoneOf( diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index c83e82674dee1..92231e1598a12 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1508,23 +1508,47 @@ void UnwrappedLineParser::parseStructuralElement( return; } switch (FormatTok->Tok.getKind()) { - case tok::kw_asm: + case tok::kw_asm: { + bool DoNotFormat = false; + tok::TokenKind OpenType; + tok::TokenKind CloseType; nextToken(); - if (FormatTok->is(tok::l_brace)) { + while (FormatTok && + FormatTok->isOneOf(tok::kw_volatile, tok::kw_inline, tok::kw_goto)) { + nextToken(); + } + if (FormatTok && FormatTok->is(tok::l_brace)) { FormatTok->setFinalizedType(TT_InlineASMBrace); + OpenType = tok::l_brace; + CloseType = tok::r_brace; + DoNotFormat = true; + } else if (FormatTok && FormatTok->is(tok::l_paren)) { + OpenType = tok::l_paren; + CloseType = tok::r_paren; + FormatTok->setFinalizedType(TT_InlineASMParen); + } + if (DoNotFormat) { + FormatToken *OpenTok = FormatTok; + int NestLevel = 0; nextToken(); while (FormatTok && !eof()) { - if (FormatTok->is(tok::r_brace)) { - FormatTok->setFinalizedType(TT_InlineASMBrace); - nextToken(); - addUnwrappedLine(); - break; + if (FormatTok->is(OpenType)) { + ++NestLevel; + } else if (FormatTok->is(CloseType)) { + --NestLevel; + if (NestLevel < 1) { + FormatTok->setFinalizedType(OpenTok->getType()); + nextToken(); + addUnwrappedLine(); + break; + } } FormatTok->Finalized = true; nextToken(); } } break; + } case tok::kw_namespace: parseNamespace(); return; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 34106489d7f38..398c308d245ae 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1930,9 +1930,11 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { ":);"); ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_InlineASMParen); 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_paren, TT_InlineASMParen); Tokens = annotate("asm volatile (\n" "\"a_label:\"\n" @@ -1941,9 +1943,11 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { ":);"); ASSERT_EQ(Tokens.size(), 11u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_InlineASMParen); EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_InlineASMParen); Tokens = annotate("__asm__(\n" "\"a_label:\"\n" @@ -1952,9 +1956,11 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { ": y);"); ASSERT_EQ(Tokens.size(), 11u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_InlineASMParen); EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_InlineASMParen); Tokens = annotate("__asm volatile (\n" "\"a_label:\"\n" @@ -1964,9 +1970,11 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { ":);"); ASSERT_EQ(Tokens.size(), 12u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_InlineASMParen); EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[8], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_InlineASMParen); Tokens = annotate("asm(\n" "\"insn\"\n" @@ -1975,9 +1983,11 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { ": \"memory\");"); ASSERT_EQ(Tokens.size(), 19u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_InlineASMParen); EXPECT_TOKEN(Tokens[3], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[13], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[14], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[16], tok::r_paren, TT_InlineASMParen); Tokens = annotate("__asm__ volatile (\n" "\"ldr r1, [r0, %%[sym]]\"\n" @@ -1986,9 +1996,11 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { ");"); ASSERT_EQ(Tokens.size(), 21u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_InlineASMParen); EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[6], tok::l_square, TT_InlineASMSymbolicNameLSquare); + EXPECT_TOKEN(Tokens[18], tok::r_paren, TT_InlineASMParen); } TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) { >From 42fd2fb6ef6483b7a434d1655493c8e5131d2a18 Mon Sep 17 00:00:00 2001 From: Gedare Bloom <[email protected]> Date: Fri, 5 Jun 2026 11:22:24 -0600 Subject: [PATCH 2/5] Add annotation tests for asm qualifiers --- clang/unittests/Format/TokenAnnotatorTest.cpp | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 398c308d245ae..a178222d80eb2 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -2001,6 +2001,51 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[6], tok::l_square, TT_InlineASMSymbolicNameLSquare); EXPECT_TOKEN(Tokens[18], tok::r_paren, TT_InlineASMParen); + + Tokens = annotate("__asm__ inline (\n" + "\"ldr r1, [r0, %%[sym]]\"\n" + ":\n" + ": [sym] \"J\" (aaaaa(aaaa, aaaa))\n" + ");"); + ASSERT_EQ(Tokens.size(), 21u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_InlineASMParen); + EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::l_square, TT_InlineASMSymbolicNameLSquare); + EXPECT_TOKEN(Tokens[18], tok::r_paren, TT_InlineASMParen); + + Tokens = annotate("asm goto (\n" + "\"btl %1, %0\\n\\t\" \"jc %l2\"\n" + ":\n" + ": \"r\"(a), \"r\"(b)\n" + ": \"cc\"\n" + ": carry\n" + ");"); + ASSERT_EQ(Tokens.size(), 23u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_InlineASMParen); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[16], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[18], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[20], tok::r_paren, TT_InlineASMParen); + + Tokens = annotate("__asm__ volatile inline goto (\n" + "\"btl %1, %0\\n\\t\" \"jc %l2\"\n" + ":\n" + ": \"r\"(a), \"r\"(b)\n" + ": \"cc\"\n" + ": carry\n" + ");"); + ASSERT_EQ(Tokens.size(), 25u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_InlineASMParen); + EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[8], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[18], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[20], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[22], tok::r_paren, TT_InlineASMParen); } TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) { >From d70c52e84cabdf1db17ac182857d095a97f3a011 Mon Sep 17 00:00:00 2001 From: Gedare Bloom <[email protected]> Date: Fri, 5 Jun 2026 11:25:01 -0600 Subject: [PATCH 3/5] Simplify logic for NULL condition --- clang/lib/Format/UnwrappedLineParser.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 92231e1598a12..354e518926653 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1517,12 +1517,14 @@ void UnwrappedLineParser::parseStructuralElement( FormatTok->isOneOf(tok::kw_volatile, tok::kw_inline, tok::kw_goto)) { nextToken(); } - if (FormatTok && FormatTok->is(tok::l_brace)) { + if (!FormatTok) + break; + if (FormatTok->is(tok::l_brace)) { FormatTok->setFinalizedType(TT_InlineASMBrace); OpenType = tok::l_brace; CloseType = tok::r_brace; DoNotFormat = true; - } else if (FormatTok && FormatTok->is(tok::l_paren)) { + } else if (FormatTok->is(tok::l_paren)) { OpenType = tok::l_paren; CloseType = tok::r_paren; FormatTok->setFinalizedType(TT_InlineASMParen); >From a978ad2957b0bff1fcc8c7c26a56bcf275f8a345 Mon Sep 17 00:00:00 2001 From: Gedare Bloom <[email protected]> Date: Fri, 5 Jun 2026 16:22:20 -0600 Subject: [PATCH 4/5] Updates from review comments --- clang/lib/Format/UnwrappedLineParser.cpp | 5 +++ clang/unittests/Format/TokenAnnotatorTest.cpp | 45 +++---------------- 2 files changed, 10 insertions(+), 40 deletions(-) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 354e518926653..79ab2d460d295 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1509,6 +1509,9 @@ void UnwrappedLineParser::parseStructuralElement( } switch (FormatTok->Tok.getKind()) { case tok::kw_asm: { + // Track whether to skip formatting the inline asm block with a variable. + // Formatting is skipped for any asm blocks inside of braces by default. + // A style option could be added to also skip formatting inside parens. bool DoNotFormat = false; tok::TokenKind OpenType; tok::TokenKind CloseType; @@ -1528,6 +1531,8 @@ void UnwrappedLineParser::parseStructuralElement( OpenType = tok::l_paren; CloseType = tok::r_paren; FormatTok->setFinalizedType(TT_InlineASMParen); + } else { + break; } if (DoNotFormat) { FormatToken *OpenTok = FormatTok; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index a178222d80eb2..3ec74c7e705b4 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -2002,50 +2002,15 @@ TEST_F(TokenAnnotatorTest, UnderstandsAsm) { EXPECT_TOKEN(Tokens[6], tok::l_square, TT_InlineASMSymbolicNameLSquare); EXPECT_TOKEN(Tokens[18], tok::r_paren, TT_InlineASMParen); - Tokens = annotate("__asm__ inline (\n" - "\"ldr r1, [r0, %%[sym]]\"\n" - ":\n" - ": [sym] \"J\" (aaaaa(aaaa, aaaa))\n" - ");"); - ASSERT_EQ(Tokens.size(), 21u) << Tokens; - EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); - EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_InlineASMParen); - EXPECT_TOKEN(Tokens[4], tok::colon, TT_InlineASMColon); - EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); - EXPECT_TOKEN(Tokens[6], tok::l_square, TT_InlineASMSymbolicNameLSquare); - EXPECT_TOKEN(Tokens[18], tok::r_paren, TT_InlineASMParen); - - Tokens = annotate("asm goto (\n" - "\"btl %1, %0\\n\\t\" \"jc %l2\"\n" - ":\n" - ": \"r\"(a), \"r\"(b)\n" - ": \"cc\"\n" - ": carry\n" - ");"); - ASSERT_EQ(Tokens.size(), 23u) << Tokens; - EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); - EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_InlineASMParen); - EXPECT_TOKEN(Tokens[5], tok::colon, TT_InlineASMColon); - EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); - EXPECT_TOKEN(Tokens[16], tok::colon, TT_InlineASMColon); - EXPECT_TOKEN(Tokens[18], tok::colon, TT_InlineASMColon); - EXPECT_TOKEN(Tokens[20], tok::r_paren, TT_InlineASMParen); - - Tokens = annotate("__asm__ volatile inline goto (\n" - "\"btl %1, %0\\n\\t\" \"jc %l2\"\n" - ":\n" - ": \"r\"(a), \"r\"(b)\n" - ": \"cc\"\n" - ": carry\n" - ");"); - ASSERT_EQ(Tokens.size(), 25u) << Tokens; + Tokens = annotate("__asm__ volatile inline goto (\"nop\" : : : : l );"); + ASSERT_EQ(Tokens.size(), 14u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown); EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_InlineASMParen); + EXPECT_TOKEN(Tokens[6], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[7], tok::colon, TT_InlineASMColon); EXPECT_TOKEN(Tokens[8], tok::colon, TT_InlineASMColon); - EXPECT_TOKEN(Tokens[18], tok::colon, TT_InlineASMColon); - EXPECT_TOKEN(Tokens[20], tok::colon, TT_InlineASMColon); - EXPECT_TOKEN(Tokens[22], tok::r_paren, TT_InlineASMParen); + EXPECT_TOKEN(Tokens[9], tok::colon, TT_InlineASMColon); + EXPECT_TOKEN(Tokens[11], tok::r_paren, TT_InlineASMParen); } TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) { >From bf324fe218d21caacc0e4247fb7ea111ebe8dadc Mon Sep 17 00:00:00 2001 From: Gedare Bloom <[email protected]> Date: Mon, 8 Jun 2026 10:56:18 -0600 Subject: [PATCH 5/5] UnwrappedLineParser: comment on finalizing type --- clang/lib/Format/UnwrappedLineParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 79ab2d460d295..bf8320f6f51a4 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1509,8 +1509,8 @@ void UnwrappedLineParser::parseStructuralElement( } switch (FormatTok->Tok.getKind()) { case tok::kw_asm: { - // Track whether to skip formatting the inline asm block with a variable. - // Formatting is skipped for any asm blocks inside of braces by default. + // Track whether to skip formatting inline asm by finalizing the tokens + // in the block. Formatting is skipped inside of braces by default. // A style option could be added to also skip formatting inside parens. bool DoNotFormat = false; tok::TokenKind OpenType; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
