This is an archive of the discontinued LLVM Phabricator instance.

[clang-format] Add an option to insert braces after control statements
ClosedPublic

Authored by owenpan on Feb 20 2022, 12:11 PM.

Details

Summary

This new option InsertBraces has been tested on make clang and make check-clang. It has almost zero overhead when turned off.

  • Why this new patch?

Because of this comment, I ran
https://reviews.llvm.org/D95168?id=322240 (the last diff before @MyDeveloperDay took over) on make clang and indeed it failed a lot.

  • Why isn't this option an enum or a struct?

We plan to re-configure/re-package RemoveBracesLLVM to support other styles. After that, one can simply turn on InsertBraces and specify the suboptions of RemoveBraces.

  • How does InsertBraces work with RemoveBracesLLVM (or the future RemoveBraces after the latter is renamed and expanded)?

Simply turn on both options (or the desired suboptions of RemoveBraces when it becomes available). See the example below:

$ cat f.cpp
if (a) {
  f();
} else
  // comment
  while (b)
      --b;
$ clang-format -style="{RemoveBracesLLVM: true}" f.cpp  # Incorrect.
if (a)
  f();
else
  // comment
  while (b)
    --b;
$ clang-format -style="{InsertBraces: true, RemoveBracesLLVM: true}" f.cpp
if (a) {
  f();
} else {
  // comment
  while (b)
    --b;
}
$ 

Diff Detail

Event Timeline

owenpan requested review of this revision.Feb 20 2022, 12:11 PM
owenpan created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptFeb 20 2022, 12:11 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Nice! A few minor comments though.

clang/include/clang/Format/Format.h
2572–2573

Please add a comment in which cases the braces are added. If I understand correctly, everywhere except for PP directives, right?

clang/lib/Format/Format.cpp
1839

This comment seems not very useful, remove please.

clang/lib/Format/UnwrappedLineParser.cpp
2449

Is it possible to get rid of the CheckEOF parameter and do if (FormatTok->is(tok::eof)) addUnwrappedLine(); only here?
(I'm unsure about the dependency between Line and addUnwrappedLine)

clang/unittests/Format/FormatTest.cpp
24298

Could you add a test with a // clang-format off part?

clang/lib/Format/UnwrappedLineParser.cpp
2303

Get the last token, and if it's a comment getPreviousNonComment()?

owenpan added inline comments.Feb 20 2022, 5:06 PM
clang/lib/Format/UnwrappedLineParser.cpp
2449

Unfortunately, no. Decrementing Line->Level before calling addUnwrappedLine() would fail MacroDefinitionsWithIncompleteCode in FormatTest.cpp.

owenpan edited the summary of this revision. (Show Details)Feb 20 2022, 8:29 PM
owenpan added inline comments.Feb 20 2022, 9:27 PM
clang/lib/Format/UnwrappedLineParser.cpp
2303

Almost. I tried to use getPreviousNonComment() but sometimes got nullptr when a nonnull was always expected (line 2316).

owenpan updated this revision to Diff 410216.Feb 20 2022, 9:57 PM

Rebased and addressed review comments.

owenpan marked 3 inline comments as done.Feb 20 2022, 9:58 PM
This revision is now accepted and ready to land.Feb 20 2022, 11:18 PM
curdeius accepted this revision.Feb 21 2022, 12:09 AM

LGTM!

clang/lib/Format/Format.cpp
1847

I think that we can skip the whole line if the first token on line is finalized.

owenpan updated this revision to Diff 410244.Feb 21 2022, 1:37 AM

In insertBraces() in Format.cpp, skip an annotated line if its first token is finalized.

owenpan marked an inline comment as done.Feb 21 2022, 1:38 AM
owenpan added inline comments.
clang/lib/Format/Format.cpp
1847

Good point!

owenpan updated this revision to Diff 410365.Feb 21 2022, 12:27 PM
owenpan marked an inline comment as done.

If the line immediately following // clang-format off is a line comment, assert(!Token->Finalized) will fail. Fixed it and updated the corresponding unit test.

This revision was landed with ongoing or failed builds.Feb 21 2022, 8:16 PM
This revision was automatically updated to reflect the committed changes.

@owenpan I didn't get to this one to review it, but it looks good to me and thank you for following through with this, I'll abandon the other implementation