This is an archive of the discontinued LLVM Phabricator instance.

[Format] Don't derive pointers right based on space before method ref-qualifiers
ClosedPublic

Authored by sammccall on Feb 3 2022, 9:20 AM.

Details

Summary

The second space in void foo() & is always produced by clang-format,
and isn't evidence of any particular style.

Before this patch, it was considered evidence of PAS_Right, because
there is a space before a pointerlike ampersand.

This caused the following code to have "unstable" pointer alignment:

void a() &;
void b() &;
int *x;

PAS_Left, Derive=false would produce 'int* x' with other lines unchanged.
But subsequent formatting with Derive=true would produce 'int *x' again.

Diff Detail

Event Timeline

sammccall requested review of this revision.Feb 3 2022, 9:20 AM
sammccall created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptFeb 3 2022, 9:20 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
sammccall updated this revision to Diff 405682.Feb 3 2022, 9:21 AM

clean up formatting

benhamilton requested changes to this revision.Feb 3 2022, 9:35 AM
benhamilton added inline comments.
clang/lib/Format/Format.cpp
1944

Do we also need to worry about T && foo(); style declarations?

1946

If this is parsing a general function declaration, I think it's not safe to assume that the token immediately before the ref-spec is the close-paren.

It looks like Prev can be a few other things, including at least:

  • tok::kw_const
  • tok::kw_volatile
  • tok::kw_throw
  • tok::kw_noexcept

and probably C++ attribute(s) as well:

noptr-declarator ( parameter-list ) cv(optional) ref(optional) except(optional) attr(optional)

I *think* they can also be in any order, so the ref-spec could come at the very end after cv-qualifier, an expection specification, and C++ attributes.

This revision now requires changes to proceed.Feb 3 2022, 9:35 AM
sammccall added inline comments.Feb 3 2022, 9:47 AM
clang/lib/Format/Format.cpp
1944

A space before && in that case *should* trigger right-alignment.

Are you concerned the exclusion here might fire?

1946

const/volatile: a space between const and & does indicate right alignment. (And clang-format emits a space under PAS_Right)

throw etc: these are not possible, there's no "in any order". Here's the grammar: http://eel.is/c++draft/dcl.decl.general#nt:parameters-and-qualifiers

benhamilton accepted this revision.Feb 3 2022, 10:02 AM

Got it, thanks.

clang/lib/Format/Format.cpp
1944

No, just wanted to make sure it should trigger right-alignment (which is what this implements, of course.)

1946

Ah, good to know the grammar is more strict about ordering.

clang/unittests/Format/FormatTest.cpp
9716–9719

Worth a test with &&?

This revision is now accepted and ready to land.Feb 3 2022, 10:02 AM
sammccall marked an inline comment as done.Feb 4 2022, 3:16 AM

Thanks!

clang/unittests/Format/FormatTest.cpp
9716–9719

Good idea, merged it with the overloaded-operator test.

This revision was landed with ongoing or failed builds.Feb 4 2022, 3:16 AM
This revision was automatically updated to reflect the committed changes.
sammccall marked an inline comment as done.