Skip to content

Commit 5e77775

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 75efddb commit 5e77775

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
@@ -5693,6 +5693,13 @@ the configuration (without a prefix: ``Auto``).
56935693
InConditionalStatements: true
56945694
Other: true
56955695

5696+
* ``bool InAttributeSpecifiers`` Put a space in parentheses of attribute specifiers.
5697+
5698+
.. code-block:: c++
5699+
5700+
true: false:
5701+
__attribute__( ( noreturn ) ) vs. __attribute__((noreturn))
5702+
56965703
* ``bool InConditionalStatements`` Put a space in parentheses only inside conditional statements
56975704
(``for/if/while/switch...``).
56985705

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,8 @@ clang-format
11021102
attributes (like ``nonatomic, strong, nullable``).
11031103
- Add ``.clang-format-ignore`` files.
11041104
- Add ``AlignFunctionPointers`` sub-option for ``AlignConsecutiveDeclarations``.
1105+
- Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions``
1106+
to control addition of spaces after the ``__attribute__`` keyword.
11051107

11061108
libclang
11071109
--------

clang/include/clang/Format/Format.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4534,6 +4534,12 @@ struct FormatStyle {
45344534
/// Other: true
45354535
/// \endcode
45364536
struct SpacesInParensCustom {
4537+
/// Put a space in parentheses of attribute specifiers.
4538+
/// \code
4539+
/// true: false:
4540+
/// __attribute__( ( noreturn ) ) vs. __attribute__((noreturn))
4541+
/// \endcode
4542+
bool InAttributeSpecifiers;
45374543
/// Put a space in parentheses only inside conditional statements
45384544
/// (``for/if/while/switch...``).
45394545
/// \code
@@ -4567,17 +4573,20 @@ struct FormatStyle {
45674573
bool Other;
45684574

45694575
SpacesInParensCustom()
4570-
: InConditionalStatements(false), InCStyleCasts(false),
4571-
InEmptyParentheses(false), Other(false) {}
4576+
: InAttributeSpecifiers(false), InConditionalStatements(false),
4577+
InCStyleCasts(false), InEmptyParentheses(false), Other(false) {}
45724578

4573-
SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts,
4579+
SpacesInParensCustom(bool InAttributeSpecifiers,
4580+
bool InConditionalStatements, bool InCStyleCasts,
45744581
bool InEmptyParentheses, bool Other)
4575-
: InConditionalStatements(InConditionalStatements),
4582+
: InAttributeSpecifiers(InAttributeSpecifiers),
4583+
InConditionalStatements(InConditionalStatements),
45764584
InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses),
45774585
Other(Other) {}
45784586

45794587
bool operator==(const SpacesInParensCustom &R) const {
4580-
return InConditionalStatements == R.InConditionalStatements &&
4588+
return InAttributeSpecifiers == R.InAttributeSpecifiers &&
4589+
InConditionalStatements == R.InConditionalStatements &&
45814590
InCStyleCasts == R.InCStyleCasts &&
45824591
InEmptyParentheses == R.InEmptyParentheses && Other == R.Other;
45834592
}

clang/lib/Format/Format.cpp

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

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

clang/lib/Format/TokenAnnotator.cpp

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

40074007
if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) {
4008-
return (Right.is(TT_CastRParen) ||
4009-
(Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
4010-
? Style.SpacesInParensOptions.InCStyleCasts
4011-
: Style.SpacesInParensOptions.Other;
4008+
if (Right.is(TT_CastRParen) ||
4009+
(Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen))) {
4010+
return Style.SpacesInParensOptions.InCStyleCasts;
4011+
}
4012+
const auto isAttributeParen = [](const FormatToken *Paren) {
4013+
return Paren && Paren->isOneOf(TT_AttributeLParen, TT_AttributeRParen);
4014+
};
4015+
if (isAttributeParen(&Left) || isAttributeParen(&Right) ||
4016+
isAttributeParen(Left.Previous) || isAttributeParen(Right.Next)) {
4017+
return Style.SpacesInParensOptions.InAttributeSpecifiers;
4018+
}
4019+
return Style.SpacesInParensOptions.Other;
40124020
}
40134021
if (Right.isOneOf(tok::semi, tok::comma))
40144022
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);
@@ -632,19 +633,23 @@ TEST(ConfigParseTest, ParsesConfiguration) {
632633
Style.SpacesInParens = FormatStyle::SIPO_Never;
633634
Style.SpacesInParensOptions = {};
634635
CHECK_PARSE("SpacesInParentheses: true", SpacesInParensOptions,
635-
FormatStyle::SpacesInParensCustom(true, false, false, true));
636+
FormatStyle::SpacesInParensCustom(true, true, false, false,
637+
true));
636638
Style.SpacesInParens = FormatStyle::SIPO_Never;
637639
Style.SpacesInParensOptions = {};
638640
CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions,
639-
FormatStyle::SpacesInParensCustom(true, false, false, false));
641+
FormatStyle::SpacesInParensCustom(false, true, false, false,
642+
false));
640643
Style.SpacesInParens = FormatStyle::SIPO_Never;
641644
Style.SpacesInParensOptions = {};
642645
CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
643-
FormatStyle::SpacesInParensCustom(false, true, false, false));
646+
FormatStyle::SpacesInParensCustom(false, false, true, false,
647+
false));
644648
Style.SpacesInParens = FormatStyle::SIPO_Never;
645649
Style.SpacesInParensOptions = {};
646650
CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions,
647-
FormatStyle::SpacesInParensCustom(false, false, true, false));
651+
FormatStyle::SpacesInParensCustom(false, false, false, true,
652+
false));
648653
Style.SpacesInParens = FormatStyle::SIPO_Never;
649654
Style.SpacesInParensOptions = {};
650655

clang/unittests/Format/FormatTest.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16821,6 +16821,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
1682116821
Spaces.SpacesInParensOptions = {};
1682216822
Spaces.SpacesInParensOptions.Other = true;
1682316823
Spaces.SpacesInParensOptions.InConditionalStatements = true;
16824+
Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
1682416825
verifyFormat("do_something( ::globalVar );", Spaces);
1682516826
verifyFormat("call( x, y, z );", Spaces);
1682616827
verifyFormat("call();", Spaces);
@@ -16895,6 +16896,12 @@ TEST_F(FormatTest, ConfigurableSpacesInParens) {
1689516896
verifyFormat("void __attribute__((naked)) foo(int bar)", Spaces);
1689616897
verifyFormat("void f( ) __attribute__((asdf));", Spaces);
1689716898

16899+
Spaces.SpacesInParensOptions.InAttributeSpecifiers = true;
16900+
verifyFormat("SomeType *__attribute__( ( attr ) ) *a = NULL;", Spaces);
16901+
verifyFormat("void __attribute__( ( naked ) ) foo(int bar)", Spaces);
16902+
verifyFormat("void f( ) __attribute__( ( asdf ) );", Spaces);
16903+
Spaces.SpacesInParensOptions.InAttributeSpecifiers = false;
16904+
1689816905
// Run the first set of tests again with:
1689916906
Spaces.SpaceAfterCStyleCast = true;
1690016907
verifyFormat("call(x, y, z);", Spaces);

0 commit comments

Comments
 (0)