This is an archive of the discontinued LLVM Phabricator instance.

[clang-format] Recognize c++ coroutine keywords as unary operator to avoid misleading pointer alignment
ClosedPublic

Authored by ChuanqiXu on Nov 11 2020, 3:44 AM.

Details

Summary

The clang-format may go wrong when handle c++ coroutine keywords and pointer.
The default value for PointerAlignment is PAS_Right. So the following format is good:

co_return *a;

But within some code style, the value for PointerAlignment is PAS_Left, the behavior goes wrong:

co_return* a;

test-plan: check-llvm, check-clang

Diff Detail

Event Timeline

ChuanqiXu created this revision.Nov 11 2020, 3:44 AM
ChuanqiXu requested review of this revision.Nov 11 2020, 3:44 AM
MyDeveloperDay set the repository for this revision to rG LLVM Github Monorepo.
MyDeveloperDay added projects: Restricted Project, Restricted Project.

What does the behavior goes wrong mean? why can't it be left aligned?

Peanut gallery says: It seems to me that your root problem here is that co_yield is not being recognized by the parser as a keyword, and so you're seeing e.g. co_yield* p; the same way you'd see CoYield* p;.
But in that case, you should also be seeing co_yield -1; formatted as co_yield - 1; the same way you'd see CoYield - 1;.
Is it possible that you're not using the right (C++20) language mode? (OTOH, see D69144, D69180, which also didn't concern themselves with language modes. I don't understand why not.)

Could you please re-upload the diff with context (i.e. git show -U999)?

What does the behavior goes wrong mean? why can't it be left aligned?

Because when we use PointerAlignment attribute, I think we mean that the pointer need to be aligned in declarations. However, co_return *a; is not a declaration.

ChuanqiXu updated this revision to Diff 311485.Dec 13 2020, 9:44 PM

Re-upload patch with context

Peanut gallery says: It seems to me that your root problem here is that co_yield is not being recognized by the parser as a keyword, and so you're seeing e.g. co_yield* p; the same way you'd see CoYield* p;.
But in that case, you should also be seeing co_yield -1; formatted as co_yield - 1; the same way you'd see CoYield - 1;.
Is it possible that you're not using the right (C++20) language mode? (OTOH, see D69144, D69180, which also didn't concern themselves with language modes. I don't understand why not.)

Could you please re-upload the diff with context (i.e. git show -U999)?

Yes, it looks like that co_yield is not being recognized as keywords. I use the Auto for Standard attribute in .clang-format config file. And co* would be recognized as keywords. From my point of view, I first find that the keyword return was processed specifically in the line 1962 in TokenAnnotator.cpp which recognize return as Unary Operator. So I choose to recognize co* keywords as Unary Operators to solve the format problem.

MyDeveloperDay added inline comments.Dec 14 2020, 7:33 AM
clang/unittests/Format/FormatTest.cpp
7766

maybe add, just to clarify it.

verifyFormat("return *a", PASLeftStyle);

ChuanqiXu updated this revision to Diff 311789.Dec 14 2020, 9:53 PM

add verifyFormat("return *a", PASLeftStyle); to clarify the change

ChuanqiXu marked an inline comment as done.Dec 14 2020, 9:54 PM
HazardyKnusperkeks added inline comments.
clang/unittests/Format/FormatTest.cpp
7759–7761

I don't think this should be in the tests, because it is not true (if your patch works).

ChuanqiXu added inline comments.Dec 14 2020, 11:42 PM
clang/unittests/Format/FormatTest.cpp
7759–7761

I'm confusing about your comment. What is not true? Do you mean if my patch works then the co_return *a; should be formatted as co_return* a?

clang/unittests/Format/FormatTest.cpp
7759–7761

No, I refer to the comment. You say would mis-format, but it wouln't because of your change, or not? Otherwise the tests would not pass.

clang/unittests/Format/FormatTest.cpp
7759–7761
ChuanqiXu updated this revision to Diff 311849.Dec 15 2020, 2:45 AM

Edit the comment to avoid misleading.

clang/unittests/Format/FormatTest.cpp
7759–7761

Oh, I got it. Thanks!

MyDeveloperDay accepted this revision.Dec 15 2020, 3:31 AM
This revision is now accepted and ready to land.Dec 15 2020, 3:31 AM

Aside: Would you be prepared to take a look at D34225: [clang-format] Teach clang-format how to handle C++ coroutines which is pretty much been abandoned, and see if there is anything there that might help the co_routinues support?

Aside: Would you be prepared to take a look at D34225: [clang-format] Teach clang-format how to handle C++ coroutines which is pretty much been abandoned, and see if there is anything there that might help the co_routinues support?

I think the test cases in D34225: [clang-format] Teach clang-format how to handle C++ coroutines are rare in our codes. It is a little strange to write co_return (43) instead of co_return 43. And the grammar for co_await (auto x : range) is used rarely. I think both of them are defects of clang-format while they are really rare in actual environments.

I don't like seeing users having to use `// clang-format off```

auto try_sequence = [](int& ref) -> return_ignore {
            /* clang-format off */
            for co_await(int v : return_random_int())
                ref = v;
            /* clang-format on*/
        };

it would be nice if we could land a co_routines improvement

I don't like seeing users having to use `// clang-format off```

auto try_sequence = [](int& ref) -> return_ignore {
            /* clang-format off */
            for co_await(int v : return_random_int())
                ref = v;
            /* clang-format on*/
        };

it would be nice if we could land a co_routines improvement

From the links, I find most of them are test cases of LLVM projects. But I agree with you that /* clang-format off */ looks ugly. And I find that the grammar for co_await () is missing in newer standard documentation (N4849) while it was there in N4680. Maybe it is necessary to check whether this grammar is abandoned.