@@ -116,6 +116,16 @@ static bool isCppAttribute(bool IsCpp, const FormatToken &Tok) {
116116 return AttrTok && AttrTok->startsSequence (tok::r_square, tok::r_square);
117117}
118118
119+ static bool isParametersKeyword (
120+ const FormatToken &Tok,
121+ const FormatStyle::KeywordedFunctionLikeMacro *declaration) {
122+ if (!declaration)
123+ return false ;
124+
125+ return std::find (declaration->Keywords .begin (), declaration->Keywords .end (),
126+ Tok.TokenText ) != declaration->Keywords .end ();
127+ }
128+
119129// / A parser that gathers additional information about tokens.
120130// /
121131// / The \c TokenAnnotator tries to match parenthesis and square brakets and
@@ -148,6 +158,32 @@ class AnnotatingParser {
148158 }
149159 }
150160
161+ const FormatStyle::KeywordedFunctionLikeMacro *
162+ findKeywordedFunctionLikeMacro () const {
163+ const FormatToken *TokBeforeFirstLParent = nullptr ;
164+ for (const FormatToken *T = Line.First ; T != Line.Last ; T = T->Next ) {
165+ if (T->Tok .is (tok::l_paren)) {
166+ TokBeforeFirstLParent = T->getPreviousNonComment ();
167+ break ;
168+ }
169+ }
170+
171+ // Unknown if line ends with ';', FunctionLikeOrFreestandingMacro otherwise.
172+ if (!TokBeforeFirstLParent ||
173+ !TokBeforeFirstLParent->isOneOf (TT_FunctionLikeOrFreestandingMacro,
174+ TT_Unknown)) {
175+ return nullptr ;
176+ }
177+ auto I = std::find_if (
178+ Style.KeywordedFunctionLikeMacros .begin (),
179+ Style.KeywordedFunctionLikeMacros .end (),
180+ [TokBeforeFirstLParent](
181+ const FormatStyle::KeywordedFunctionLikeMacro &Declaration) {
182+ return TokBeforeFirstLParent->TokenText == Declaration.Name ;
183+ });
184+ return I != Style.KeywordedFunctionLikeMacros .end () ? &*I : nullptr ;
185+ }
186+
151187 bool parseAngle () {
152188 if (!CurrentToken)
153189 return false ;
@@ -2415,8 +2451,12 @@ class AnnotatingParser {
24152451 Current.setType (TT_BinaryOperator);
24162452 } else if (isStartOfName (Current) &&
24172453 (!Line.MightBeFunctionDecl || Current.NestingLevel != 0 )) {
2418- Contexts.back ().FirstStartOfName = &Current;
2419- Current.setType (TT_StartOfName);
2454+ if (isParametersKeyword (Current, findKeywordedFunctionLikeMacro ())) {
2455+ Current.setType (TT_FunctionParameterKeyword);
2456+ } else {
2457+ Contexts.back ().FirstStartOfName = &Current;
2458+ Current.setType (TT_StartOfName);
2459+ }
24202460 } else if (Current.is (tok::semi)) {
24212461 // Reset FirstStartOfName after finding a semicolon so that a for loop
24222462 // with multiple increment statements is not confused with a for loop
@@ -6231,7 +6271,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
62316271 Right.Next ->isOneOf (TT_FunctionDeclarationName, tok::kw_const)));
62326272 }
62336273 if (Right.isOneOf (TT_StartOfName, TT_FunctionDeclarationName,
6234- TT_ClassHeadName, tok::kw_operator)) {
6274+ TT_FunctionParameterKeyword, TT_ClassHeadName,
6275+ tok::kw_operator)) {
62356276 return true ;
62366277 }
62376278 if (Right.isAttribute ())
0 commit comments