@@ -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 ) {
@@ -2324,37 +2331,166 @@ Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip, TemplateN
23242331 bool IsNestedTemplateArgumentList = !GreaterThanIsOperator;
23252332 GreaterThanIsOperatorScope G (GreaterThanIsOperator, false );
23262333
2334+ auto TrySkipTemplateArgument = [&]() {
2335+ bool NextIsTemplateId = false ;
2336+ unsigned TemplateDepth = 0 ;
2337+ while (true ) {
2338+ switch (Tok.getKind ()) {
2339+ case tok::eof:
2340+ case tok::annot_module_begin:
2341+ case tok::annot_module_end:
2342+ case tok::annot_module_include:
2343+ case tok::annot_repl_input_end:
2344+ case tok::semi:
2345+ return TPResult::False;
2346+
2347+ case tok::comma:
2348+ case tok::greater:
2349+ case tok::greatergreater:
2350+ case tok::greatergreatergreater:
2351+ return TPResult::True;
2352+
2353+ case tok::l_paren:
2354+ ConsumeParen ();
2355+ if (!SkipUntil (tok::r_paren, StopAtSemi))
2356+ return TPResult::Error;
2357+ break ;
2358+ case tok::l_brace:
2359+ ConsumeBrace ();
2360+ if (!SkipUntil (tok::r_brace, StopAtSemi))
2361+ return TPResult::Error;
2362+ break ;
2363+ case tok::l_square:
2364+ ConsumeBracket ();
2365+ if (!SkipUntil (tok::r_square, StopAtSemi))
2366+ return TPResult::Error;
2367+ break ;
2368+ case tok::question:
2369+ ConsumeToken ();
2370+ if (!SkipUntil (tok::colon, StopAtSemi))
2371+ return TPResult::Error;
2372+ break ;
2373+
2374+ #if 0
2375+ case tok::kw_template:
2376+ ConsumeToken();
2377+ NextIsTemplateId = true;
2378+ continue;
2379+ #endif
2380+ case tok::identifier:
2381+ ConsumeToken ();
2382+ #if 0
2383+ if (Tok.is(tok::less)) {
2384+ if (!NextIsTemplateId)
2385+ return TPResult::Ambiguous;
2386+ ConsumeToken();
2387+ if (!SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater}, StopAtSemi))
2388+ return TPResult::Error;
2389+ break;
2390+ }
2391+ #else
2392+ if (Tok.is (tok::less))
2393+ return TPResult::Ambiguous;
2394+ break ;
2395+ #endif
2396+
2397+ case tok::kw_operator:
2398+ if (TPResult TPR = TryParseNonConversionOperatorId ();
2399+ TPR == TPResult::Error) {
2400+ return TPResult::Error;
2401+ } else if (TPR == TPResult::True) {
2402+ if (Tok.is (tok::less))
2403+ return TPResult::Ambiguous;
2404+ }
2405+ break ;
2406+
2407+ #if 0
2408+ if (Tok.is(tok::less)) {
2409+ if (!NextIsTemplateId)
2410+ return TPResult::Ambiguous;
2411+ ConsumeToken();
2412+ if (!SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater}, StopAtSemi))
2413+ return TPResult::Error;
2414+ }
2415+ break;
2416+ #endif
2417+
2418+ case tok::kw_const_cast:
2419+ case tok::kw_dynamic_cast:
2420+ case tok::kw_reinterpret_cast:
2421+ case tok::kw_static_cast: {
2422+ ConsumeToken ();
2423+ if (!TryConsumeToken (tok::less))
2424+ return TPResult::Error;
2425+ bool MayHaveTrailingReturnType = Tok.is (tok::kw_auto);
2426+
2427+ while (true ) {
2428+ TPResult TPR = isCXXDeclarationSpecifier (ImplicitTypenameContext::Yes);
2429+ if (TPR == TPResult::False)
2430+ break ;
2431+ if (TPR == TPResult::Error ||
2432+ TryConsumeDeclarationSpecifier () == TPResult::Error)
2433+ return TPResult::Error;
2434+ }
2435+
2436+ if (TryParseDeclarator (
2437+ /* mayBeAbstract=*/ true ,
2438+ /* mayHaveIdentifier=*/ false ,
2439+ /* mayHaveDirectInit=*/ false ,
2440+ /* mayHaveTrailingReturnType=*/ MayHaveTrailingReturnType) == TPResult::Error)
2441+ return TPResult::Error;
2442+
2443+ if (!TryConsumeToken (tok::greater))
2444+ return TPResult::Error;
2445+ break ;
2446+ }
2447+ default :
2448+ ConsumeAnyToken ();
2449+ break ;
2450+ }
2451+ NextIsTemplateId = false ;
2452+ }
2453+ };
2454+
23272455 while (true ) {
23282456 // An expression cannot be followed by a braced-init-list unless
23292457 // its the right operand of an assignment operator.
23302458 if (Tok.is (tok::l_brace))
23312459 return TPResult::True;
23322460
2461+ if (TryAnnotateOptionalCXXScopeToken ())
2462+ return TPResult::Error;
2463+
23332464 bool InvalidAsTemplateArgumentList = false ;
2334- if (isCXXDeclarationSpecifier (ImplicitTypenameContext::No, TPResult::False,
2335- &InvalidAsTemplateArgumentList) ==
2336- TPResult::True)
2337- return TPResult::True;
2465+ TPResult TPR = isCXXDeclarationSpecifier (ImplicitTypenameContext::No,
2466+ /* BracedCastResult=*/ TPResult::Ambiguous,
2467+ &InvalidAsTemplateArgumentList);
23382468 if (InvalidAsTemplateArgumentList)
23392469 return TPResult::False;
23402470
2471+ if (TPR == TPResult::True)
2472+ return TPResult::True;
2473+
23412474 if (IsNestedTemplateArgumentList || TNK != TNK_Non_template)
23422475 break ;
23432476
2344- if (TryAnnotateOptionalCXXScopeToken ())
2345- return TPResult::Error;
2477+ if (TPR == TPResult::Ambiguous)
2478+ TryConsumeDeclarationSpecifier ();
2479+
2480+ TPR = TrySkipTemplateArgument ();
23462481
2347- if (! SkipUntil ({tok::comma, tok::less,
2348- tok::greater, tok::greatergreater, tok::greatergreatergreater},
2349- StopAtSemi | StopBeforeMatch) )
2482+ if (TPR == TPResult::Error)
2483+ return TPResult::Error;
2484+ else if (TPR == TPResult::False )
23502485 return TPResult::False;
23512486
2352- if (Tok. isNot (tok::comma)) {
2487+ if (! TryConsumeToken (tok::comma)) {
23532488 if (Tok.is (tok::less))
23542489 break ;
23552490 if (TryConsumeToken (tok::greater) && Tok.is (tok::coloncolon) &&
23562491 !NextToken ().isOneOf (tok::kw_new, tok::kw_delete)) {
23572492 TentativeParsingAction TPA (*this , /* Unannotated=*/ true );
2493+ Sema::TentativeAnalysisScope TAS (Actions);
23582494 if (isMissingTemplateKeywordBeforeScope (/* AnnotateInvalid=*/ false )) {
23592495 TPA.Revert ();
23602496 return TPResult::True;
@@ -2363,7 +2499,6 @@ Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip, TemplateN
23632499 }
23642500 return TPResult::Ambiguous;
23652501 }
2366- ConsumeToken ();
23672502 }
23682503
23692504 #if 0
0 commit comments