Skip to content

Commit 151d0a4

Browse files
authored
[clang-format] Handle __attribute/__declspec/AttributeMacro consistently (#67518)
1 parent 7a80a5d commit 151d0a4

File tree

5 files changed

+46
-34
lines changed

5 files changed

+46
-34
lines changed

clang/lib/Format/FormatToken.h

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,10 @@ struct FormatToken {
618618

619619
bool isStringLiteral() const { return tok::isStringLiteral(Tok.getKind()); }
620620

621+
bool isAttribute() const {
622+
return isOneOf(tok::kw___attribute, tok::kw___declspec, TT_AttributeMacro);
623+
}
624+
621625
bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const {
622626
return Tok.isObjCAtKeyword(Kind);
623627
}
@@ -633,9 +637,10 @@ struct FormatToken {
633637

634638
bool canBePointerOrReferenceQualifier() const {
635639
return isOneOf(tok::kw_const, tok::kw_restrict, tok::kw_volatile,
636-
tok::kw___attribute, tok::kw__Nonnull, tok::kw__Nullable,
640+
tok::kw__Nonnull, tok::kw__Nullable,
637641
tok::kw__Null_unspecified, tok::kw___ptr32, tok::kw___ptr64,
638-
tok::kw___funcref, TT_AttributeMacro);
642+
tok::kw___funcref) ||
643+
isAttribute();
639644
}
640645

641646
/// Determine whether the token is a simple-type-specifier.
@@ -708,25 +713,16 @@ struct FormatToken {
708713
/// Returns \c true if this is a keyword that can be used
709714
/// like a function call (e.g. sizeof, typeid, ...).
710715
bool isFunctionLikeKeyword() const {
711-
switch (Tok.getKind()) {
712-
case tok::kw_throw:
713-
case tok::kw_typeid:
714-
case tok::kw_return:
715-
case tok::kw_sizeof:
716-
case tok::kw_alignof:
717-
case tok::kw_alignas:
718-
case tok::kw_decltype:
719-
case tok::kw_noexcept:
720-
case tok::kw_static_assert:
721-
case tok::kw__Atomic:
722-
case tok::kw___attribute:
723-
#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
724-
#include "clang/Basic/TransformTypeTraits.def"
725-
case tok::kw_requires:
716+
if (isAttribute())
726717
return true;
727-
default:
728-
return false;
729-
}
718+
719+
return isOneOf(tok::kw_throw, tok::kw_typeid, tok::kw_return,
720+
tok::kw_sizeof, tok::kw_alignof, tok::kw_alignas,
721+
tok::kw_decltype, tok::kw_noexcept, tok::kw_static_assert,
722+
tok::kw__Atomic,
723+
#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait,
724+
#include "clang/Basic/TransformTypeTraits.def"
725+
tok::kw_requires);
730726
}
731727

732728
/// Returns \c true if this is a string literal that's like a label,

clang/lib/Format/NamespaceEndCommentsFixer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ processTokens(const FormatToken *Tok, tok::TokenKind StartTok,
4848
const FormatToken *skipAttribute(const FormatToken *Tok) {
4949
if (!Tok)
5050
return nullptr;
51-
if (Tok->is(tok::kw___attribute)) {
51+
if (Tok->isAttribute()) {
5252
Tok = Tok->getNextNonComment();
5353
Tok = processTokens(Tok, tok::l_paren, tok::r_paren, nullptr);
5454
} else if (Tok->is(tok::l_square)) {

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ class AnnotatingParser {
376376
// Infer the role of the l_paren based on the previous token if we haven't
377377
// detected one yet.
378378
if (PrevNonComment && OpeningParen.is(TT_Unknown)) {
379-
if (PrevNonComment->is(tok::kw___attribute)) {
379+
if (PrevNonComment->isAttribute()) {
380380
OpeningParen.setType(TT_AttributeLParen);
381381
} else if (PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype,
382382
tok::kw_typeof,
@@ -1207,11 +1207,13 @@ class AnnotatingParser {
12071207
return false;
12081208
if (Line.MustBeDeclaration && Contexts.size() == 1 &&
12091209
!Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
1210-
!Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen) &&
1211-
(!Tok->Previous ||
1212-
!Tok->Previous->isOneOf(tok::kw___attribute, TT_RequiresClause,
1213-
TT_LeadingJavaAnnotation))) {
1214-
Line.MightBeFunctionDecl = true;
1210+
!Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen)) {
1211+
if (const auto *Previous = Tok->Previous;
1212+
!Previous ||
1213+
(!Previous->isAttribute() &&
1214+
!Previous->isOneOf(TT_RequiresClause, TT_LeadingJavaAnnotation))) {
1215+
Line.MightBeFunctionDecl = true;
1216+
}
12151217
}
12161218
break;
12171219
case tok::l_square:
@@ -2389,7 +2391,7 @@ class AnnotatingParser {
23892391
assert(T->MatchingParen->is(tok::l_paren));
23902392
assert(T->MatchingParen->is(TT_AttributeLParen));
23912393
if (const auto *Tok = T->MatchingParen->Previous;
2392-
Tok && Tok->is(tok::kw___attribute)) {
2394+
Tok && Tok->isAttribute()) {
23932395
T = Tok->Previous;
23942396
continue;
23952397
}
@@ -5613,10 +5615,11 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
56135615
tok::less, tok::coloncolon);
56145616
}
56155617

5616-
if (Right.is(tok::kw___attribute) ||
5617-
(Right.is(tok::l_square) && Right.is(TT_AttributeSquare))) {
5618+
if (Right.isAttribute())
5619+
return true;
5620+
5621+
if (Right.is(tok::l_square) && Right.is(TT_AttributeSquare))
56185622
return Left.isNot(TT_AttributeSquare);
5619-
}
56205623

56215624
if (Left.is(tok::identifier) && Right.is(tok::string_literal))
56225625
return true;

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,
354354
bool SwitchLabelEncountered = false;
355355

356356
do {
357-
if (FormatTok->getType() == TT_AttributeMacro) {
357+
if (FormatTok->isAttribute()) {
358358
nextToken();
359359
continue;
360360
}
@@ -2658,7 +2658,7 @@ static void markOptionalBraces(FormatToken *LeftBrace) {
26582658

26592659
void UnwrappedLineParser::handleAttributes() {
26602660
// Handle AttributeMacro, e.g. `if (x) UNLIKELY`.
2661-
if (FormatTok->is(TT_AttributeMacro))
2661+
if (FormatTok->isAttribute())
26622662
nextToken();
26632663
else if (FormatTok->is(tok::l_square))
26642664
handleCppAttributes();
@@ -3835,8 +3835,8 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
38353835
// it is often token-pasted.
38363836
// An [[attribute]] can be before the identifier.
38373837
while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
3838-
tok::kw___attribute, tok::kw___declspec,
38393838
tok::kw_alignas, tok::l_square) ||
3839+
FormatTok->isAttribute() ||
38403840
((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
38413841
FormatTok->isOneOf(tok::period, tok::comma))) {
38423842
if (Style.isJavaScript() &&

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,6 +2107,19 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributes) {
21072107
EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_Unknown);
21082108
EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_Unknown);
21092109
EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_AttributeRParen);
2110+
2111+
Tokens = annotate("bool foo __declspec(dllimport);");
2112+
ASSERT_EQ(Tokens.size(), 8u) << Tokens;
2113+
EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_AttributeLParen);
2114+
EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen);
2115+
2116+
FormatStyle Style = getLLVMStyle();
2117+
Style.AttributeMacros.push_back("FOO");
2118+
Tokens = annotate("bool foo FOO(unused);", Style);
2119+
ASSERT_EQ(Tokens.size(), 8u) << Tokens;
2120+
EXPECT_TOKEN(Tokens[2], tok::identifier, TT_AttributeMacro);
2121+
EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_AttributeLParen);
2122+
EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen);
21102123
}
21112124

21122125
} // namespace

0 commit comments

Comments
 (0)