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