[clang] [clang-format] Handle generic selections inside parentheses (PR #79785)

via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 28 21:47:21 PST 2024


https://github.com/sstwcw created https://github.com/llvm/llvm-project/pull/79785

new

```C
while (_Generic(x, //
           long: x)(x) > x) {
}
while (_Generic(x, //
           long: x)(x)) {
}
```

old

```C
while (_Generic(x, //
       long: x)(x) > x) {
}
while (_Generic(x, //
    long: x)(x)) {
}
```

In the first case above, the second line previously aligned to the open parenthesis.  The 4 spaces did not get added by the fallback line near the end of getNewLineColumn because there was already some indentaton. Now the spaces get added explicitly.

In the second case above, without the fake parentheses, the second line did not respect the outer parentheses.  Because the LastSpace field did not get set without the fake parentheses.  Now the indentation of the outer level is used instead.

>From bf4685e1ebbca1be7258e8fa41a0f5f90fa1e152 Mon Sep 17 00:00:00 2001
From: sstwcw <su3e8a96kzlver at posteo.net>
Date: Mon, 29 Jan 2024 05:24:51 +0000
Subject: [PATCH] [clang-format] Handle generic selections inside parentheses

new

```C
while (_Generic(x, //
           long: x)(x) > x) {
}
while (_Generic(x, //
           long: x)(x)) {
}
```

old

```C
while (_Generic(x, //
       long: x)(x) > x) {
}
while (_Generic(x, //
    long: x)(x)) {
}
```

In the first case above, the second line previously aligned to the open
parenthesis.  The 4 spaces did not get added by the fallback line near
the end of getNewLineColumn because there was already some indentaton.
Now the spaces get added explicitly.

In the second case above, without the fake parentheses, the second line
did not respect the outer parentheses.  Because the LastSpace field did
not get set without the fake parentheses.  Now the indentation of the
outer level is used instead.
---
 clang/lib/Format/ContinuationIndenter.cpp | 7 +++++--
 clang/unittests/Format/FormatTest.cpp     | 9 +++++++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index a3eb9138b21833..a1c5a297c67c13 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -1694,8 +1694,11 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
     // Special case for generic selection expressions, its comma-separated
     // expressions are not aligned to the opening paren like regular calls, but
     // rather continuation-indented relative to the _Generic keyword.
-    if (Previous && Previous->endsSequence(tok::l_paren, tok::kw__Generic))
-      NewParenState.Indent = CurrentState.LastSpace;
+    if (Previous && Previous->endsSequence(tok::l_paren, tok::kw__Generic) &&
+        State.Stack.size() >= 2) {
+      NewParenState.Indent =
+          State.Stack.end()[-2].Indent + Style.ContinuationIndentWidth;
+    }
 
     if ((shouldUnindentNextOperator(Current) ||
          (Previous &&
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index e5e763edf5b5bf..c066107bebdd73 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24111,6 +24111,15 @@ TEST_F(FormatTest, C11Generic) {
                "    double _Complex: dc,\n"
                "    long double _Complex: ldc)");
 
+  verifyFormat("while (_Generic(x, //\n"
+               "           long: x)(x) > x) {\n"
+               "}");
+  verifyFormat("while (_Generic(x, //\n"
+               "           long: x)(x)) {\n"
+               "}");
+  verifyFormat("x(_Generic(x, //\n"
+               "      long: x)(x));");
+
   FormatStyle Style = getLLVMStyle();
   Style.ColumnLimit = 40;
   verifyFormat("#define LIMIT_MAX(T)                   \\\n"



More information about the cfe-commits mailing list