Skip to content

Commit 5d28f33

Browse files
committed
Add SpaceInParensOption for __attribute__ keyword
The __attribute((specifier-list)) currently is formatted based on the SpacesInParensOptions.Other (previously, SpacesInParentheses). This change allows finer control over addition of spaces between the consecutive parens, and between the inner parens and the list of attribute specifiers. Differential Revision: https://reviews.llvm.org/D155529
1 parent fb14662 commit 5d28f33

File tree

7 files changed

+53
-13
lines changed

7 files changed

+53
-13
lines changed

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5625,6 +5625,13 @@ the configuration (without a prefix: ``Auto``).
56255625
InConditionalStatements: true
56265626
Other: true
56275627

5628+
* ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers.
5629+
5630+
.. code-block:: c++
5631+
5632+
true: false:
5633+
__attribute__( ( noreturn ) ) vs. __attribute__((noreturn))
5634+
56285635
* ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements
56295636
(``for/if/while/switch...``).
56305637

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,8 @@ clang-format
10791079
- Add ``ObjCPropertyAttributeOrder`` which can be used to sort ObjC property
10801080
attributes (like ``nonatomic, strong, nullable``).
10811081
- Add ``.clang-format-ignore`` files.
1082+
- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions``
1083+
to control addition of spaces after the ``__attribute__`` keyword.
10821084

10831085
libclang
10841086
--------

