Skip to content

Commit

Permalink
[clang-format] Don't wrap struct return types as structs
Browse files Browse the repository at this point in the history
When using BraceWrapping.AfterClass or BraceWrapping.AfterStruct, the
token annotator relies on the first token of the line to determine if
we're dealing with a struct or class, however, this check is faulty if
it's actually a function with an elaborated struct/class return type, as
is common in C.

This patch skips the check if the brace is already annotated as
FunctionLBrace, in which case we already know it's a function and should
be treated as such.

Fixes #58527

Reviewed By: HazardyKnusperkeks, owenpan

Differential Revision: https://reviews.llvm.org/D146281
  • Loading branch information
rymiel committed Mar 26, 2023
1 parent 5409fb3 commit a8d2bff
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
9 changes: 7 additions & 2 deletions clang/lib/Format/TokenAnnotator.cpp
Expand Up @@ -4916,8 +4916,13 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
return true;
}

return (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) ||
(Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct);
// Don't attempt to interpret struct return types as structs.
if (Right.isNot(TT_FunctionLBrace)) {
return (Line.startsWith(tok::kw_class) &&
Style.BraceWrapping.AfterClass) ||
(Line.startsWith(tok::kw_struct) &&
Style.BraceWrapping.AfterStruct);
}
}

if (Left.is(TT_ObjCBlockLBrace) &&
Expand Down
33 changes: 33 additions & 0 deletions clang/unittests/Format/FormatTest.cpp
Expand Up @@ -3205,17 +3205,50 @@ TEST_F(FormatTest, MultiLineControlStatements) {
format("try{foo();}catch(...){baz();}", Style));

Style.BraceWrapping.AfterFunction = true;
Style.BraceWrapping.AfterStruct = false;
Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_MultiLine;
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
Style.ColumnLimit = 80;
verifyFormat("void shortfunction() { bar(); }", Style);
verifyFormat("struct T shortfunction() { return bar(); }", Style);
verifyFormat("struct T {};", Style);

Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
verifyFormat("void shortfunction()\n"
"{\n"
" bar();\n"
"}",
Style);
verifyFormat("struct T shortfunction()\n"
"{\n"
" return bar();\n"
"}",
Style);
verifyFormat("struct T {};", Style);

Style.BraceWrapping.AfterFunction = false;
Style.BraceWrapping.AfterStruct = true;
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
verifyFormat("void shortfunction() { bar(); }", Style);
verifyFormat("struct T shortfunction() { return bar(); }", Style);
verifyFormat("struct T\n"
"{\n"
"};",
Style);

Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
verifyFormat("void shortfunction() {\n"
" bar();\n"
"}",
Style);
verifyFormat("struct T shortfunction() {\n"
" return bar();\n"
"}",
Style);
verifyFormat("struct T\n"
"{\n"
"};",
Style);
}

TEST_F(FormatTest, BeforeWhile) {
Expand Down

0 comments on commit a8d2bff

Please sign in to comment.