@@ -155,8 +155,8 @@ class AnnotatingParser {
155
155
if (NonTemplateLess.count (CurrentToken->Previous ) > 0 )
156
156
return false ;
157
157
158
- const FormatToken &Previous = *CurrentToken->Previous ; // The '<'.
159
- if ( Previous.Previous ) {
158
+ if ( const auto &Previous = *CurrentToken->Previous ; // The '<'.
159
+ Previous.Previous ) {
160
160
if (Previous.Previous ->Tok .isLiteral ())
161
161
return false ;
162
162
if (Previous.Previous ->is (tok::r_brace))
@@ -176,31 +176,38 @@ class AnnotatingParser {
176
176
FormatToken *Left = CurrentToken->Previous ;
177
177
Left->ParentBracket = Contexts.back ().ContextKind ;
178
178
ScopedContextCreator ContextCreator (*this , tok::less, 12 );
179
-
180
179
Contexts.back ().IsExpression = false ;
180
+
181
+ const auto *BeforeLess = Left->Previous ;
182
+
181
183
// If there's a template keyword before the opening angle bracket, this is a
182
184
// template parameter, not an argument.
183
- if (Left-> Previous && Left-> Previous ->isNot (tok::kw_template))
185
+ if (BeforeLess && BeforeLess ->isNot (tok::kw_template))
184
186
Contexts.back ().ContextType = Context::TemplateArgument;
185
187
186
188
if (Style .Language == FormatStyle::LK_Java &&
187
189
CurrentToken->is (tok::question)) {
188
190
next ();
189
191
}
190
192
191
- while (CurrentToken) {
193
+ for (bool SeenTernaryOperator = false ; CurrentToken;) {
194
+ const bool InExpr = Contexts[Contexts.size () - 2 ].IsExpression ;
192
195
if (CurrentToken->is (tok::greater)) {
196
+ const auto *Next = CurrentToken->Next ;
193
197
// Try to do a better job at looking for ">>" within the condition of
194
198
// a statement. Conservatively insert spaces between consecutive ">"
195
199
// tokens to prevent splitting right bitshift operators and potentially
196
200
// altering program semantics. This check is overly conservative and
197
201
// will prevent spaces from being inserted in select nested template
198
202
// parameter cases, but should not alter program semantics.
199
- if (CurrentToken-> Next && CurrentToken-> Next ->is (tok::greater) &&
203
+ if (Next && Next->is (tok::greater) &&
200
204
Left->ParentBracket != tok::less &&
201
205
CurrentToken->getStartOfNonWhitespace () ==
202
- CurrentToken->Next ->getStartOfNonWhitespace ().getLocWithOffset (
203
- -1 )) {
206
+ Next->getStartOfNonWhitespace ().getLocWithOffset (-1 )) {
207
+ return false ;
208
+ }
209
+ if (InExpr && SeenTernaryOperator &&
210
+ (!Next || !Next->isOneOf (tok::l_paren, tok::l_brace))) {
204
211
return false ;
205
212
}
206
213
Left->MatchingParen = CurrentToken;
@@ -211,14 +218,14 @@ class AnnotatingParser {
211
218
// msg: < item: data >
212
219
// In TT_TextProto, map<key, value> does not occur.
213
220
if (Style .Language == FormatStyle::LK_TextProto ||
214
- (Style .Language == FormatStyle::LK_Proto && Left-> Previous &&
215
- Left-> Previous ->isOneOf (TT_SelectorName, TT_DictLiteral))) {
221
+ (Style .Language == FormatStyle::LK_Proto && BeforeLess &&
222
+ BeforeLess ->isOneOf (TT_SelectorName, TT_DictLiteral))) {
216
223
CurrentToken->setType (TT_DictLiteral);
217
224
} else {
218
225
CurrentToken->setType (TT_TemplateCloser);
219
226
CurrentToken->Tok .setLength (1 );
220
227
}
221
- if (CurrentToken-> Next && CurrentToken-> Next ->Tok .isLiteral ())
228
+ if (Next && Next->Tok .isLiteral ())
222
229
return false ;
223
230
next ();
224
231
return true ;
@@ -230,18 +237,21 @@ class AnnotatingParser {
230
237
}
231
238
if (CurrentToken->isOneOf (tok::r_paren, tok::r_square, tok::r_brace))
232
239
return false ;
240
+ const auto &Prev = *CurrentToken->Previous ;
233
241
// If a && or || is found and interpreted as a binary operator, this set
234
242
// of angles is likely part of something like "a < b && c > d". If the
235
243
// angles are inside an expression, the ||/&& might also be a binary
236
244
// operator that was misinterpreted because we are parsing template
237
245
// parameters.
238
246
// FIXME: This is getting out of hand, write a decent parser.
239
- if (CurrentToken-> Previous -> isOneOf (tok::pipepipe, tok::ampamp ) &&
240
- CurrentToken-> Previous -> is (TT_BinaryOperator) &&
241
- Contexts[Contexts. size () - 2 ]. IsExpression &&
242
- !Line. startsWith (tok::kw_template)) {
243
- return false ;
247
+ if (InExpr && !Line. startsWith (tok::kw_template ) &&
248
+ Prev. is (TT_BinaryOperator)) {
249
+ const auto Precedence = Prev. getPrecedence ();
250
+ if (Precedence > prec::Conditional && Precedence < prec::Relational)
251
+ return false ;
244
252
}
253
+ if (Prev.is (TT_ConditionalExpr))
254
+ SeenTernaryOperator = true ;
245
255
updateParameterCount (Left, CurrentToken);
246
256
if (Style .Language == FormatStyle::LK_Proto) {
247
257
if (FormatToken *Previous = CurrentToken->getPreviousNonComment ()) {
0 commit comments