This is an archive of the discontinued LLVM Phabricator instance.

[clang-format] Avoid inserting space after C++ casts.
ClosedPublic

Authored by curdeius on Feb 18 2022, 9:25 AM.

Details

Summary

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

This is a solution for standard C++ casts: const_cast, dynamic_cast, reinterpret_cast, static_cast.

A general approach handling all possible casts is not possible without semantic information.
Consider the code:

static_cast<T>(*function_pointer_variable)(arguments);

vs.

some_return_type<T> (*function_pointer_variable)(parameters);
// Later used as:
function_pointer_variable = &some_function;
return function_pointer_variable(args);

In the latter case, it's not a cast but a variable declaration of a pointer to function.
Without knowing what some_return_type<T> is (and clang-format does not know it), it's hard to distinguish between the two cases. Theoretically, one could check whether "parameters" are types (not a cast) and "arguments" are value/expressions (a cast), but that might be inefficient (needs lots of lookahead).

Diff Detail

Event Timeline

curdeius requested review of this revision.Feb 18 2022, 9:25 AM
curdeius created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptFeb 18 2022, 9:25 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
curdeius added inline comments.Feb 18 2022, 9:29 AM
clang/lib/Format/TokenAnnotator.cpp
1744

To add some context, in the failing cases, the opening parenthesis was set to type TT_FunctionTypeLParen that we don't want because combined with a * after the next paren, it adds a space (cf. https://github.com/llvm/llvm-project/blob/331e8e4e27be5dd673898a89a7cf00e76903216a/clang/lib/Format/TokenAnnotator.cpp#L3105-L3109).

lichray added inline comments.
clang/lib/Format/TokenAnnotator.cpp
1971

Very unlikely bit_cast gives you something callable; any_cast may. I think keywords are ok for now, and cheap. Others may need a different strategy.

curdeius marked an inline comment as done.Feb 18 2022, 12:35 PM
curdeius added inline comments.
clang/lib/Format/TokenAnnotator.cpp
1971

Indeed.

MyDeveloperDay accepted this revision.Feb 18 2022, 12:56 PM
This revision is now accepted and ready to land.Feb 18 2022, 12:56 PM
owenpan accepted this revision.Feb 19 2022, 1:20 AM
This revision was automatically updated to reflect the committed changes.
curdeius marked an inline comment as done.
curdeius reopened this revision.Feb 20 2022, 1:20 PM
This revision is now accepted and ready to land.Feb 20 2022, 1:20 PM
curdeius planned changes to this revision.Feb 20 2022, 1:21 PM

This commit provokes failures in formatting tests of polly.
Cf. https://lab.llvm.org/buildbot/#/builders/205/builds/3320.

That's probably because of ) being annotated as CastRParen instead of Unknown before, hence being kept on the same line with the next token.

curdeius updated this revision to Diff 410638.Feb 22 2022, 1:41 PM
  • Fix. Add tests from inspired by polly and lib/Format that had misformats.
This revision is now accepted and ready to land.Feb 22 2022, 1:41 PM
curdeius requested review of this revision.Feb 22 2022, 1:44 PM

I took another approach to fix the problem found in polly tests.
I added CppCastLParen kind so as not to interfere with C-style casts.
I also added a test case taken from lib/Format that got misformatted by the previous version (if (static_cast<int>(A) + B >= 0)\n ; got the spaces around + removed: if (static_cast<int>(A)+B >= 0)\n ;).

This revision is now accepted and ready to land.Feb 23 2022, 11:46 AM
This revision was landed with ongoing or failed builds.Feb 24 2022, 1:21 AM
This revision was automatically updated to reflect the committed changes.