clang/include/clang/Format/Format.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4515,6 +4515,12 @@ struct FormatStyle {
45154515
/// Other: true
45164516
/// \endcode
45174517
struct SpacesInParensCustom {
4518+
/// Put a space in parentheses of attribute specifiers.
4519+
/// \code
4520+
/// true: false:
4521+
/// __attribute__( ( noreturn ) ) vs. __attribute__((noreturn))
4522+
/// \endcode
4523+
bool InAttributeSpecifiers;
45184524
/// Put a space in parentheses only inside conditional statements
45194525
/// (``for/if/while/switch...``).
45204526
/// \code
@@ -4548,17 +4554,20 @@ struct FormatStyle {
45484554
bool Other;
45494555

45504556
SpacesInParensCustom()
4551-
: InConditionalStatements(false), InCStyleCasts(false),
4552-
InEmptyParentheses(false), Other(false) {}
4557+
: InAttributeSpecifiers(false), InConditionalStatements(false),
4558+
InCStyleCasts(false), InEmptyParentheses(false), Other(false) {}
45534559

4554-
SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts,
4560+
SpacesInParensCustom(bool InAttributeSpecifiers,
4561+
bool InConditionalStatements, bool InCStyleCasts,
45554562
bool InEmptyParentheses, bool Other)
4556-
: InConditionalStatements(InConditionalStatements),
4563+
: InAttributeSpecifiers(InAttributeSpecifiers),
4564+
InConditionalStatements(InConditionalStatements),
45574565
InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses),
45584566
Other(Other) {}
45594567

45604568
bool operator==(const SpacesInParensCustom &R) const {
4561-
return InConditionalStatements == R.InConditionalStatements &&
4569+
return InAttributeSpecifiers == R.InAttributeSpecifiers &&
4570+
InConditionalStatements == R.InConditionalStatements &&
45624571
InCStyleCasts == R.InCStyleCasts &&
45634572
InEmptyParentheses == R.InEmptyParentheses && Other == R.Other;
45644573
}

clang/lib/Format/Format.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,7 @@ template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
753753

754754
template <> struct MappingTraits<FormatStyle::SpacesInParensCustom> {
755755
static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {
756+
IO.mapOptional("InAttributeSpecifiers", Spaces.InAttributeSpecifiers);
756757
IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts);
757758
IO.mapOptional("InConditionalStatements", Spaces.InConditionalStatements);
758759
IO.mapOptional("InEmptyParentheses", Spaces.InEmptyParentheses);
@@ -1191,6 +1192,7 @@ template <> struct MappingTraits<FormatStyle> {
11911192
if (SpacesInParentheses) {
11921193
// set all options except InCStyleCasts and InEmptyParentheses
11931194
// to true for backward compatibility.
1195+
Style.SpacesInParensOptions.InAttributeSpecifiers = true;
11941196
Style.SpacesInParensOptions.InConditionalStatements = true;
11951197
Style.SpacesInParensOptions.InCStyleCasts =
11961198
SpacesInCStyleCastParentheses;

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3999,10 +3999,18 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
39993999
}
40004000

40014001
if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) {
4002-
return (Right.is(TT_CastRParen) ||
4003-
(Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
4004-
? Style.SpacesInParensOptions.InCStyleCasts
4005-
: Style.SpacesInParensOptions.Other;
4002+
if (Right.is(TT_CastRParen) ||
4003+
(Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen))) {
4004+
return Style.SpacesInParensOptions.InCStyleCasts;
4005+
}
4006+
const auto isAttributeParen = [](const FormatToken *Paren) {
4007+
return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
4008+
};
4009+
if (isAttributeParen(&Left) || isAttributeParen(&Right) ||
4010+
isAttributeParen(Left.Previous) || isAttributeParen(Right.Next)) {
4011+
return Style.SpacesInParensOptions.InAttributeSpecifiers;
4012+
}
4013+
return Style.SpacesInParensOptions.Other;
40064014
}
40074015
if (Right.isOneOf(tok::semi, tok::comma))
40084016
return false;

clang/unittests/Format/ConfigParseTest.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
231231
CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterIfMacros);
232232
CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
233233
CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
234+
CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InAttributeSpecifiers);
234235
CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts);
235236
CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
236237
CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
@@ -626,19 +627,23 @@ TEST(ConfigParseTest, ParsesConfiguration) {
626627
Style.SpacesInParens = FormatStyle::SIPO_Never;
627628
Style.SpacesInParensOptions = {};
628629
CHECK_PARSE("SpacesInParentheses: true", SpacesInParensOptions,
629-
FormatStyle::SpacesInParensCustom(true, false, false, true));
630+
FormatStyle::SpacesInParensCustom(true, true, false, false,
631+
true));
630632
Style.SpacesInParens = FormatStyle::SIPO_Never;
631633
Style.SpacesInParensOptions = {};
632634
CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions,
633-
FormatStyle::SpacesInParensCustom(true, false, false, false));
635+
FormatStyle::SpacesInParensCustom(false, true, false, false,
636+
false));
634637
Style.SpacesInParens = FormatStyle::SIPO_Never;
635638
Style.SpacesInParensOptions = {};
636639
CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
637-
FormatStyle::SpacesInParensCustom(false, true, false, false));
640+
FormatStyle::SpacesInParensCustom(false, false, true, false,
641+
false));
638642
Style.SpacesInParens = FormatStyle::SIPO_Never;
639643
Style.SpacesInParensOptions = {};
640644
CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions,
641-
FormatStyle::SpacesInParensCustom(false, false, true, false));
645+
FormatStyle::SpacesInParensCustom(false, false, false, true,
646+
false));
642647
Style.SpacesInParens = FormatStyle::SIPO_Never;
643648
Style.SpacesInParensOptions = {};
644649

clang/unittests/Format/FormatTest.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16741,6 +16741,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
1674116741
Spaces.SpacesInParensOptions = {};
1674216742
Spaces.SpacesInParensOptions.Other = true;
1674316743
Spaces.SpacesInParensOptions.InConditionalStatements = true;
16744+
Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
1674416745
verifyFormat("do_something( ::globalVar );", Spaces);
1674516746
verifyFormat("call( x, y, z );", Spaces);
1674616747
verifyFormat("call();", Spaces);
@@ -16815,6 +16816,12 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
1681516816
verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
1681616817
verifyFormat("void f( ) __attribute__((asdf));", Spaces);
1681716818

16819+
Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
16820+
verifyFormat("SomeType *__attribute__( ( attr ) ) *a = NULL;", Spaces);
16821+
verifyFormat("void __attribute__( ( naked ) ) foo(int bar)", Spaces);
16822+
verifyFormat("void f( ) __attribute__( ( asdf ) );", Spaces);
16823+
Spaces.SpacesInParensOptions.InAttributeSpecifiers = false;
16824+
1681816825
// Run the first set of tests again with:
1681916826
Spaces.SpaceAfterCStyleCast = true;
1682016827
verifyFormat("call(x, y, z);", Spaces);

0 commit comments

Comments
 (0)