@@ -154,8 +154,8 @@ class AnnotatingParser {
154154 if (NonTemplateLess.count (CurrentToken->Previous ) > 0 )
155155 return false ;
156156
157- const FormatToken &Previous = *CurrentToken->Previous ; // The '<'.
158- if ( Previous.Previous ) {
157+ if ( const auto &Previous = *CurrentToken->Previous ; // The '<'.
158+ Previous.Previous ) {
159159 if (Previous.Previous ->Tok .isLiteral ())
160160 return false ;
161161 if (Previous.Previous ->is (tok::r_brace))
@@ -175,31 +175,38 @@ class AnnotatingParser {
175175 FormatToken *Left = CurrentToken->Previous ;
176176 Left->ParentBracket = Contexts.back ().ContextKind ;
177177 ScopedContextCreator ContextCreator (*this , tok::less, 12 );
178-
179178 Contexts.back ().IsExpression = false ;
179+
180+ const auto *BeforeLess = Left->Previous ;
181+
180182 // If there's a template keyword before the opening angle bracket, this is a
181183 // template parameter, not an argument.
182- if (Left-> Previous && Left-> Previous ->isNot (tok::kw_template))
184+ if (BeforeLess && BeforeLess ->isNot (tok::kw_template))
183185 Contexts.back ().ContextType = Context::TemplateArgument;
184186
185187 if (Style.Language == FormatStyle::LK_Java &&
186188 CurrentToken->is (tok::question)) {
187189 next ();
188190 }
189191
190- while (CurrentToken) {
192+ for (bool SeenTernaryOperator = false ; CurrentToken;) {
193+ const bool InExpr = Contexts[Contexts.size () - 2 ].IsExpression ;
191194 if (CurrentToken->is (tok::greater)) {
195+ const auto *Next = CurrentToken->Next ;
192196 // Try to do a better job at looking for ">>" within the condition of
193197 // a statement. Conservatively insert spaces between consecutive ">"
194198 // tokens to prevent splitting right bitshift operators and potentially
195199 // altering program semantics. This check is overly conservative and
196200 // will prevent spaces from being inserted in select nested template
197201 // parameter cases, but should not alter program semantics.
198- if (CurrentToken-> Next && CurrentToken-> Next ->is (tok::greater) &&
202+ if (Next && Next->is (tok::greater) &&
199203 Left->ParentBracket != tok::less &&
200204 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))) {
203210 return false ;
204211 }
205212 Left->MatchingParen = CurrentToken;
@@ -210,14 +217,14 @@ class AnnotatingParser {
210217 // msg: < item: data >
211218 // In TT_TextProto, map<key, value> does not occur.
212219 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))) {
215222 CurrentToken->setType (TT_DictLiteral);
216223 } else {
217224 CurrentToken->setType (TT_TemplateCloser);
218225 CurrentToken->Tok .setLength (1 );
219226 }
220- if (CurrentToken-> Next && CurrentToken-> Next ->Tok .isLiteral ())
227+ if (Next && Next->Tok .isLiteral ())
221228 return false ;
222229 next ();
223230 return true ;
@@ -229,18 +236,21 @@ class AnnotatingParser {
229236 }
230237 if (CurrentToken->isOneOf (tok::r_paren, tok::r_square, tok::r_brace))
231238 return false ;
239+ const auto &Prev = *CurrentToken->Previous ;
232240 // If a && or || is found and interpreted as a binary operator, this set
233241 // of angles is likely part of something like "a < b && c > d". If the
234242 // angles are inside an expression, the ||/&& might also be a binary
235243 // operator that was misinterpreted because we are parsing template
236244 // parameters.
237245 // 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 ;
243251 }
252+ if (Prev.is (TT_ConditionalExpr))
253+ SeenTernaryOperator = true ;
244254 updateParameterCount (Left, CurrentToken);
245255 if (Style.Language == FormatStyle::LK_Proto) {
246256 if (FormatToken *Previous = CurrentToken->getPreviousNonComment ()) {
0 commit comments