Skip to content

Conversation

rymiel
Copy link
Member

@rymiel rymiel commented Sep 5, 2023

When encountering braces, such as those of a designated initializer, clang-format scans ahead to see what is contained within the braces. If it found a statement, like an if-statement of for-loop, it would deem the braces as not an initializer, but as a block instead.

However, this heuristic incorrectly included a preprocessor #if line as an if-statement. This manifested in strange results and discrepancies between #ifdef and #if defined.

With this patch, if is now ignored if it is preceeded by #.

Fixes most of #56685

When encountering braces, such as those of a designated initializer,
clang-format scans ahead to see what is contained within the braces. If
it found a statement, like an if-statement of for-loop, it would deem
the braces as not an initializer, but as a block instead.

However, this heuristic incorrectly included a preprocessor `#if` line as
an if-statement. This manifested in strange results and discrepancies
between `#ifdef` and `#if defined`.

With this patch, `if` is now ignored if it is preceeded by `#`.

Fixes most of llvm#56685
Comment on lines 629 to 630
if (PrevTok->is(tok::hash))
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be applied to kw_if only, right? So something like the following instead?

    case tok::identifier:
      if (Tok->isNot(TT_StatementMacro))
        break;
      [[fallthrough]];
    case tok::kw_if:
      if (PrevTok->is(tok::hash))
        break;
      [[fallthrough]];
    case tok::at:
    case tok::semi:
    case tok::kw_while:
    case tok::kw_for:
    case tok::kw_switch:
    case tok::kw_try:
    case tok::kw___try:
      if (!LBraceStack.empty() && LBraceStack.back().Tok->is(BK_Unknown))
        LBraceStack.back().Tok->setBlockKind(BK_Block);
      break;

Comment on lines 2014 to 2017
"#ifdef FOO\n"
" .a = 1,\n"
"#endif\n"
" .b = 2\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not clang-formatted.

Comment on lines 2025 to 2029
"#if defined FOO\n"
" .a = 1,\n"
"#endif\n"
" .b = 2\n"
"};");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

@rymiel rymiel merged commit e9ed1aa into llvm:main Sep 7, 2023
@rymiel rymiel deleted the clang-format/hash-if-initializer branch September 7, 2023 19:23
rymiel added a commit to rymiel/llvm-project that referenced this pull request Oct 18, 2023
Pull request llvm#65409 changed the brace kind heuristic to not treat a
preprocessor if directive as a in statement, however, this caused some
regressions.

If the contents of a brace don't immediately determine the brace kind,
the heuristic will look at the characters immediately before and after
the closing brace to determine the brace type.

Unfortunately, if the closing brace was preceded by a preprocessor
directive, for example `#endif`, the preceding token was `endif`, seen
as just an identifier, so the braces were understood as a braced list.

This patch fixes this behaviour by skipping all preprocessor directives
when calculating brace types. Comments were already being skipped, so
now preprocessor lines are skipped alongside comments.

Fixes llvm#68404
rymiel added a commit that referenced this pull request Nov 3, 2023
Pull request #65409 changed the brace kind heuristic to not treat a
preprocessor if directive as a in statement, however, this caused some
regressions.

If the contents of a brace don't immediately determine the brace kind,
the heuristic will look at the characters immediately before and after
the closing brace to determine the brace type.

Unfortunately, if the closing brace was preceded by a preprocessor
directive, for example `#endif`, the preceding token was `endif`, seen
as just an identifier, so the braces were understood as a braced list.

This patch fixes this behaviour by skipping all preprocessor directives
when calculating brace types. Comments were already being skipped, so
now preprocessor lines are skipped alongside comments.

Fixes #68404
aarongable pushed a commit to chromium/chromium that referenced this pull request Feb 14, 2024
LLVM pull no. 65409 [1] has largely fixed the underlying issue. In
addition, MTECheckedPtr has been fully removed (crbug.com/40233676), no
longer necessitating interspersing preprocessor gates with designated
initializers. `git cl format` no longer does anything unexpected in
these particular blocks.

[1]: llvm/llvm-project#65409

Fixed: 40854198
Change-Id: Icd36b3dbb5cac24b7aacf63916e91ac5b9e125ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5294696
Auto-Submit: Kalvin Lee <[email protected]>
Commit-Queue: Keishi Hattori <[email protected]>
Reviewed-by: Keishi Hattori <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1260289}
github-actions bot pushed a commit to kaidokert/chrome_base_mirror that referenced this pull request Feb 15, 2024
LLVM pull no. 65409 [1] has largely fixed the underlying issue. In
addition, MTECheckedPtr has been fully removed (crbug.com/40233676), no
longer necessitating interspersing preprocessor gates with designated
initializers. `git cl format` no longer does anything unexpected in
these particular blocks.

[1]: llvm/llvm-project#65409

Fixed: 40854198
Change-Id: Icd36b3dbb5cac24b7aacf63916e91ac5b9e125ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5294696
Auto-Submit: Kalvin Lee <[email protected]>
Commit-Queue: Keishi Hattori <[email protected]>
Reviewed-by: Keishi Hattori <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1260289}
NOKEYCHECK=True
GitOrigin-RevId: fd0b9c3bbf560d709b3ebcd443efec8cc73afc68
jrguzman-ms pushed a commit to msft-mirror-aosp/platform.external.libchrome that referenced this pull request Feb 15, 2024
LLVM pull no. 65409 [1] has largely fixed the underlying issue. In
addition, MTECheckedPtr has been fully removed (crbug.com/40233676), no
longer necessitating interspersing preprocessor gates with designated
initializers. `git cl format` no longer does anything unexpected in
these particular blocks.

[1]: llvm/llvm-project#65409

Fixed: 40854198
Change-Id: Icd36b3dbb5cac24b7aacf63916e91ac5b9e125ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5294696
Auto-Submit: Kalvin Lee <[email protected]>
Commit-Queue: Keishi Hattori <[email protected]>
Reviewed-by: Keishi Hattori <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1260289}


CrOS-Libchrome-Original-Commit: fd0b9c3bbf560d709b3ebcd443efec8cc73afc68
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants