This is an archive of the discontinued LLVM Phabricator instance.

[clang-format] Don't finalize #if, #else, #endif, etc.
ClosedPublic

Authored by owenpan on Jun 18 2023, 11:32 PM.

Details

Summary

Don't finalize a preprocessor branch directive if it's the first token of an annotated line. See the rationale at D150057#inline-1449546.

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

Diff Detail

Event Timeline

owenpan created this revision.Jun 18 2023, 11:32 PM
Herald added projects: Restricted Project, Restricted Project, Restricted Project. · View Herald TranscriptJun 18 2023, 11:32 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
owenpan requested review of this revision.Jun 18 2023, 11:32 PM
Sedeniono requested changes to this revision.Jun 19 2023, 12:31 PM
Sedeniono added inline comments.
clang/lib/Format/UnwrappedLineFormatter.cpp
1416–1421

After some time, I found your comment here which explains the intention of the "do not finalize '#'" thing. Would it be possible to provide the reasoning here as some comment, or at least some hint that it has to do with multiple passes because of PP branches? To give future readers some chance to understand what is going on. Maybe something along the lines of

// Never mark the '#' of a PP branch as finalized, since clang-format performs 
// multiple passes, where each pass represents a version where the code of 
// one of the PP branches is filled in. Later passes must also  be allowed to 
// format the PP tokens.

Alternatively or additionally, I would be happy with a link to your explanation in the code or the commit message, if the llvm rules/conventions allow it.

Apart from this, I have dug way too little into how clang-format works to reason about the change. I tested it with the full hpp file from https://github.com/llvm/llvm-project/issues/57117, and can confirm that the issue is fixed. So I believe you. ;-)
But: Considering your comment here, I thought that the whole "do not finalize '#'" thing is relevant only if there are some "else"-PP-branches? But in the minimal example/the unit test, there is no "else" branch? How do the multiple passes because of PP branches relate to the clang-format off comment?

This revision now requires changes to proceed.Jun 19 2023, 12:31 PM
owenpan edited the summary of this revision. (Show Details)Jun 19 2023, 12:55 PM
owenpan added inline comments.Jun 19 2023, 7:28 PM
clang/lib/Format/UnwrappedLineFormatter.cpp
1416–1421

Alternatively or additionally, I would be happy with a link to your explanation in the code or the commit message, if the llvm rules/conventions allow it.

I've updated the summary and will include the link in the commit message.

But: Considering your comment here, I thought that the whole "do not finalize '#'" thing is relevant only if there are some "else"-PP-branches? But in the minimal example/the unit test, there is no "else" branch?

This patch fixes the issue that #if/#else etc. may get formatted even if clang-format off is specified. It's not specific to #else, and the added unit test is sufficient.

How do the multiple passes because of PP branches relate to the clang-format off comment?

They are not (or should not be) related. We probably should add an attribute to FormatToken exclusively for clang-format off as Finalized doesn't necessarily mean clang-format off is in effect.

owenpan marked an inline comment as done.Jun 19 2023, 7:28 PM
MyDeveloperDay accepted this revision.Jun 20 2023, 8:19 AM
Sedeniono accepted this revision.Jun 20 2023, 10:10 AM
This revision is now accepted and ready to land.Jun 20 2023, 10:10 AM
This revision was automatically updated to reflect the committed changes.