Skip to content

Commit a106131

Browse files
authored
[clang-format] Handle AttributeMacro before access modifiers (llvm#95634)
Closes llvm#95094.
1 parent 67285fe commit a106131

File tree

5 files changed

+41
-19
lines changed

5 files changed

+41
-19
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,8 @@ class AnnotatingParser {
14191419
Tok->setType(TT_CtorInitializerColon);
14201420
} else {
14211421
Tok->setType(TT_InheritanceColon);
1422+
if (Prev->isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected))
1423+
Line.Type = LT_AccessModifier;
14221424
}
14231425
} else if (canBeObjCSelectorComponent(*Tok->Previous) && Tok->Next &&
14241426
(Tok->Next->isOneOf(tok::r_paren, tok::comma) ||
@@ -1998,6 +2000,8 @@ class AnnotatingParser {
19982000
if (!consumeToken())
19992001
return LT_Invalid;
20002002
}
2003+
if (Line.Type == LT_AccessModifier)
2004+
return LT_AccessModifier;
20012005
if (KeywordVirtualFound)
20022006
return LT_VirtualFunctionDecl;
20032007
if (ImportStatement)

clang/lib/Format/TokenAnnotator.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ namespace format {
2222

2323
enum LineType {
2424
LT_Invalid,
25+
// Contains public/private/protected followed by TT_InheritanceColon.
26+
LT_AccessModifier,
2527
LT_ImportStatement,
2628
LT_ObjCDecl, // An @interface, @implementation, or @protocol line.
2729
LT_ObjCMethodDecl,
@@ -45,7 +47,7 @@ enum ScopeType {
4547
class AnnotatedLine {
4648
public:
4749
AnnotatedLine(const UnwrappedLine &Line)
48-
: First(Line.Tokens.front().Tok), Level(Line.Level),
50+
: First(Line.Tokens.front().Tok), Type(LT_Other), Level(Line.Level),
4951
PPLevel(Line.PPLevel),
5052
MatchingOpeningBlockLineIndex(Line.MatchingOpeningBlockLineIndex),
5153
MatchingClosingBlockLineIndex(Line.MatchingClosingBlockLineIndex),

clang/lib/Format/UnwrappedLineFormatter.cpp

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class LevelIndentTracker {
5757
/// Update the indent state given that \p Line is going to be formatted
5858
/// next.
5959
void nextLine(const AnnotatedLine &Line) {
60-
Offset = getIndentOffset(*Line.First);
60+
Offset = getIndentOffset(Line);
6161
// Update the indent level cache size so that we can rely on it
6262
// having the right size in adjustToUnmodifiedline.
6363
if (Line.Level >= IndentForLevel.size())
@@ -111,42 +111,41 @@ class LevelIndentTracker {
111111
///
112112
/// For example, 'public:' labels in classes are offset by 1 or 2
113113
/// characters to the left from their level.
114-
int getIndentOffset(const FormatToken &RootToken) {
114+
int getIndentOffset(const AnnotatedLine &Line) {
115115
if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript() ||
116116
Style.isCSharp()) {
117117
return 0;
118118
}
119119

120-
auto IsAccessModifier = [this, &RootToken]() {
121-
if (RootToken.isAccessSpecifier(Style.isCpp())) {
120+
auto IsAccessModifier = [&](const FormatToken &RootToken) {
121+
if (Line.Type == LT_AccessModifier || RootToken.isObjCAccessSpecifier())
122122
return true;
123-
} else if (RootToken.isObjCAccessSpecifier()) {
124-
return true;
125-
}
123+
124+
const auto *Next = RootToken.Next;
125+
126126
// Handle Qt signals.
127-
else if (RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
128-
RootToken.Next && RootToken.Next->is(tok::colon)) {
129-
return true;
130-
} else if (RootToken.Next &&
131-
RootToken.Next->isOneOf(Keywords.kw_slots,
132-
Keywords.kw_qslots) &&
133-
RootToken.Next->Next && RootToken.Next->Next->is(tok::colon)) {
127+
if (RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
128+
Next && Next->is(tok::colon)) {
134129
return true;
135130
}
136-
// Handle malformed access specifier e.g. 'private' without trailing ':'.
137-
else if (!RootToken.Next && RootToken.isAccessSpecifier(false)) {
131+
132+
if (Next && Next->isOneOf(Keywords.kw_slots, Keywords.kw_qslots) &&
133+
Next->Next && Next->Next->is(tok::colon)) {
138134
return true;
139135
}
140-
return false;
136+
137+
// Handle malformed access specifier e.g. 'private' without trailing ':'.
138+
return !Next && RootToken.isAccessSpecifier(false);
141139
};
142140

143-
if (IsAccessModifier()) {
141+
if (IsAccessModifier(*Line.First)) {
144142
// The AccessModifierOffset may be overridden by IndentAccessModifiers,
145143
// in which case we take a negative value of the IndentWidth to simulate
146144
// the upper indent level.
147145
return Style.IndentAccessModifiers ? -Style.IndentWidth
148146
: Style.AccessModifierOffset;
149147
}
148+
150149
return 0;
151150
}
152151

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,
368368
do {
369369
if (FormatTok->isAttribute()) {
370370
nextToken();
371+
if (FormatTok->is(tok::l_paren))
372+
parseParens();
371373
continue;
372374
}
373375
tok::TokenKind Kind = FormatTok->Tok.getKind();

clang/unittests/Format/FormatTest.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12912,6 +12912,15 @@ TEST_F(FormatTest, FormatsAccessModifiers) {
1291212912
" int j;\n"
1291312913
"};",
1291412914
Style);
12915+
Style.AttributeMacros.push_back("FOO");
12916+
Style.AttributeMacros.push_back("BAR");
12917+
verifyFormat("struct foo {\n"
12918+
"FOO private:\n"
12919+
" int i;\n"
12920+
"BAR(x) protected:\n"
12921+
" int j;\n"
12922+
"};",
12923+
Style);
1291512924

1291612925
FormatStyle NoEmptyLines = getLLVMStyle();
1291712926
NoEmptyLines.MaxEmptyLinesToKeep = 0;
@@ -26130,6 +26139,12 @@ TEST_F(FormatTest, IndentAccessModifiers) {
2613026139
" int i;\n"
2613126140
"};",
2613226141
Style);
26142+
Style.AttributeMacros.push_back("FOO");
26143+
verifyFormat("class C {\n"
26144+
" FOO public:\n"
26145+
" int i;\n"
26146+
"};",
26147+
Style);
2613326148
}
2613426149

2613526150
TEST_F(FormatTest, LimitlessStringsAndComments) {

0 commit comments

Comments
 (0)