@@ -955,7 +955,7 @@ Parser::TPResult Parser::TryParsePtrOperatorSeq() {
955955// / literal-operator-id:
956956// / 'operator' string-literal identifier
957957// / 'operator' user-defined-string-literal
958- Parser::TPResult Parser::TryParseOperatorId () {
958+ Parser::TPResult Parser::TryParseNonConversionOperatorId () {
959959 assert (Tok.is (tok::kw_operator));
960960 ConsumeToken ();
961961
@@ -1013,6 +1013,13 @@ Parser::TPResult Parser::TryParseOperatorId() {
10131013 return TPResult::True;
10141014 }
10151015
1016+ return TPResult::False;
1017+ }
1018+ Parser::TPResult Parser::TryParseOperatorId () {
1019+ if (TPResult TPR = TryParseNonConversionOperatorId ();
1020+ TPR != TPResult::False)
1021+ return TPR;
1022+
10161023 // Maybe this is a conversion-function-id.
10171024 bool AnyDeclSpecifiers = false ;
10181025 while (true ) {
@@ -2328,37 +2335,166 @@ Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip, TemplateN
23282335 bool IsNestedTemplateArgumentList = !GreaterThanIsOperator;
23292336 GreaterThanIsOperatorScope G (GreaterThanIsOperator, false );
23302337
2338+ auto TrySkipTemplateArgument = [&]() {
2339+ bool NextIsTemplateId = false ;
2340+ unsigned TemplateDepth = 0 ;
2341+ while (true ) {
2342+ switch (Tok.getKind ()) {
2343+ case tok::eof:
2344+ case tok::annot_module_begin:
2345+ case tok::annot_module_end:
2346+ case tok::annot_module_include:
2347+ case tok::annot_repl_input_end:
2348+ case tok::semi:
2349+ return TPResult::False;
2350+
2351+ case tok::comma:
2352+ case tok::greater:
2353+ case tok::greatergreater:
2354+ case tok::greatergreatergreater:
2355+ return TPResult::True;
2356+
2357+ case tok::l_paren:
2358+ ConsumeParen ();
2359+ if (!SkipUntil (tok::r_paren, StopAtSemi))
2360+ return TPResult::Error;
2361+ break ;
2362+ case tok::l_brace:
2363+ ConsumeBrace ();
2364+ if (!SkipUntil (tok::r_brace, StopAtSemi))
2365+ return TPResult::Error;
2366+ break ;
2367+ case tok::l_square:
2368+ ConsumeBracket ();
2369+ if (!SkipUntil (tok::r_square, StopAtSemi))
2370+ return TPResult::Error;
2371+ break ;
2372+ case tok::question:
2373+ ConsumeToken ();
2374+ if (!SkipUntil (tok::colon, StopAtSemi))
2375+ return TPResult::Error;
2376+ break ;
2377+
2378+ #if 0
2379+ case tok::kw_template:
2380+ ConsumeToken();
2381+ NextIsTemplateId = true;
2382+ continue;
2383+ #endif
2384+ case tok::identifier:
2385+ ConsumeToken ();
2386+ #if 0
2387+ if (Tok.is(tok::less)) {
2388+ if (!NextIsTemplateId)
2389+ return TPResult::Ambiguous;
2390+ ConsumeToken();
2391+ if (!SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater}, StopAtSemi))
2392+ return TPResult::Error;
2393+ break;
2394+ }
2395+ #else
2396+ if (Tok.is (tok::less))
2397+ return TPResult::Ambiguous;
2398+ break ;
2399+ #endif
2400+
2401+ case tok::kw_operator:
2402+ if (TPResult TPR = TryParseNonConversionOperatorId ();
2403+ TPR == TPResult::Error) {
2404+ return TPResult::Error;
2405+ } else if (TPR == TPResult::True) {
2406+ if (Tok.is (tok::less))
2407+ return TPResult::Ambiguous;
2408+ }
2409+ break ;
2410+
2411+ #if 0
2412+ if (Tok.is(tok::less)) {
2413+ if (!NextIsTemplateId)
2414+ return TPResult::Ambiguous;
2415+ ConsumeToken();
2416+ if (!SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater}, StopAtSemi))
2417+ return TPResult::Error;
2418+ }
2419+ break;
2420+ #endif
2421+
2422+ case tok::kw_const_cast:
2423+ case tok::kw_dynamic_cast:
2424+ case tok::kw_reinterpret_cast:
2425+ case tok::kw_static_cast: {
2426+ ConsumeToken ();
2427+ if (!TryConsumeToken (tok::less))
2428+ return TPResult::Error;
2429+ bool MayHaveTrailingReturnType = Tok.is (tok::kw_auto);
2430+
2431+ while (true ) {
2432+ TPResult TPR = isCXXDeclarationSpecifier (ImplicitTypenameContext::Yes);
2433+ if (TPR == TPResult::False)
2434+ break ;
2435+ if (TPR == TPResult::Error ||
2436+ TryConsumeDeclarationSpecifier () == TPResult::Error)
2437+ return TPResult::Error;
2438+ }
2439+
2440+ if (TryParseDeclarator (
2441+ /* mayBeAbstract=*/ true ,
2442+ /* mayHaveIdentifier=*/ false ,
2443+ /* mayHaveDirectInit=*/ false ,
2444+ /* mayHaveTrailingReturnType=*/ MayHaveTrailingReturnType) == TPResult::Error)
2445+ return TPResult::Error;
2446+
2447+ if (!TryConsumeToken (tok::greater))
2448+ return TPResult::Error;
2449+ break ;
2450+ }
2451+ default :
2452+ ConsumeAnyToken ();
2453+ break ;
2454+ }
2455+ NextIsTemplateId = false ;
2456+ }
2457+ };
2458+
23312459 while (true ) {
23322460 // An expression cannot be followed by a braced-init-list unless
23332461 // its the right operand of an assignment operator.
23342462 if (Tok.is (tok::l_brace))
23352463 return TPResult::True;
23362464
2465+ if (TryAnnotateOptionalCXXScopeToken ())
2466+ return TPResult::Error;
2467+
23372468 bool InvalidAsTemplateArgumentList = false ;
2338- if (isCXXDeclarationSpecifier (ImplicitTypenameContext::No, TPResult::False,
2339- &InvalidAsTemplateArgumentList) ==
2340- TPResult::True)
2341- return TPResult::True;
2469+ TPResult TPR = isCXXDeclarationSpecifier (ImplicitTypenameContext::No,
2470+ /* BracedCastResult=*/ TPResult::Ambiguous,
2471+ &InvalidAsTemplateArgumentList);
23422472 if (InvalidAsTemplateArgumentList)
23432473 return TPResult::False;
23442474
2475+ if (TPR == TPResult::True)
2476+ return TPResult::True;
2477+
23452478 if (IsNestedTemplateArgumentList || TNK != TNK_Non_template)
23462479 break ;
23472480
2348- if (TryAnnotateOptionalCXXScopeToken ())
2349- return TPResult::Error;
2481+ if (TPR == TPResult::Ambiguous)
2482+ TryConsumeDeclarationSpecifier ();
2483+
2484+ TPR = TrySkipTemplateArgument ();
23502485
2351- if (! SkipUntil ({tok::comma, tok::less,
2352- tok::greater, tok::greatergreater, tok::greatergreatergreater},
2353- StopAtSemi | StopBeforeMatch) )
2486+ if (TPR == TPResult::Error)
2487+ return TPResult::Error;
2488+ else if (TPR == TPResult::False )
23542489 return TPResult::False;
23552490
2356- if (Tok. isNot (tok::comma)) {
2491+ if (! TryConsumeToken (tok::comma)) {
23572492 if (Tok.is (tok::less))
23582493 break ;
23592494 if (TryConsumeToken (tok::greater) && Tok.is (tok::coloncolon) &&
23602495 !NextToken ().isOneOf (tok::kw_new, tok::kw_delete)) {
23612496 TentativeParsingAction TPA (*this , /* Unannotated=*/ true );
2497+ Sema::TentativeAnalysisScope TAS (Actions);
23622498 if (isMissingTemplateKeywordBeforeScope (/* AnnotateInvalid=*/ false )) {
23632499 TPA.Revert ();
23642500 return TPResult::True;
@@ -2367,7 +2503,6 @@ Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip, TemplateN
23672503 }
23682504 return TPResult::Ambiguous;
23692505 }
2370- ConsumeToken ();
23712506 }
23722507
23732508 #if 0
0 commit comments