brintos

brintos / llvm-project-archived public Read only

0
0
Text · 68.4 KiB · 82f2294 Raw
2023 lines · cpp
1//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//  This file implements the tentative parsing portions of the Parser10//  interfaces, for ambiguity resolution.11//12//===----------------------------------------------------------------------===//13 14#include "clang/Parse/Parser.h"15#include "clang/Sema/ParsedTemplate.h"16using namespace clang;17 18bool Parser::isCXXDeclarationStatement(19    bool DisambiguatingWithExpression /*=false*/) {20  assert(getLangOpts().CPlusPlus && "Must be called for C++ only.");21 22  switch (Tok.getKind()) {23    // asm-definition24  case tok::kw_asm:25    // namespace-alias-definition26  case tok::kw_namespace:27    // using-declaration28    // using-directive29  case tok::kw_using:30    // static_assert-declaration31  case tok::kw_static_assert:32  case tok::kw__Static_assert:33    return true;34  case tok::coloncolon:35  case tok::identifier: {36    if (DisambiguatingWithExpression) {37      RevertingTentativeParsingAction TPA(*this);38      // Parse the C++ scope specifier.39      CXXScopeSpec SS;40      ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,41                                     /*ObjectHasErrors=*/false,42                                     /*EnteringContext=*/true);43 44      switch (Tok.getKind()) {45      case tok::identifier: {46        IdentifierInfo *II = Tok.getIdentifierInfo();47        bool isDeductionGuide = Actions.isDeductionGuideName(48            getCurScope(), *II, Tok.getLocation(), SS, /*Template=*/nullptr);49        if (Actions.isCurrentClassName(*II, getCurScope(), &SS) ||50            isDeductionGuide) {51          if (isConstructorDeclarator(52                  /*Unqualified=*/SS.isEmpty(), isDeductionGuide,53                  /*IsFriend=*/DeclSpec::FriendSpecified::No))54            return true;55        } else if (SS.isNotEmpty()) {56          // If the scope is not empty, it could alternatively be something like57          // a typedef or using declaration. That declaration might be private58          // in the global context, which would be diagnosed by calling into59          // isCXXSimpleDeclaration, but may actually be fine in the context of60          // member functions and static variable definitions. Check if the next61          // token is also an identifier and assume a declaration.62          // We cannot check if the scopes match because the declarations could63          // involve namespaces and friend declarations.64          if (NextToken().is(tok::identifier))65            return true;66        }67        break;68      }69      case tok::kw_operator:70        return true;71      case tok::tilde:72        return true;73      default:74        break;75      }76    }77  }78    [[fallthrough]];79    // simple-declaration80  default:81    return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);82  }83}84 85bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {86  // C++ 6.8p1:87  // There is an ambiguity in the grammar involving expression-statements and88  // declarations: An expression-statement with a function-style explicit type89  // conversion (5.2.3) as its leftmost subexpression can be indistinguishable90  // from a declaration where the first declarator starts with a '('. In those91  // cases the statement is a declaration. [Note: To disambiguate, the whole92  // statement might have to be examined to determine if it is an93  // expression-statement or a declaration].94 95  // C++ 6.8p3:96  // The disambiguation is purely syntactic; that is, the meaning of the names97  // occurring in such a statement, beyond whether they are type-names or not,98  // is not generally used in or changed by the disambiguation. Class99  // templates are instantiated as necessary to determine if a qualified name100  // is a type-name. Disambiguation precedes parsing, and a statement101  // disambiguated as a declaration may be an ill-formed declaration.102 103  // We don't have to parse all of the decl-specifier-seq part. There's only104  // an ambiguity if the first decl-specifier is105  // simple-type-specifier/typename-specifier followed by a '(', which may106  // indicate a function-style cast expression.107  // isCXXDeclarationSpecifier will return TPResult::Ambiguous only in such108  // a case.109 110  bool InvalidAsDeclaration = false;111  TPResult TPR = isCXXDeclarationSpecifier(112      ImplicitTypenameContext::No, TPResult::False, &InvalidAsDeclaration);113  if (TPR != TPResult::Ambiguous)114    return TPR != TPResult::False; // Returns true for TPResult::True or115                                   // TPResult::Error.116 117  // FIXME: TryParseSimpleDeclaration doesn't look past the first initializer,118  // and so gets some cases wrong. We can't carry on if we've already seen119  // something which makes this statement invalid as a declaration in this case,120  // since it can cause us to misparse valid code. Revisit this once121  // TryParseInitDeclaratorList is fixed.122  if (InvalidAsDeclaration)123    return false;124 125  // FIXME: Add statistics about the number of ambiguous statements encountered126  // and how they were resolved (number of declarations+number of expressions).127 128  // Ok, we have a simple-type-specifier/typename-specifier followed by a '(',129  // or an identifier which doesn't resolve as anything. We need tentative130  // parsing...131 132  {133    RevertingTentativeParsingAction PA(*this);134    TPR = TryParseSimpleDeclaration(AllowForRangeDecl);135  }136 137  // In case of an error, let the declaration parsing code handle it.138  if (TPR == TPResult::Error)139    return true;140 141  // Declarations take precedence over expressions.142  if (TPR == TPResult::Ambiguous)143    TPR = TPResult::True;144 145  assert(TPR == TPResult::True || TPR == TPResult::False);146  return TPR == TPResult::True;147}148 149Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {150  switch (Tok.getKind()) {151  case tok::kw__Atomic:152    if (NextToken().isNot(tok::l_paren)) {153      ConsumeToken();154      break;155    }156    [[fallthrough]];157  case tok::kw_typeof:158  case tok::kw___attribute:159#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:160#include "clang/Basic/TransformTypeTraits.def"161  {162    ConsumeToken();163    if (Tok.isNot(tok::l_paren))164      return TPResult::Error;165    ConsumeParen();166    if (!SkipUntil(tok::r_paren))167      return TPResult::Error;168    break;169  }170 171  case tok::kw_class:172  case tok::kw_struct:173  case tok::kw_union:174  case tok::kw___interface:175  case tok::kw_enum:176    // elaborated-type-specifier:177    //     class-key attribute-specifier-seq[opt]178    //         nested-name-specifier[opt] identifier179    //     class-key nested-name-specifier[opt] template[opt] simple-template-id180    //     enum nested-name-specifier[opt] identifier181    //182    // FIXME: We don't support class-specifiers nor enum-specifiers here.183    ConsumeToken();184 185    // Skip attributes.186    if (!TrySkipAttributes())187      return TPResult::Error;188 189    if (TryAnnotateOptionalCXXScopeToken())190      return TPResult::Error;191    if (Tok.is(tok::annot_cxxscope))192      ConsumeAnnotationToken();193    if (Tok.is(tok::identifier))194      ConsumeToken();195    else if (Tok.is(tok::annot_template_id))196      ConsumeAnnotationToken();197    else198      return TPResult::Error;199    break;200 201  case tok::annot_cxxscope:202    ConsumeAnnotationToken();203    [[fallthrough]];204  default:205    ConsumeAnyToken();206 207    if (getLangOpts().ObjC && Tok.is(tok::less))208      return TryParseProtocolQualifiers();209    break;210  }211 212  return TPResult::Ambiguous;213}214 215Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {216  bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);217  if (TryConsumeDeclarationSpecifier() == TPResult::Error)218    return TPResult::Error;219 220  // Two decl-specifiers in a row conclusively disambiguate this as being a221  // simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the222  // overwhelmingly common case that the next token is a '('.223  if (Tok.isNot(tok::l_paren)) {224    TPResult TPR = isCXXDeclarationSpecifier(ImplicitTypenameContext::No);225    if (TPR == TPResult::Ambiguous)226      return TPResult::True;227    if (TPR == TPResult::True || TPR == TPResult::Error)228      return TPR;229    assert(TPR == TPResult::False);230  }231 232  TPResult TPR = TryParseInitDeclaratorList(233      /*mayHaveTrailingReturnType=*/DeclSpecifierIsAuto);234  if (TPR != TPResult::Ambiguous)235    return TPR;236 237  if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))238    return TPResult::False;239 240  return TPResult::Ambiguous;241}242 243Parser::TPResult244Parser::TryParseInitDeclaratorList(bool MayHaveTrailingReturnType) {245  while (true) {246    // declarator247    TPResult TPR = TryParseDeclarator(248        /*mayBeAbstract=*/false,249        /*mayHaveIdentifier=*/true,250        /*mayHaveDirectInit=*/false,251        /*mayHaveTrailingReturnType=*/MayHaveTrailingReturnType);252    if (TPR != TPResult::Ambiguous)253      return TPR;254 255    // [GNU] simple-asm-expr[opt] attributes[opt]256    if (Tok.isOneOf(tok::kw_asm, tok::kw___attribute))257      return TPResult::True;258 259    // initializer[opt]260    if (Tok.is(tok::l_paren)) {261      // Parse through the parens.262      ConsumeParen();263      if (!SkipUntil(tok::r_paren, StopAtSemi))264        return TPResult::Error;265    } else if (Tok.is(tok::l_brace)) {266      // A left-brace here is sufficient to disambiguate the parse; an267      // expression can never be followed directly by a braced-init-list.268      return TPResult::True;269    } else if (Tok.is(tok::equal) || isTokIdentifier_in()) {270      // MSVC and g++ won't examine the rest of declarators if '=' is271      // encountered; they just conclude that we have a declaration.272      // EDG parses the initializer completely, which is the proper behavior273      // for this case.274      //275      // At present, Clang follows MSVC and g++, since the parser does not have276      // the ability to parse an expression fully without recording the277      // results of that parse.278      // FIXME: Handle this case correctly.279      //280      // Also allow 'in' after an Objective-C declaration as in:281      // for (int (^b)(void) in array). Ideally this should be done in the282      // context of parsing for-init-statement of a foreach statement only. But,283      // in any other context 'in' is invalid after a declaration and parser284      // issues the error regardless of outcome of this decision.285      // FIXME: Change if above assumption does not hold.286      return TPResult::True;287    }288 289    if (!TryConsumeToken(tok::comma))290      break;291  }292 293  return TPResult::Ambiguous;294}295 296struct Parser::ConditionDeclarationOrInitStatementState {297  Parser &P;298  bool CanBeExpression = true;299  bool CanBeCondition = true;300  bool CanBeInitStatement;301  bool CanBeForRangeDecl;302 303  ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement,304                                           bool CanBeForRangeDecl)305      : P(P), CanBeInitStatement(CanBeInitStatement),306        CanBeForRangeDecl(CanBeForRangeDecl) {}307 308  bool resolved() {309    return CanBeExpression + CanBeCondition + CanBeInitStatement +310               CanBeForRangeDecl < 2;311  }312 313  void markNotExpression() {314    CanBeExpression = false;315 316    if (!resolved()) {317      // FIXME: Unify the parsing codepaths for condition variables and318      // simple-declarations so that we don't need to eagerly figure out which319      // kind we have here. (Just parse init-declarators until we reach a320      // semicolon or right paren.)321      RevertingTentativeParsingAction PA(P);322      if (CanBeForRangeDecl) {323        // Skip until we hit a ')', ';', or a ':' with no matching '?'.324        // The final case is a for range declaration, the rest are not.325        unsigned QuestionColonDepth = 0;326        while (true) {327          P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},328                      StopBeforeMatch);329          if (P.Tok.is(tok::question))330            ++QuestionColonDepth;331          else if (P.Tok.is(tok::colon)) {332            if (QuestionColonDepth)333              --QuestionColonDepth;334            else {335              CanBeCondition = CanBeInitStatement = false;336              return;337            }338          } else {339            CanBeForRangeDecl = false;340            break;341          }342          P.ConsumeToken();343        }344      } else {345        // Just skip until we hit a ')' or ';'.346        P.SkipUntil(tok::r_paren, tok::semi, StopBeforeMatch);347      }348      if (P.Tok.isNot(tok::r_paren))349        CanBeCondition = CanBeForRangeDecl = false;350      if (P.Tok.isNot(tok::semi))351        CanBeInitStatement = false;352    }353  }354 355  bool markNotCondition() {356    CanBeCondition = false;357    return resolved();358  }359 360  bool markNotForRangeDecl() {361    CanBeForRangeDecl = false;362    return resolved();363  }364 365  bool update(TPResult IsDecl) {366    switch (IsDecl) {367    case TPResult::True:368      markNotExpression();369      assert(resolved() && "can't continue after tentative parsing bails out");370      break;371    case TPResult::False:372      CanBeCondition = CanBeInitStatement = CanBeForRangeDecl = false;373      break;374    case TPResult::Ambiguous:375      break;376    case TPResult::Error:377      CanBeExpression = CanBeCondition = CanBeInitStatement =378          CanBeForRangeDecl = false;379      break;380    }381    return resolved();382  }383 384  ConditionOrInitStatement result() const {385    assert(CanBeExpression + CanBeCondition + CanBeInitStatement +386                   CanBeForRangeDecl < 2 &&387           "result called but not yet resolved");388    if (CanBeExpression)389      return ConditionOrInitStatement::Expression;390    if (CanBeCondition)391      return ConditionOrInitStatement::ConditionDecl;392    if (CanBeInitStatement)393      return ConditionOrInitStatement::InitStmtDecl;394    if (CanBeForRangeDecl)395      return ConditionOrInitStatement::ForRangeDecl;396    return ConditionOrInitStatement::Error;397  }398};399 400bool Parser::isEnumBase(bool AllowSemi) {401  assert(Tok.is(tok::colon) && "should be looking at the ':'");402 403  RevertingTentativeParsingAction PA(*this);404  // ':'405  ConsumeToken();406 407  // type-specifier-seq408  bool InvalidAsDeclSpec = false;409  // FIXME: We could disallow non-type decl-specifiers here, but it makes no410  // difference: those specifiers are ill-formed regardless of the411  // interpretation.412  TPResult R = isCXXDeclarationSpecifier(ImplicitTypenameContext::No,413                                         /*BracedCastResult=*/TPResult::True,414                                         &InvalidAsDeclSpec);415  if (R == TPResult::Ambiguous) {416    // We either have a decl-specifier followed by '(' or an undeclared417    // identifier.418    if (TryConsumeDeclarationSpecifier() == TPResult::Error)419      return true;420 421    // If we get to the end of the enum-base, we hit either a '{' or a ';'.422    // Don't bother checking the enumerator-list.423    if (Tok.is(tok::l_brace) || (AllowSemi && Tok.is(tok::semi)))424      return true;425 426    // A second decl-specifier unambiguously indicatges an enum-base.427    R = isCXXDeclarationSpecifier(ImplicitTypenameContext::No, TPResult::True,428                                  &InvalidAsDeclSpec);429  }430 431  return R != TPResult::False;432}433 434Parser::ConditionOrInitStatement435Parser::isCXXConditionDeclarationOrInitStatement(bool CanBeInitStatement,436                                                 bool CanBeForRangeDecl) {437  ConditionDeclarationOrInitStatementState State(*this, CanBeInitStatement,438                                                 CanBeForRangeDecl);439 440  if (CanBeInitStatement && Tok.is(tok::kw_using))441    return ConditionOrInitStatement::InitStmtDecl;442  if (State.update(isCXXDeclarationSpecifier(ImplicitTypenameContext::No)))443    return State.result();444 445  // It might be a declaration; we need tentative parsing.446  RevertingTentativeParsingAction PA(*this);447 448  // FIXME: A tag definition unambiguously tells us this is an init-statement.449  bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);450  if (State.update(TryConsumeDeclarationSpecifier()))451    return State.result();452  assert(Tok.is(tok::l_paren) && "Expected '('");453 454  while (true) {455    // Consume a declarator.456    if (State.update(TryParseDeclarator(457            /*mayBeAbstract=*/false,458            /*mayHaveIdentifier=*/true,459            /*mayHaveDirectInit=*/false,460            /*mayHaveTrailingReturnType=*/MayHaveTrailingReturnType)))461      return State.result();462 463    // Attributes, asm label, or an initializer imply this is not an expression.464    // FIXME: Disambiguate properly after an = instead of assuming that it's a465    // valid declaration.466    if (Tok.isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||467        (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))) {468      State.markNotExpression();469      return State.result();470    }471 472    // A colon here identifies a for-range declaration.473    if (State.CanBeForRangeDecl && Tok.is(tok::colon))474      return ConditionOrInitStatement::ForRangeDecl;475 476    // At this point, it can't be a condition any more, because a condition477    // must have a brace-or-equal-initializer.478    if (State.markNotCondition())479      return State.result();480 481    // Likewise, it can't be a for-range declaration any more.482    if (State.markNotForRangeDecl())483      return State.result();484 485    // A parenthesized initializer could be part of an expression or a486    // simple-declaration.487    if (Tok.is(tok::l_paren)) {488      ConsumeParen();489      SkipUntil(tok::r_paren, StopAtSemi);490    }491 492    if (!TryConsumeToken(tok::comma))493      break;494  }495 496  // We reached the end. If it can now be some kind of decl, then it is.497  if (State.CanBeCondition && Tok.is(tok::r_paren))498    return ConditionOrInitStatement::ConditionDecl;499  else if (State.CanBeInitStatement && Tok.is(tok::semi))500    return ConditionOrInitStatement::InitStmtDecl;501  else502    return ConditionOrInitStatement::Expression;503}504 505bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {506 507  isAmbiguous = false;508 509  // C++ 8.2p2:510  // The ambiguity arising from the similarity between a function-style cast and511  // a type-id can occur in different contexts. The ambiguity appears as a512  // choice between a function-style cast expression and a declaration of a513  // type. The resolution is that any construct that could possibly be a type-id514  // in its syntactic context shall be considered a type-id.515 516  TPResult TPR = isCXXDeclarationSpecifier(ImplicitTypenameContext::No);517  if (TPR != TPResult::Ambiguous)518    return TPR != TPResult::False; // Returns true for TPResult::True or519                                     // TPResult::Error.520 521  // FIXME: Add statistics about the number of ambiguous statements encountered522  // and how they were resolved (number of declarations+number of expressions).523 524  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.525  // We need tentative parsing...526 527  RevertingTentativeParsingAction PA(*this);528  bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);529 530  // type-specifier-seq531  TryConsumeDeclarationSpecifier();532  assert(Tok.is(tok::l_paren) && "Expected '('");533 534  // declarator535  TPR = TryParseDeclarator(true /*mayBeAbstract*/, false /*mayHaveIdentifier*/,536                           /*mayHaveDirectInit=*/false,537                           MayHaveTrailingReturnType);538 539  // In case of an error, let the declaration parsing code handle it.540  if (TPR == TPResult::Error)541    TPR = TPResult::True;542 543  if (TPR == TPResult::Ambiguous) {544    // We are supposed to be inside parens, so if after the abstract declarator545    // we encounter a ')' this is a type-id, otherwise it's an expression.546    if (Context == TentativeCXXTypeIdContext::InParens &&547        Tok.is(tok::r_paren)) {548      TPR = TPResult::True;549      isAmbiguous = true;550    // We are supposed to be inside the first operand to a _Generic selection551    // expression, so if we find a comma after the declarator, we've found a552    // type and not an expression.553    } else if (Context ==554                   TentativeCXXTypeIdContext::AsGenericSelectionArgument &&555               Tok.is(tok::comma)) {556      TPR = TPResult::True;557      isAmbiguous = true;558    // We are supposed to be inside a template argument, so if after559    // the abstract declarator we encounter a '>', '>>' (in C++0x), or560    // ','; or, in C++0x, an ellipsis immediately preceding such, this561    // is a type-id. Otherwise, it's an expression.562    } else if (Context == TentativeCXXTypeIdContext::AsTemplateArgument &&563               (Tok.isOneOf(tok::greater, tok::comma) ||564                (getLangOpts().CPlusPlus11 &&565                 (Tok.isOneOf(tok::greatergreater,566                              tok::greatergreatergreater) ||567                  (Tok.is(tok::ellipsis) &&568                   NextToken().isOneOf(tok::greater, tok::greatergreater,569                                       tok::greatergreatergreater,570                                       tok::comma)))))) {571      TPR = TPResult::True;572      isAmbiguous = true;573 574    } else if (Context == TentativeCXXTypeIdContext::InTrailingReturnType) {575      TPR = TPResult::True;576      isAmbiguous = true;577    } else578      TPR = TPResult::False;579  }580 581  assert(TPR == TPResult::True || TPR == TPResult::False);582  return TPR == TPResult::True;583}584 585CXX11AttributeKind586Parser::isCXX11AttributeSpecifier(bool Disambiguate,587                                  bool OuterMightBeMessageSend) {588  // alignas is an attribute specifier in C++ but not in C23.589  if (Tok.is(tok::kw_alignas) && !getLangOpts().C23)590    return CXX11AttributeKind::AttributeSpecifier;591 592  if (Tok.isRegularKeywordAttribute())593    return CXX11AttributeKind::AttributeSpecifier;594 595  if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square))596    return CXX11AttributeKind::NotAttributeSpecifier;597 598  // No tentative parsing if we don't need to look for ']]' or a lambda.599  if (!Disambiguate && !getLangOpts().ObjC)600    return CXX11AttributeKind::AttributeSpecifier;601 602  // '[[using ns: ...]]' is an attribute.603  if (GetLookAheadToken(2).is(tok::kw_using))604    return CXX11AttributeKind::AttributeSpecifier;605 606  RevertingTentativeParsingAction PA(*this);607 608  // Opening brackets were checked for above.609  ConsumeBracket();610 611  if (!getLangOpts().ObjC) {612    ConsumeBracket();613 614    bool IsAttribute = SkipUntil(tok::r_square);615    IsAttribute &= Tok.is(tok::r_square);616 617    return IsAttribute ? CXX11AttributeKind::AttributeSpecifier618                       : CXX11AttributeKind::InvalidAttributeSpecifier;619  }620 621  // In Obj-C++11, we need to distinguish four situations:622  //  1a) int x[[attr]];                     C++11 attribute.623  //  1b) [[attr]];                          C++11 statement attribute.624  //   2) int x[[obj](){ return 1; }()];     Lambda in array size/index.625  //  3a) int x[[obj get]];                  Message send in array size/index.626  //  3b) [[Class alloc] init];              Message send in message send.627  //   4) [[obj]{ return self; }() doStuff]; Lambda in message send.628  // (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted.629 630  // Check to see if this is a lambda-expression.631  // FIXME: If this disambiguation is too slow, fold the tentative lambda parse632  // into the tentative attribute parse below.633  {634    RevertingTentativeParsingAction LambdaTPA(*this);635    LambdaIntroducer Intro;636    LambdaIntroducerTentativeParse Tentative;637    if (ParseLambdaIntroducer(Intro, &Tentative)) {638      // We hit a hard error after deciding this was not an attribute.639      // FIXME: Don't parse and annotate expressions when disambiguating640      // against an attribute.641      return CXX11AttributeKind::NotAttributeSpecifier;642    }643 644    switch (Tentative) {645    case LambdaIntroducerTentativeParse::MessageSend:646      // Case 3: The inner construct is definitely a message send, so the647      // outer construct is definitely not an attribute.648      return CXX11AttributeKind::NotAttributeSpecifier;649 650    case LambdaIntroducerTentativeParse::Success:651    case LambdaIntroducerTentativeParse::Incomplete:652      // This is a lambda-introducer or attribute-specifier.653      if (Tok.is(tok::r_square))654        // Case 1: C++11 attribute.655        return CXX11AttributeKind::AttributeSpecifier;656 657      if (OuterMightBeMessageSend)658        // Case 4: Lambda in message send.659        return CXX11AttributeKind::NotAttributeSpecifier;660 661      // Case 2: Lambda in array size / index.662      return CXX11AttributeKind::InvalidAttributeSpecifier;663 664    case LambdaIntroducerTentativeParse::Invalid:665      // No idea what this is; we couldn't parse it as a lambda-introducer.666      // Might still be an attribute-specifier or a message send.667      break;668    }669  }670 671  ConsumeBracket();672 673  // If we don't have a lambda-introducer, then we have an attribute or a674  // message-send.675  bool IsAttribute = true;676  while (Tok.isNot(tok::r_square)) {677    if (Tok.is(tok::comma)) {678      // Case 1: Stray commas can only occur in attributes.679      return CXX11AttributeKind::AttributeSpecifier;680    }681 682    // Parse the attribute-token, if present.683    // C++11 [dcl.attr.grammar]:684    //   If a keyword or an alternative token that satisfies the syntactic685    //   requirements of an identifier is contained in an attribute-token,686    //   it is considered an identifier.687    SourceLocation Loc;688    if (!TryParseCXX11AttributeIdentifier(Loc)) {689      IsAttribute = false;690      break;691    }692    if (Tok.is(tok::coloncolon)) {693      ConsumeToken();694      if (!TryParseCXX11AttributeIdentifier(Loc)) {695        IsAttribute = false;696        break;697      }698    }699 700    // Parse the attribute-argument-clause, if present.701    if (Tok.is(tok::l_paren)) {702      ConsumeParen();703      if (!SkipUntil(tok::r_paren)) {704        IsAttribute = false;705        break;706      }707    }708 709    TryConsumeToken(tok::ellipsis);710 711    if (!TryConsumeToken(tok::comma))712      break;713  }714 715  // An attribute must end ']]'.716  if (IsAttribute) {717    if (Tok.is(tok::r_square)) {718      ConsumeBracket();719      IsAttribute = Tok.is(tok::r_square);720    } else {721      IsAttribute = false;722    }723  }724 725  if (IsAttribute)726    // Case 1: C++11 statement attribute.727    return CXX11AttributeKind::AttributeSpecifier;728 729  // Case 3: Message send.730  return CXX11AttributeKind::NotAttributeSpecifier;731}732 733bool Parser::TrySkipAttributes() {734  while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,735                     tok::kw_alignas) ||736         Tok.isRegularKeywordAttribute()) {737    if (Tok.is(tok::l_square)) {738      if (!NextToken().is(tok::l_square))739        return true;740 741      ConsumeBracket();742      ConsumeBracket();743 744      if (!SkipUntil(tok::r_square) || Tok.isNot(tok::r_square))745        return false;746      // Note that explicitly checking for `[[` and `]]` allows to fail as747      // expected in the case of the Objective-C message send syntax.748      ConsumeBracket();749    } else if (Tok.isRegularKeywordAttribute() &&750               !doesKeywordAttributeTakeArgs(Tok.getKind())) {751      ConsumeToken();752    } else {753      ConsumeToken();754      if (Tok.isNot(tok::l_paren))755        return false;756      ConsumeParen();757      if (!SkipUntil(tok::r_paren))758        return false;759    }760  }761 762  return true;763}764 765Parser::TPResult Parser::TryParsePtrOperatorSeq() {766  while (true) {767    if (TryAnnotateOptionalCXXScopeToken(true))768      return TPResult::Error;769 770    if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||771        (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {772      // ptr-operator773      ConsumeAnyToken();774 775      // Skip attributes.776      if (!TrySkipAttributes())777        return TPResult::Error;778 779      while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,780                         tok::kw__Nonnull, tok::kw__Nullable,781                         tok::kw__Nullable_result, tok::kw__Null_unspecified,782                         tok::kw__Atomic))783        ConsumeToken();784    } else {785      return TPResult::True;786    }787  }788}789 790Parser::TPResult Parser::TryParseOperatorId() {791  assert(Tok.is(tok::kw_operator));792  ConsumeToken();793 794  // Maybe this is an operator-function-id.795  switch (Tok.getKind()) {796  case tok::kw_new: case tok::kw_delete:797    ConsumeToken();798    if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) {799      ConsumeBracket();800      ConsumeBracket();801    }802    return TPResult::True;803 804#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \805  case tok::Token:806#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)807#include "clang/Basic/OperatorKinds.def"808    ConsumeToken();809    return TPResult::True;810 811  case tok::l_square:812    if (NextToken().is(tok::r_square)) {813      ConsumeBracket();814      ConsumeBracket();815      return TPResult::True;816    }817    break;818 819  case tok::l_paren:820    if (NextToken().is(tok::r_paren)) {821      ConsumeParen();822      ConsumeParen();823      return TPResult::True;824    }825    break;826 827  default:828    break;829  }830 831  // Maybe this is a literal-operator-id.832  if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) {833    bool FoundUDSuffix = false;834    do {835      FoundUDSuffix |= Tok.hasUDSuffix();836      ConsumeStringToken();837    } while (isTokenStringLiteral());838 839    if (!FoundUDSuffix) {840      if (Tok.is(tok::identifier))841        ConsumeToken();842      else843        return TPResult::Error;844    }845    return TPResult::True;846  }847 848  // Maybe this is a conversion-function-id.849  bool AnyDeclSpecifiers = false;850  while (true) {851    TPResult TPR = isCXXDeclarationSpecifier(ImplicitTypenameContext::No);852    if (TPR == TPResult::Error)853      return TPR;854    if (TPR == TPResult::False) {855      if (!AnyDeclSpecifiers)856        return TPResult::Error;857      break;858    }859    if (TryConsumeDeclarationSpecifier() == TPResult::Error)860      return TPResult::Error;861    AnyDeclSpecifiers = true;862  }863  return TryParsePtrOperatorSeq();864}865 866Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,867                                            bool mayHaveIdentifier,868                                            bool mayHaveDirectInit,869                                            bool mayHaveTrailingReturnType) {870  // declarator:871  //   direct-declarator872  //   ptr-operator declarator873  if (TryParsePtrOperatorSeq() == TPResult::Error)874    return TPResult::Error;875 876  // direct-declarator:877  // direct-abstract-declarator:878  if (Tok.is(tok::ellipsis))879    ConsumeToken();880 881  if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||882       (Tok.is(tok::annot_cxxscope) && (NextToken().is(tok::identifier) ||883                                        NextToken().is(tok::kw_operator)))) &&884      mayHaveIdentifier) {885    // declarator-id886    if (Tok.is(tok::annot_cxxscope)) {887      CXXScopeSpec SS;888      Actions.RestoreNestedNameSpecifierAnnotation(889          Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);890      if (SS.isInvalid())891        return TPResult::Error;892      ConsumeAnnotationToken();893    } else if (Tok.is(tok::identifier)) {894      TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());895    }896    if (Tok.is(tok::kw_operator)) {897      if (TryParseOperatorId() == TPResult::Error)898        return TPResult::Error;899    } else900      ConsumeToken();901  } else if (Tok.is(tok::l_paren)) {902    ConsumeParen();903    if (mayBeAbstract &&904        (Tok.is(tok::r_paren) || // 'int()' is a function.905                                 // 'int(...)' is a function.906         (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) ||907         isDeclarationSpecifier(908             ImplicitTypenameContext::No))) { // 'int(int)' is a function.909      // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]910      //        exception-specification[opt]911      TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);912      if (TPR != TPResult::Ambiguous)913        return TPR;914    } else {915      // '(' declarator ')'916      // '(' attributes declarator ')'917      // '(' abstract-declarator ')'918      if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,919                      tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,920                      tok::kw___regcall, tok::kw___vectorcall))921        return TPResult::True; // attributes indicate declaration922      TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);923      if (TPR != TPResult::Ambiguous)924        return TPR;925      if (Tok.isNot(tok::r_paren))926        return TPResult::False;927      ConsumeParen();928    }929  } else if (!mayBeAbstract) {930    return TPResult::False;931  }932 933  if (mayHaveDirectInit)934    return TPResult::Ambiguous;935 936  while (true) {937    TPResult TPR(TPResult::Ambiguous);938 939    if (Tok.is(tok::l_paren)) {940      // Check whether we have a function declarator or a possible ctor-style941      // initializer that follows the declarator. Note that ctor-style942      // initializers are not possible in contexts where abstract declarators943      // are allowed.944      if (!mayBeAbstract && !isCXXFunctionDeclarator())945        break;946 947      // direct-declarator '(' parameter-declaration-clause ')'948      //        cv-qualifier-seq[opt] exception-specification[opt]949      ConsumeParen();950      TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);951    } else if (Tok.is(tok::l_square)) {952      // direct-declarator '[' constant-expression[opt] ']'953      // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'954      TPR = TryParseBracketDeclarator();955    } else if (Tok.is(tok::kw_requires)) {956      // declarator requires-clause957      // A requires clause indicates a function declaration.958      TPR = TPResult::True;959    } else {960      break;961    }962 963    if (TPR != TPResult::Ambiguous)964      return TPR;965  }966 967  return TPResult::Ambiguous;968}969 970bool Parser::isTentativelyDeclared(IdentifierInfo *II) {971  return llvm::is_contained(TentativelyDeclaredIdentifiers, II);972}973 974namespace {975class TentativeParseCCC final : public CorrectionCandidateCallback {976public:977  TentativeParseCCC(const Token &Next) {978    WantRemainingKeywords = false;979    WantTypeSpecifiers =980        Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,981                     tok::identifier, tok::comma);982  }983 984  bool ValidateCandidate(const TypoCorrection &Candidate) override {985    // Reject any candidate that only resolves to instance members since they986    // aren't viable as standalone identifiers instead of member references.987    if (Candidate.isResolved() && !Candidate.isKeyword() &&988        llvm::all_of(Candidate,989                     [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))990      return false;991 992    return CorrectionCandidateCallback::ValidateCandidate(Candidate);993  }994 995  std::unique_ptr<CorrectionCandidateCallback> clone() override {996    return std::make_unique<TentativeParseCCC>(*this);997  }998};999}1000 1001Parser::TPResult1002Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,1003                                  Parser::TPResult BracedCastResult,1004                                  bool *InvalidAsDeclSpec) {1005  auto IsPlaceholderSpecifier = [&](TemplateIdAnnotation *TemplateId,1006                                    int Lookahead) {1007    // We have a placeholder-constraint (we check for 'auto' or 'decltype' to1008    // distinguish 'C<int>;' from 'C<int> auto c = 1;')1009    return TemplateId->Kind == TNK_Concept_template &&1010           (GetLookAheadToken(Lookahead + 1)1011                .isOneOf(tok::kw_auto, tok::kw_decltype,1012                         // If we have an identifier here, the user probably1013                         // forgot the 'auto' in the placeholder constraint,1014                         // e.g. 'C<int> x = 2;' This will be diagnosed nicely1015                         // later, so disambiguate as a declaration.1016                         tok::identifier,1017                         // CVR qualifierslikely the same situation for the1018                         // user, so let this be diagnosed nicely later. We1019                         // cannot handle references here, as `C<int> & Other`1020                         // and `C<int> && Other` are both legal.1021                         tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||1022            // While `C<int> && Other` is legal, doing so while not specifying a1023            // template argument is NOT, so see if we can fix up in that case at1024            // minimum. Concepts require at least 1 template parameter, so we1025            // can count on the argument count.1026            // FIXME: In the future, we migth be able to have SEMA look up the1027            // declaration for this concept, and see how many template1028            // parameters it has.  If the concept isn't fully specified, it is1029            // possibly a situation where we want deduction, such as:1030            // `BinaryConcept<int> auto f = bar();`1031            (TemplateId->NumArgs == 0 &&1032             GetLookAheadToken(Lookahead + 1).isOneOf(tok::amp, tok::ampamp)));1033  };1034  switch (Tok.getKind()) {1035  case tok::identifier: {1036    if (GetLookAheadToken(1).is(tok::ellipsis) &&1037        GetLookAheadToken(2).is(tok::l_square)) {1038 1039      if (TryAnnotateTypeOrScopeToken())1040        return TPResult::Error;1041      if (Tok.is(tok::identifier))1042        return TPResult::False;1043      return isCXXDeclarationSpecifier(ImplicitTypenameContext::No,1044                                       BracedCastResult, InvalidAsDeclSpec);1045    }1046 1047    // Check for need to substitute AltiVec __vector keyword1048    // for "vector" identifier.1049    if (TryAltiVecVectorToken())1050      return TPResult::True;1051 1052    const Token &Next = NextToken();1053    // In 'foo bar', 'foo' is always a type name outside of Objective-C.1054    if (!getLangOpts().ObjC && Next.is(tok::identifier))1055      return TPResult::True;1056 1057    // If this identifier was reverted from a token ID, and the next token1058    // is a '(', we assume it to be a use of a type trait, so this1059    // can never be a type name.1060    if (Next.is(tok::l_paren) &&1061        Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier() &&1062        isRevertibleTypeTrait(Tok.getIdentifierInfo())) {1063      return TPResult::False;1064    }1065 1066    if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {1067      // Determine whether this is a valid expression. If not, we will hit1068      // a parse error one way or another. In that case, tell the caller that1069      // this is ambiguous. Typo-correct to type and expression keywords and1070      // to types and identifiers, in order to try to recover from errors.1071      TentativeParseCCC CCC(Next);1072      switch (TryAnnotateName(&CCC)) {1073      case AnnotatedNameKind::Error:1074        return TPResult::Error;1075      case AnnotatedNameKind::TentativeDecl:1076        return TPResult::False;1077      case AnnotatedNameKind::TemplateName:1078        // In C++17, this could be a type template for class template argument1079        // deduction. Try to form a type annotation for it. If we're in a1080        // template template argument, we'll undo this when checking the1081        // validity of the argument.1082        if (getLangOpts().CPlusPlus17) {1083          if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))1084            return TPResult::Error;1085          if (Tok.isNot(tok::identifier))1086            break;1087        }1088 1089        // A bare type template-name which can't be a template template1090        // argument is an error, and was probably intended to be a type.1091        return GreaterThanIsOperator ? TPResult::True : TPResult::False;1092      case AnnotatedNameKind::Unresolved:1093        return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;1094      case AnnotatedNameKind::Success:1095        break;1096      }1097      assert(Tok.isNot(tok::identifier) &&1098             "TryAnnotateName succeeded without producing an annotation");1099    } else {1100      // This might possibly be a type with a dependent scope specifier and1101      // a missing 'typename' keyword. Don't use TryAnnotateName in this case,1102      // since it will annotate as a primary expression, and we want to use the1103      // "missing 'typename'" logic.1104      if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))1105        return TPResult::Error;1106      // If annotation failed, assume it's a non-type.1107      // FIXME: If this happens due to an undeclared identifier, treat it as1108      // ambiguous.1109      if (Tok.is(tok::identifier))1110        return TPResult::False;1111    }1112 1113    // We annotated this token as something. Recurse to handle whatever we got.1114    return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,1115                                     InvalidAsDeclSpec);1116  }1117 1118  case tok::kw_typename:  // typename T::type1119    // Annotate typenames and C++ scope specifiers.  If we get one, just1120    // recurse to handle whatever we get.1121    if (TryAnnotateTypeOrScopeToken(ImplicitTypenameContext::Yes))1122      return TPResult::Error;1123    return isCXXDeclarationSpecifier(ImplicitTypenameContext::Yes,1124                                     BracedCastResult, InvalidAsDeclSpec);1125 1126  case tok::kw_auto: {1127    if (!getLangOpts().CPlusPlus23)1128      return TPResult::True;1129    if (NextToken().is(tok::l_brace))1130      return TPResult::False;1131    if (NextToken().is(tok::l_paren))1132      return TPResult::Ambiguous;1133    return TPResult::True;1134  }1135 1136  case tok::coloncolon: {    // ::foo::bar1137    const Token &Next = NextToken();1138    if (Next.isOneOf(tok::kw_new,       // ::new1139                     tok::kw_delete))   // ::delete1140      return TPResult::False;1141    [[fallthrough]];1142  }1143  case tok::kw___super:1144  case tok::kw_decltype:1145    // Annotate typenames and C++ scope specifiers.  If we get one, just1146    // recurse to handle whatever we get.1147    if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))1148      return TPResult::Error;1149    return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,1150                                     InvalidAsDeclSpec);1151 1152    // decl-specifier:1153    //   storage-class-specifier1154    //   type-specifier1155    //   function-specifier1156    //   'friend'1157    //   'typedef'1158    //   'constexpr'1159  case tok::kw_friend:1160  case tok::kw_typedef:1161  case tok::kw_constexpr:1162  case tok::kw_consteval:1163  case tok::kw_constinit:1164    // storage-class-specifier1165  case tok::kw_register:1166  case tok::kw_static:1167  case tok::kw_extern:1168  case tok::kw_mutable:1169  case tok::kw___thread:1170  case tok::kw_thread_local:1171  case tok::kw__Thread_local:1172    // function-specifier1173  case tok::kw_inline:1174  case tok::kw_virtual:1175  case tok::kw_explicit:1176 1177    // Modules1178  case tok::kw___module_private__:1179 1180    // Debugger support1181  case tok::kw___unknown_anytype:1182 1183    // type-specifier:1184    //   simple-type-specifier1185    //   class-specifier1186    //   enum-specifier1187    //   elaborated-type-specifier1188    //   typename-specifier1189    //   cv-qualifier1190 1191    // class-specifier1192    // elaborated-type-specifier1193  case tok::kw_class:1194  case tok::kw_struct:1195  case tok::kw_union:1196  case tok::kw___interface:1197    // enum-specifier1198  case tok::kw_enum:1199    // cv-qualifier1200  case tok::kw_const:1201  case tok::kw_volatile:1202    return TPResult::True;1203 1204    // OpenCL address space qualifiers1205  case tok::kw_private:1206    if (!getLangOpts().OpenCL)1207      return TPResult::False;1208    [[fallthrough]];1209  case tok::kw___private:1210  case tok::kw___local:1211  case tok::kw___global:1212  case tok::kw___constant:1213  case tok::kw___generic:1214    // OpenCL access qualifiers1215  case tok::kw___read_only:1216  case tok::kw___write_only:1217  case tok::kw___read_write:1218    // OpenCL pipe1219  case tok::kw_pipe:1220 1221    // HLSL address space qualifiers1222  case tok::kw_groupshared:1223  case tok::kw_in:1224  case tok::kw_inout:1225  case tok::kw_out:1226 1227    // GNU1228  case tok::kw_restrict:1229  case tok::kw__Complex:1230  case tok::kw___attribute:1231  case tok::kw___auto_type:1232    return TPResult::True;1233 1234    // Microsoft1235  case tok::kw___declspec:1236  case tok::kw___cdecl:1237  case tok::kw___stdcall:1238  case tok::kw___fastcall:1239  case tok::kw___thiscall:1240  case tok::kw___regcall:1241  case tok::kw___vectorcall:1242  case tok::kw___w64:1243  case tok::kw___sptr:1244  case tok::kw___uptr:1245  case tok::kw___ptr64:1246  case tok::kw___ptr32:1247  case tok::kw___forceinline:1248  case tok::kw___unaligned:1249  case tok::kw__Nonnull:1250  case tok::kw__Nullable:1251  case tok::kw__Nullable_result:1252  case tok::kw__Null_unspecified:1253  case tok::kw___kindof:1254    return TPResult::True;1255 1256    // WebAssemblyFuncref1257  case tok::kw___funcref:1258    return TPResult::True;1259 1260    // Borland1261  case tok::kw___pascal:1262    return TPResult::True;1263 1264    // AltiVec1265  case tok::kw___vector:1266    return TPResult::True;1267 1268  case tok::kw_this: {1269    // Try to parse a C++23 Explicit Object Parameter1270    // We do that in all language modes to produce a better diagnostic.1271    if (getLangOpts().CPlusPlus) {1272      RevertingTentativeParsingAction PA(*this);1273      ConsumeToken();1274      return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,1275                                       InvalidAsDeclSpec);1276    }1277    return TPResult::False;1278  }1279  case tok::annot_template_id: {1280    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);1281    // If lookup for the template-name found nothing, don't assume we have a1282    // definitive disambiguation result yet.1283    if ((TemplateId->hasInvalidName() ||1284         TemplateId->Kind == TNK_Undeclared_template) &&1285        InvalidAsDeclSpec) {1286      // 'template-id(' can be a valid expression but not a valid decl spec if1287      // the template-name is not declared, but we don't consider this to be a1288      // definitive disambiguation. In any other context, it's an error either1289      // way.1290      *InvalidAsDeclSpec = NextToken().is(tok::l_paren);1291      return TPResult::Ambiguous;1292    }1293    if (TemplateId->hasInvalidName())1294      return TPResult::Error;1295    if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/0))1296      return TPResult::True;1297    if (TemplateId->Kind != TNK_Type_template)1298      return TPResult::False;1299    CXXScopeSpec SS;1300    AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);1301    assert(Tok.is(tok::annot_typename));1302    goto case_typename;1303  }1304 1305  case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed1306    // We've already annotated a scope; try to annotate a type.1307    if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))1308      return TPResult::Error;1309    if (!Tok.is(tok::annot_typename)) {1310      if (Tok.is(tok::annot_cxxscope) &&1311          NextToken().is(tok::annot_template_id)) {1312        TemplateIdAnnotation *TemplateId =1313            takeTemplateIdAnnotation(NextToken());1314        if (TemplateId->hasInvalidName()) {1315          if (InvalidAsDeclSpec) {1316            *InvalidAsDeclSpec = NextToken().is(tok::l_paren);1317            return TPResult::Ambiguous;1318          }1319          return TPResult::Error;1320        }1321        if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/1))1322          return TPResult::True;1323      }1324      // If the next token is an identifier or a type qualifier, then this1325      // can't possibly be a valid expression either.1326      if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) {1327        CXXScopeSpec SS;1328        Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),1329                                                     Tok.getAnnotationRange(),1330                                                     SS);1331        if (SS.getScopeRep().isDependent()) {1332          RevertingTentativeParsingAction PA(*this);1333          ConsumeAnnotationToken();1334          ConsumeToken();1335          bool isIdentifier = Tok.is(tok::identifier);1336          TPResult TPR = TPResult::False;1337          if (!isIdentifier)1338            TPR = isCXXDeclarationSpecifier(1339                AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);1340 1341          if (isIdentifier ||1342              TPR == TPResult::True || TPR == TPResult::Error)1343            return TPResult::Error;1344 1345          if (InvalidAsDeclSpec) {1346            // We can't tell whether this is a missing 'typename' or a valid1347            // expression.1348            *InvalidAsDeclSpec = true;1349            return TPResult::Ambiguous;1350          } else {1351            // In MS mode, if InvalidAsDeclSpec is not provided, and the tokens1352            // are or the form *) or &) *> or &> &&>, this can't be an expression.1353            // The typename must be missing.1354            if (getLangOpts().MSVCCompat) {1355              if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&1356                   (NextToken().is(tok::r_paren) ||1357                    NextToken().is(tok::greater))) ||1358                  (Tok.is(tok::ampamp) && NextToken().is(tok::greater)))1359                return TPResult::True;1360            }1361          }1362        } else {1363          // Try to resolve the name. If it doesn't exist, assume it was1364          // intended to name a type and keep disambiguating.1365          switch (TryAnnotateName(/*CCC=*/nullptr, AllowImplicitTypename)) {1366          case AnnotatedNameKind::Error:1367            return TPResult::Error;1368          case AnnotatedNameKind::TentativeDecl:1369            return TPResult::False;1370          case AnnotatedNameKind::TemplateName:1371            // In C++17, this could be a type template for class template1372            // argument deduction.1373            if (getLangOpts().CPlusPlus17) {1374              if (TryAnnotateTypeOrScopeToken())1375                return TPResult::Error;1376              // If we annotated then the current token should not still be ::1377              // FIXME we may want to also check for tok::annot_typename but1378              // currently don't have a test case.1379              if (Tok.isNot(tok::annot_cxxscope) && Tok.isNot(tok::identifier))1380                break;1381            }1382 1383            // A bare type template-name which can't be a template template1384            // argument is an error, and was probably intended to be a type.1385            // In C++17, this could be class template argument deduction.1386            return (getLangOpts().CPlusPlus17 || GreaterThanIsOperator)1387                       ? TPResult::True1388                       : TPResult::False;1389          case AnnotatedNameKind::Unresolved:1390            return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;1391          case AnnotatedNameKind::Success:1392            break;1393          }1394 1395          // Annotated it, check again.1396          assert(Tok.isNot(tok::annot_cxxscope) ||1397                 NextToken().isNot(tok::identifier));1398          return isCXXDeclarationSpecifier(AllowImplicitTypename,1399                                           BracedCastResult, InvalidAsDeclSpec);1400        }1401      }1402      return TPResult::False;1403    }1404    // If that succeeded, fallthrough into the generic simple-type-id case.1405    [[fallthrough]];1406 1407    // The ambiguity resides in a simple-type-specifier/typename-specifier1408    // followed by a '('. The '(' could either be the start of:1409    //1410    //   direct-declarator:1411    //     '(' declarator ')'1412    //1413    //   direct-abstract-declarator:1414    //     '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]1415    //              exception-specification[opt]1416    //     '(' abstract-declarator ')'1417    //1418    // or part of a function-style cast expression:1419    //1420    //     simple-type-specifier '(' expression-list[opt] ')'1421    //1422 1423    // simple-type-specifier:1424 1425  case tok::annot_typename:1426  case_typename:1427    // In Objective-C, we might have a protocol-qualified type.1428    if (getLangOpts().ObjC && NextToken().is(tok::less)) {1429      // Tentatively parse the protocol qualifiers.1430      RevertingTentativeParsingAction PA(*this);1431      ConsumeAnyToken(); // The type token1432 1433      TPResult TPR = TryParseProtocolQualifiers();1434      bool isFollowedByParen = Tok.is(tok::l_paren);1435      bool isFollowedByBrace = Tok.is(tok::l_brace);1436 1437      if (TPR == TPResult::Error)1438        return TPResult::Error;1439 1440      if (isFollowedByParen)1441        return TPResult::Ambiguous;1442 1443      if (getLangOpts().CPlusPlus11 && isFollowedByBrace)1444        return BracedCastResult;1445 1446      return TPResult::True;1447    }1448 1449    [[fallthrough]];1450 1451  case tok::kw_char:1452  case tok::kw_wchar_t:1453  case tok::kw_char8_t:1454  case tok::kw_char16_t:1455  case tok::kw_char32_t:1456  case tok::kw_bool:1457  case tok::kw_short:1458  case tok::kw_int:1459  case tok::kw_long:1460  case tok::kw___int64:1461  case tok::kw___int128:1462  case tok::kw_signed:1463  case tok::kw_unsigned:1464  case tok::kw_half:1465  case tok::kw_float:1466  case tok::kw_double:1467  case tok::kw___bf16:1468  case tok::kw__Float16:1469  case tok::kw___float128:1470  case tok::kw___ibm128:1471  case tok::kw_void:1472  case tok::annot_decltype:1473  case tok::kw__Accum:1474  case tok::kw__Fract:1475  case tok::kw__Sat:1476  case tok::annot_pack_indexing_type:1477#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:1478#include "clang/Basic/OpenCLImageTypes.def"1479#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:1480#include "clang/Basic/HLSLIntangibleTypes.def"1481    if (NextToken().is(tok::l_paren))1482      return TPResult::Ambiguous;1483 1484    // This is a function-style cast in all cases we disambiguate other than1485    // one:1486    //   struct S {1487    //     enum E : int { a = 4 }; // enum1488    //     enum E : int { 4 };     // bit-field1489    //   };1490    if (getLangOpts().CPlusPlus11 && NextToken().is(tok::l_brace))1491      return BracedCastResult;1492 1493    if (isStartOfObjCClassMessageMissingOpenBracket())1494      return TPResult::False;1495 1496    return TPResult::True;1497 1498  // GNU typeof support.1499  case tok::kw_typeof: {1500    if (NextToken().isNot(tok::l_paren))1501      return TPResult::True;1502 1503    RevertingTentativeParsingAction PA(*this);1504 1505    TPResult TPR = TryParseTypeofSpecifier();1506    bool isFollowedByParen = Tok.is(tok::l_paren);1507    bool isFollowedByBrace = Tok.is(tok::l_brace);1508 1509    if (TPR == TPResult::Error)1510      return TPResult::Error;1511 1512    if (isFollowedByParen)1513      return TPResult::Ambiguous;1514 1515    if (getLangOpts().CPlusPlus11 && isFollowedByBrace)1516      return BracedCastResult;1517 1518    return TPResult::True;1519  }1520 1521#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:1522#include "clang/Basic/TransformTypeTraits.def"1523    return TPResult::True;1524 1525  // C11 _Alignas1526  case tok::kw__Alignas:1527    return TPResult::True;1528  // C11 _Atomic1529  case tok::kw__Atomic:1530    return TPResult::True;1531 1532  case tok::kw__BitInt:1533  case tok::kw__ExtInt: {1534    if (NextToken().isNot(tok::l_paren))1535      return TPResult::Error;1536    RevertingTentativeParsingAction PA(*this);1537    ConsumeToken();1538    ConsumeParen();1539 1540    if (!SkipUntil(tok::r_paren, StopAtSemi))1541      return TPResult::Error;1542 1543    if (Tok.is(tok::l_paren))1544      return TPResult::Ambiguous;1545 1546    if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))1547      return BracedCastResult;1548 1549    return TPResult::True;1550  }1551  default:1552    return TPResult::False;1553  }1554}1555 1556bool Parser::isCXXDeclarationSpecifierAType() {1557  switch (Tok.getKind()) {1558    // typename-specifier1559  case tok::annot_decltype:1560  case tok::annot_pack_indexing_type:1561  case tok::annot_template_id:1562  case tok::annot_typename:1563  case tok::kw_typeof:1564#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:1565#include "clang/Basic/TransformTypeTraits.def"1566    return true;1567 1568    // elaborated-type-specifier1569  case tok::kw_class:1570  case tok::kw_struct:1571  case tok::kw_union:1572  case tok::kw___interface:1573  case tok::kw_enum:1574    return true;1575 1576    // simple-type-specifier1577  case tok::kw_char:1578  case tok::kw_wchar_t:1579  case tok::kw_char8_t:1580  case tok::kw_char16_t:1581  case tok::kw_char32_t:1582  case tok::kw_bool:1583  case tok::kw_short:1584  case tok::kw_int:1585  case tok::kw__ExtInt:1586  case tok::kw__BitInt:1587  case tok::kw_long:1588  case tok::kw___int64:1589  case tok::kw___int128:1590  case tok::kw_signed:1591  case tok::kw_unsigned:1592  case tok::kw_half:1593  case tok::kw_float:1594  case tok::kw_double:1595  case tok::kw___bf16:1596  case tok::kw__Float16:1597  case tok::kw___float128:1598  case tok::kw___ibm128:1599  case tok::kw_void:1600  case tok::kw___unknown_anytype:1601  case tok::kw___auto_type:1602  case tok::kw__Accum:1603  case tok::kw__Fract:1604  case tok::kw__Sat:1605#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:1606#include "clang/Basic/OpenCLImageTypes.def"1607#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:1608#include "clang/Basic/HLSLIntangibleTypes.def"1609    return true;1610 1611  case tok::kw_auto:1612    return getLangOpts().CPlusPlus11;1613 1614  case tok::kw__Atomic:1615    // "_Atomic foo"1616    return NextToken().is(tok::l_paren);1617 1618  default:1619    return false;1620  }1621}1622 1623Parser::TPResult Parser::TryParseTypeofSpecifier() {1624  assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");1625  ConsumeToken();1626 1627  assert(Tok.is(tok::l_paren) && "Expected '('");1628  // Parse through the parens after 'typeof'.1629  ConsumeParen();1630  if (!SkipUntil(tok::r_paren, StopAtSemi))1631    return TPResult::Error;1632 1633  return TPResult::Ambiguous;1634}1635 1636Parser::TPResult Parser::TryParseProtocolQualifiers() {1637  assert(Tok.is(tok::less) && "Expected '<' for qualifier list");1638  ConsumeToken();1639  do {1640    if (Tok.isNot(tok::identifier))1641      return TPResult::Error;1642    ConsumeToken();1643 1644    if (Tok.is(tok::comma)) {1645      ConsumeToken();1646      continue;1647    }1648 1649    if (Tok.is(tok::greater)) {1650      ConsumeToken();1651      return TPResult::Ambiguous;1652    }1653  } while (false);1654 1655  return TPResult::Error;1656}1657 1658bool Parser::isCXXFunctionDeclarator(1659    bool *IsAmbiguous, ImplicitTypenameContext AllowImplicitTypename) {1660 1661  // C++ 8.2p1:1662  // The ambiguity arising from the similarity between a function-style cast and1663  // a declaration mentioned in 6.8 can also occur in the context of a1664  // declaration. In that context, the choice is between a function declaration1665  // with a redundant set of parentheses around a parameter name and an object1666  // declaration with a function-style cast as the initializer. Just as for the1667  // ambiguities mentioned in 6.8, the resolution is to consider any construct1668  // that could possibly be a declaration a declaration.1669 1670  RevertingTentativeParsingAction PA(*this);1671 1672  ConsumeParen();1673  bool InvalidAsDeclaration = false;1674  TPResult TPR = TryParseParameterDeclarationClause(1675      &InvalidAsDeclaration, /*VersusTemplateArgument=*/false,1676      AllowImplicitTypename);1677  if (TPR == TPResult::Ambiguous) {1678    if (Tok.isNot(tok::r_paren))1679      TPR = TPResult::False;1680    else {1681      const Token &Next = NextToken();1682      if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,1683                       tok::kw_throw, tok::kw_noexcept, tok::l_square,1684                       tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||1685          isCXX11VirtSpecifier(Next))1686        // The next token cannot appear after a constructor-style initializer,1687        // and can appear next in a function definition. This must be a function1688        // declarator.1689        TPR = TPResult::True;1690      else if (InvalidAsDeclaration)1691        // Use the absence of 'typename' as a tie-breaker.1692        TPR = TPResult::False;1693    }1694  }1695 1696  if (IsAmbiguous && TPR == TPResult::Ambiguous)1697    *IsAmbiguous = true;1698 1699  // In case of an error, let the declaration parsing code handle it.1700  return TPR != TPResult::False;1701}1702 1703Parser::TPResult Parser::TryParseParameterDeclarationClause(1704    bool *InvalidAsDeclaration, bool VersusTemplateArgument,1705    ImplicitTypenameContext AllowImplicitTypename) {1706 1707  if (Tok.is(tok::r_paren))1708    return TPResult::Ambiguous;1709 1710  //   parameter-declaration-list[opt] '...'[opt]1711  //   parameter-declaration-list ',' '...'1712  //1713  // parameter-declaration-list:1714  //   parameter-declaration1715  //   parameter-declaration-list ',' parameter-declaration1716  //1717  while (true) {1718    // '...'[opt]1719    if (Tok.is(tok::ellipsis)) {1720      ConsumeToken();1721      if (Tok.is(tok::r_paren))1722        return TPResult::True; // '...)' is a sign of a function declarator.1723      else1724        return TPResult::False;1725    }1726 1727    // An attribute-specifier-seq here is a sign of a function declarator.1728    if (isCXX11AttributeSpecifier(/*Disambiguate*/ false,1729                                  /*OuterMightBeMessageSend*/ true) !=1730        CXX11AttributeKind::NotAttributeSpecifier)1731      return TPResult::True;1732 1733    ParsedAttributes attrs(AttrFactory);1734    MaybeParseMicrosoftAttributes(attrs);1735 1736    // decl-specifier-seq1737    // A parameter-declaration's initializer must be preceded by an '=', so1738    // decl-specifier-seq '{' is not a parameter in C++11.1739    TPResult TPR = isCXXDeclarationSpecifier(1740        AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);1741    // A declaration-specifier (not followed by '(' or '{') means this can't be1742    // an expression, but it could still be a template argument.1743    if (TPR != TPResult::Ambiguous &&1744        !(VersusTemplateArgument && TPR == TPResult::True))1745      return TPR;1746 1747    bool SeenType = false;1748    bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);1749    do {1750      SeenType |= isCXXDeclarationSpecifierAType();1751      if (TryConsumeDeclarationSpecifier() == TPResult::Error)1752        return TPResult::Error;1753 1754      // If we see a parameter name, this can't be a template argument.1755      if (SeenType && Tok.is(tok::identifier))1756        return TPResult::True;1757 1758      TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,1759                                      InvalidAsDeclaration);1760      if (TPR == TPResult::Error)1761        return TPR;1762 1763      // Two declaration-specifiers means this can't be an expression.1764      if (TPR == TPResult::True && !VersusTemplateArgument)1765        return TPR;1766    } while (TPR != TPResult::False);1767 1768    // declarator1769    // abstract-declarator[opt]1770    TPR = TryParseDeclarator(1771        /*mayBeAbstract=*/true,1772        /*mayHaveIdentifier=*/true,1773        /*mayHaveDirectInit=*/false,1774        /*mayHaveTrailingReturnType=*/DeclarationSpecifierIsAuto);1775    if (TPR != TPResult::Ambiguous)1776      return TPR;1777 1778    // [GNU] attributes[opt]1779    if (Tok.is(tok::kw___attribute))1780      return TPResult::True;1781 1782    // If we're disambiguating a template argument in a default argument in1783    // a class definition versus a parameter declaration, an '=' here1784    // disambiguates the parse one way or the other.1785    // If this is a parameter, it must have a default argument because1786    //   (a) the previous parameter did, and1787    //   (b) this must be the first declaration of the function, so we can't1788    //       inherit any default arguments from elsewhere.1789    // FIXME: If we reach a ')' without consuming any '>'s, then this must1790    // also be a function parameter (that's missing its default argument).1791    if (VersusTemplateArgument)1792      return Tok.is(tok::equal) ? TPResult::True : TPResult::False;1793 1794    if (Tok.is(tok::equal)) {1795      // '=' assignment-expression1796      // Parse through assignment-expression.1797      if (!SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch))1798        return TPResult::Error;1799    }1800 1801    if (Tok.is(tok::ellipsis)) {1802      ConsumeToken();1803      if (Tok.is(tok::r_paren))1804        return TPResult::True; // '...)' is a sign of a function declarator.1805      else1806        return TPResult::False;1807    }1808 1809    if (!TryConsumeToken(tok::comma))1810      break;1811  }1812 1813  return TPResult::Ambiguous;1814}1815 1816Parser::TPResult1817Parser::TryParseFunctionDeclarator(bool MayHaveTrailingReturnType) {1818  // The '(' is already parsed.1819 1820  TPResult TPR = TryParseParameterDeclarationClause();1821  if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))1822    TPR = TPResult::False;1823 1824  if (TPR == TPResult::False || TPR == TPResult::Error)1825    return TPR;1826 1827  // Parse through the parens.1828  if (!SkipUntil(tok::r_paren, StopAtSemi))1829    return TPResult::Error;1830 1831  // cv-qualifier-seq1832  while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,1833                     tok::kw_restrict))1834    ConsumeToken();1835 1836  // ref-qualifier[opt]1837  if (Tok.isOneOf(tok::amp, tok::ampamp))1838    ConsumeToken();1839 1840  // exception-specification1841  if (Tok.is(tok::kw_throw)) {1842    ConsumeToken();1843    if (Tok.isNot(tok::l_paren))1844      return TPResult::Error;1845 1846    // Parse through the parens after 'throw'.1847    ConsumeParen();1848    if (!SkipUntil(tok::r_paren, StopAtSemi))1849      return TPResult::Error;1850  }1851  if (Tok.is(tok::kw_noexcept)) {1852    ConsumeToken();1853    // Possibly an expression as well.1854    if (Tok.is(tok::l_paren)) {1855      // Find the matching rparen.1856      ConsumeParen();1857      if (!SkipUntil(tok::r_paren, StopAtSemi))1858        return TPResult::Error;1859    }1860  }1861 1862  // attribute-specifier-seq1863  if (!TrySkipAttributes())1864    return TPResult::Ambiguous;1865 1866  // trailing-return-type1867  if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {1868    if (TPR == TPResult::True)1869      return TPR;1870    ConsumeToken();1871    if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {1872      return TPResult::False;1873    }1874    if (isCXXTypeId(TentativeCXXTypeIdContext::InTrailingReturnType))1875      return TPResult::True;1876  }1877 1878  return TPResult::Ambiguous;1879}1880 1881bool Parser::NameAfterArrowIsNonType() {1882  assert(Tok.is(tok::identifier));1883  Token Next = NextToken();1884  if (Next.is(tok::coloncolon))1885    return false;1886  IdentifierInfo *Name = Tok.getIdentifierInfo();1887  SourceLocation NameLoc = Tok.getLocation();1888  CXXScopeSpec SS;1889  TentativeParseCCC CCC(Next);1890  Sema::NameClassification Classification =1891      Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next, &CCC);1892  switch (Classification.getKind()) {1893  case NameClassificationKind::OverloadSet:1894  case NameClassificationKind::NonType:1895  case NameClassificationKind::VarTemplate:1896  case NameClassificationKind::FunctionTemplate:1897    return true;1898  default:1899    break;1900  }1901  return false;1902}1903 1904Parser::TPResult Parser::TryParseBracketDeclarator() {1905  ConsumeBracket();1906 1907  // A constant-expression cannot begin with a '{', but the1908  // expr-or-braced-init-list of a postfix-expression can.1909  if (Tok.is(tok::l_brace))1910    return TPResult::False;1911 1912  if (!SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch))1913    return TPResult::Error;1914 1915  // If we hit a comma before the ']', this is not a constant-expression,1916  // but might still be the expr-or-braced-init-list of a postfix-expression.1917  if (Tok.isNot(tok::r_square))1918    return TPResult::False;1919 1920  ConsumeBracket();1921  return TPResult::Ambiguous;1922}1923 1924Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip) {1925  if (!TokensToSkip) {1926    if (Tok.isNot(tok::less))1927      return TPResult::False;1928    if (NextToken().is(tok::greater))1929      return TPResult::True;1930  }1931 1932  RevertingTentativeParsingAction PA(*this);1933 1934  while (TokensToSkip) {1935    ConsumeAnyToken();1936    --TokensToSkip;1937  }1938 1939  if (!TryConsumeToken(tok::less))1940    return TPResult::False;1941 1942  // We can't do much to tell an expression apart from a template-argument,1943  // but one good distinguishing factor is that a "decl-specifier" not1944  // followed by '(' or '{' can't appear in an expression.1945  bool InvalidAsTemplateArgumentList = false;1946  if (isCXXDeclarationSpecifier(ImplicitTypenameContext::No, TPResult::False,1947                                &InvalidAsTemplateArgumentList) ==1948      TPResult::True)1949    return TPResult::True;1950  if (InvalidAsTemplateArgumentList)1951    return TPResult::False;1952 1953  // FIXME: In many contexts, X<thing1, Type> can only be a1954  // template-argument-list. But that's not true in general:1955  //1956  // using b = int;1957  // void f() {1958  //   int a = A<B, b, c = C>D; // OK, declares b, not a template-id.1959  //1960  // X<Y<0, int> // ', int>' might be end of X's template argument list1961  //1962  // We might be able to disambiguate a few more cases if we're careful.1963 1964  // A template-argument-list must be terminated by a '>'.1965  if (SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},1966                StopAtSemi | StopBeforeMatch))1967    return TPResult::Ambiguous;1968  return TPResult::False;1969}1970 1971Parser::TPResult Parser::isExplicitBool() {1972  assert(Tok.is(tok::l_paren) && "expected to be looking at a '(' token");1973 1974  RevertingTentativeParsingAction PA(*this);1975  ConsumeParen();1976 1977  // We can only have 'explicit' on a constructor, conversion function, or1978  // deduction guide. The declarator of a deduction guide cannot be1979  // parenthesized, so we know this isn't a deduction guide. So the only1980  // thing we need to check for is some number of parens followed by either1981  // the current class name or 'operator'.1982  while (Tok.is(tok::l_paren))1983    ConsumeParen();1984 1985  if (TryAnnotateOptionalCXXScopeToken())1986    return TPResult::Error;1987 1988  // Class-scope constructor and conversion function names can't really be1989  // qualified, but we get better diagnostics if we assume they can be.1990  CXXScopeSpec SS;1991  if (Tok.is(tok::annot_cxxscope)) {1992    Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),1993                                                 Tok.getAnnotationRange(),1994                                                 SS);1995    ConsumeAnnotationToken();1996  }1997 1998  // 'explicit(operator' might be explicit(bool) or the declaration of a1999  // conversion function, but it's probably a conversion function.2000  if (Tok.is(tok::kw_operator))2001    return TPResult::Ambiguous;2002 2003  // If this can't be a constructor name, it can only be explicit(bool).2004  if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))2005    return TPResult::True;2006  if (!Actions.isCurrentClassName(Tok.is(tok::identifier)2007                                      ? *Tok.getIdentifierInfo()2008                                      : *takeTemplateIdAnnotation(Tok)->Name,2009                                  getCurScope(), &SS))2010    return TPResult::True;2011  // Formally, we must have a right-paren after the constructor name to match2012  // the grammar for a constructor. But clang permits a parenthesized2013  // constructor declarator, so also allow a constructor declarator to follow2014  // with no ')' token after the constructor name.2015  if (!NextToken().is(tok::r_paren) &&2016      !isConstructorDeclarator(/*Unqualified=*/SS.isEmpty(),2017                               /*DeductionGuide=*/false))2018    return TPResult::True;2019 2020  // Might be explicit(bool) or a parenthesized constructor name.2021  return TPResult::Ambiguous;2022}2023