Skip to content

Commit a8d2bff

Browse files
committed
[clang-format] Don't wrap struct return types as structs
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
1 parent 5409fb3 commit a8d2bff

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4916,8 +4916,13 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
49164916
return true;
49174917
}
49184918

4919-
return (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) ||
4920-
(Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct);
4919+
// Don't attempt to interpret struct return types as structs.
4920+
if (Right.isNot(TT_FunctionLBrace)) {
4921+
return (Line.startsWith(tok::kw_class) &&
4922+
Style.BraceWrapping.AfterClass) ||
4923+
(Line.startsWith(tok::kw_struct) &&
4924+
Style.BraceWrapping.AfterStruct);
4925+
}
49214926
}
49224927

49234928
if (Left.is(TT_ObjCBlockLBrace) &&

clang/unittests/Format/FormatTest.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3205,17 +3205,50 @@ TEST_F(FormatTest, MultiLineControlStatements) {
32053205
format("try{foo();}catch(...){baz();}", Style));
32063206

32073207
Style.BraceWrapping.AfterFunction = true;
3208+
Style.BraceWrapping.AfterStruct = false;
32083209
Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_MultiLine;
32093210
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
32103211
Style.ColumnLimit = 80;
32113212
verifyFormat("void shortfunction() { bar(); }", Style);
3213+
verifyFormat("struct T shortfunction() { return bar(); }", Style);
3214+
verifyFormat("struct T {};", Style);
32123215

32133216
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
32143217
verifyFormat("void shortfunction()\n"
32153218
"{\n"
32163219
" bar();\n"
32173220
"}",
32183221
Style);
3222+
verifyFormat("struct T shortfunction()\n"
3223+
"{\n"
3224+
" return bar();\n"
3225+
"}",
3226+
Style);
3227+
verifyFormat("struct T {};", Style);
3228+
3229+
Style.BraceWrapping.AfterFunction = false;
3230+
Style.BraceWrapping.AfterStruct = true;
3231+
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
3232+
verifyFormat("void shortfunction() { bar(); }", Style);
3233+
verifyFormat("struct T shortfunction() { return bar(); }", Style);
3234+
verifyFormat("struct T\n"
3235+
"{\n"
3236+
"};",
3237+
Style);
3238+
3239+
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
3240+
verifyFormat("void shortfunction() {\n"
3241+
" bar();\n"
3242+
"}",
3243+
Style);
3244+
verifyFormat("struct T shortfunction() {\n"
3245+
" return bar();\n"
3246+
"}",
3247+
Style);
3248+
verifyFormat("struct T\n"
3249+
"{\n"
3250+
"};",
3251+
Style);
32193252
}
32203253

32213254
TEST_F(FormatTest, BeforeWhile) {

0 commit comments

Comments
 (0)