[clang] [clang-format] Don't skip stringizing when determining brace kind (PR #73886)

Emilia Kond via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 29 17:44:19 PST 2023


https://github.com/rymiel created https://github.com/llvm/llvm-project/pull/73886

PR #69473 introduced skipping PP directives when determining the brace kind of an lbrace. However, it did so by skipping to the end of the line when encountering a hash character. This means it also skipped to the end of line when encountering a macro stringizing operator, which, unlike PP directives, don't have effect until the end of line.

This led to cases where the rbrace could be completely skipped if it was on the same line as a stringizing operator.

This patch skips hash characters if we're already in a PP directive, as you can't define a macro inside of a macro

Fixes https://github.com/llvm/llvm-project/issues/72662

>From 95e2a2ee5d901d79430cb9b9468e1af8215b334f Mon Sep 17 00:00:00 2001
From: Emilia Kond <emilia at rymiel.space>
Date: Thu, 30 Nov 2023 03:30:48 +0200
Subject: [PATCH] [clang-format] Don't skip stringizing when determining brace
 kind

PR #69473 introduced skipping PP directives when determining the brace
kind of an lbrace. However, it did so by skipping to the end of the line
when encountering a hash character. This means it also skipped to the
end of line when encountering a macro stringizing operator, which, unlike
PP directives, don't have effect until the end of line.

This led to cases where the rbrace could be completely skipped if it was
on the same line as a stringizing operator.

This patch skips hash characters if we're already in a PP directive, as
you can't define a macro inside of a macro

Fixes https://github.com/llvm/llvm-project/issues/72662
---
 clang/lib/Format/UnwrappedLineParser.cpp      |  2 +-
 clang/unittests/Format/TokenAnnotatorTest.cpp | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index a5a4419b98239e6..5f574dfeafc874b 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -496,7 +496,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
     do {
       NextTok = Tokens->getNextToken();
     } while (NextTok->is(tok::comment));
-    while (NextTok->is(tok::hash)) {
+    while (NextTok->is(tok::hash) && !Line->InPPDirective) {
       NextTok = Tokens->getNextToken();
       do {
         NextTok = Tokens->getNextToken();
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index bc734573ce0cb4d..8ad6a585d004593 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -1851,6 +1851,22 @@ TEST_F(TokenAnnotatorTest, UnderstandsTrailingReturnArrow) {
   EXPECT_TOKEN(Tokens[13], tok::arrow, TT_Unknown);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandHashInMacro) {
+  auto Tokens = annotate("#define Foo(Bar) \\\n"
+                         "  { \\\n"
+                         "    #Bar \\\n"
+                         "  }\n");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_BRACE_KIND(Tokens[6], BK_Block);
+  EXPECT_BRACE_KIND(Tokens[9], BK_Block);
+
+  Tokens = annotate("#define Foo(Bar) \\\n"
+                    "  { #Bar }\n");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_BRACE_KIND(Tokens[6], BK_Block);
+  EXPECT_BRACE_KIND(Tokens[9], BK_Block);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacros) {
   // '__attribute__' has special handling.
   auto Tokens = annotate("__attribute__(X) void Foo(void);");



More information about the cfe-commits mailing list