//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file implements the tentative parsing portions of the Parser
//  interfaces, for ambiguity resolution.
//
//===----------------------------------------------------------------------===//

#include "clang/Parse/Parser.h"
#include "clang/Sema/ParsedTemplate.h"
using namespace clang;

bool Parser::isCXXDeclarationStatement(
    bool DisambiguatingWithExpression /*=false*/) {
  assert(getLangOpts().CPlusPlus && "Must be called for C++ only.");

  switch (Tok.getKind()) {
    // asm-definition
  case tok::kw_asm:
    // namespace-alias-definition
  case tok::kw_namespace:
    // using-declaration
    // using-directive
  case tok::kw_using:
    // static_assert-declaration
  case tok::kw_static_assert:
  case tok::kw__Static_assert:
    return true;
  case tok::coloncolon:
  case tok::identifier: {
    if (DisambiguatingWithExpression) {
      RevertingTentativeParsingAction TPA(*this);
      // Parse the C++ scope specifier.
      CXXScopeSpec SS;
      ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
                                     /*ObjectHasErrors=*/false,
                                     /*EnteringContext=*/true);

      switch (Tok.getKind()) {
      case tok::identifier: {
        IdentifierInfo *II = Tok.getIdentifierInfo();
        bool isDeductionGuide = Actions.isDeductionGuideName(
            getCurScope(), *II, Tok.getLocation(), SS, /*Template=*/nullptr);
        if (Actions.isCurrentClassName(*II, getCurScope(), &SS) ||
            isDeductionGuide) {
          if (isConstructorDeclarator(
                  /*Unqualified=*/SS.isEmpty(), isDeductionGuide,
                  /*IsFriend=*/DeclSpec::FriendSpecified::No))
            return true;
        } else if (SS.isNotEmpty()) {
          // If the scope is not empty, it could alternatively be something like
          // a typedef or using declaration. That declaration might be private
          // in the global context, which would be diagnosed by calling into
          // isCXXSimpleDeclaration, but may actually be fine in the context of
          // member functions and static variable definitions. Check if the next
          // token is also an identifier and assume a declaration.
          // We cannot check if the scopes match because the declarations could
          // involve namespaces and friend declarations.
          if (NextToken().is(tok::identifier))
            return true;
        }
        break;
      }
      case tok::kw_operator:
        return true;
      case tok::tilde:
        return true;
      default:
        break;
      }
    }
  }
    [[fallthrough]];
    // simple-declaration
  default:
    return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);
  }
}

bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
  // C++ 6.8p1:
  // There is an ambiguity in the grammar involving expression-statements and
  // declarations: An expression-statement with a function-style explicit type
  // conversion (5.2.3) as its leftmost subexpression can be indistinguishable
  // from a declaration where the first declarator starts with a '('. In those
  // cases the statement is a declaration. [Note: To disambiguate, the whole
  // statement might have to be examined to determine if it is an
  // expression-statement or a declaration].

  // C++ 6.8p3:
  // The disambiguation is purely syntactic; that is, the meaning of the names
  // occurring in such a statement, beyond whether they are type-names or not,
  // is not generally used in or changed by the disambiguation. Class
  // templates are instantiated as necessary to determine if a qualified name
  // is a type-name. Disambiguation precedes parsing, and a statement
  // disambiguated as a declaration may be an ill-formed declaration.

  // We don't have to parse all of the decl-specifier-seq part. There's only
  // an ambiguity if the first decl-specifier is
  // simple-type-specifier/typename-specifier followed by a '(', which may
  // indicate a function-style cast expression.
  // isCXXDeclarationSpecifier will return TPResult::Ambiguous only in such
  // a case.

  bool InvalidAsDeclaration = false;
  TPResult TPR = isCXXDeclarationSpecifier(
      ImplicitTypenameContext::No, TPResult::False, &InvalidAsDeclaration);
  if (TPR != TPResult::Ambiguous)
    return TPR != TPResult::False; // Returns true for TPResult::True or
                                   // TPResult::Error.

  // FIXME: TryParseSimpleDeclaration doesn't look past the first initializer,
  // and so gets some cases wrong. We can't carry on if we've already seen
  // something which makes this statement invalid as a declaration in this case,
  // since it can cause us to misparse valid code. Revisit this once
  // TryParseInitDeclaratorList is fixed.
  if (InvalidAsDeclaration)
    return false;

  // FIXME: Add statistics about the number of ambiguous statements encountered
  // and how they were resolved (number of declarations+number of expressions).

  // Ok, we have a simple-type-specifier/typename-specifier followed by a '(',
  // or an identifier which doesn't resolve as anything. We need tentative
  // parsing...

  {
    RevertingTentativeParsingAction PA(*this);
    TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
  }

  // In case of an error, let the declaration parsing code handle it.
  if (TPR == TPResult::Error)
    return true;

  // Declarations take precedence over expressions.
  if (TPR == TPResult::Ambiguous)
    TPR = TPResult::True;

  assert(TPR == TPResult::True || TPR == TPResult::False);
  return TPR == TPResult::True;
}

Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
  switch (Tok.getKind()) {
  case tok::kw__Atomic:
    if (NextToken().isNot(tok::l_paren)) {
      ConsumeToken();
      break;
    }
    [[fallthrough]];
  case tok::kw_typeof:
  case tok::kw___attribute:
#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
#include "clang/Basic/TransformTypeTraits.def"
  {
    ConsumeToken();
    if (Tok.isNot(tok::l_paren))
      return TPResult::Error;
    ConsumeParen();
    if (!SkipUntil(tok::r_paren))
      return TPResult::Error;
    break;
  }

  case tok::kw_class:
  case tok::kw_struct:
  case tok::kw_union:
  case tok::kw___interface:
  case tok::kw_enum:
    // elaborated-type-specifier:
    //     class-key attribute-specifier-seq[opt]
    //         nested-name-specifier[opt] identifier
    //     class-key nested-name-specifier[opt] template[opt] simple-template-id
    //     enum nested-name-specifier[opt] identifier
    //
    // FIXME: We don't support class-specifiers nor enum-specifiers here.
    ConsumeToken();

    // Skip attributes.
    if (!TrySkipAttributes())
      return TPResult::Error;

    if (TryAnnotateOptionalCXXScopeToken())
      return TPResult::Error;
    if (Tok.is(tok::annot_cxxscope))
      ConsumeAnnotationToken();
    if (Tok.is(tok::identifier))
      ConsumeToken();
    else if (Tok.is(tok::annot_template_id))
      ConsumeAnnotationToken();
    else
      return TPResult::Error;
    break;

  case tok::annot_cxxscope:
    ConsumeAnnotationToken();
    [[fallthrough]];
  default:
    ConsumeAnyToken();

    if (getLangOpts().ObjC && Tok.is(tok::less))
      return TryParseProtocolQualifiers();
    break;
  }

  return TPResult::Ambiguous;
}

Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
  bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);
  if (TryConsumeDeclarationSpecifier() == TPResult::Error)
    return TPResult::Error;

  // Two decl-specifiers in a row conclusively disambiguate this as being a
  // simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the
  // overwhelmingly common case that the next token is a '('.
  if (Tok.isNot(tok::l_paren)) {
    TPResult TPR = isCXXDeclarationSpecifier(ImplicitTypenameContext::No);
    if (TPR == TPResult::Ambiguous)
      return TPResult::True;
    if (TPR == TPResult::True || TPR == TPResult::Error)
      return TPR;
    assert(TPR == TPResult::False);
  }

  TPResult TPR = TryParseInitDeclaratorList(
      /*mayHaveTrailingReturnType=*/DeclSpecifierIsAuto);
  if (TPR != TPResult::Ambiguous)
    return TPR;

  if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
    return TPResult::False;

  return TPResult::Ambiguous;
}

Parser::TPResult
Parser::TryParseInitDeclaratorList(bool MayHaveTrailingReturnType) {
  while (true) {
    // declarator
    TPResult TPR = TryParseDeclarator(
        /*mayBeAbstract=*/false,
        /*mayHaveIdentifier=*/true,
        /*mayHaveDirectInit=*/false,
        /*mayHaveTrailingReturnType=*/MayHaveTrailingReturnType);
    if (TPR != TPResult::Ambiguous)
      return TPR;

    // [GNU] simple-asm-expr[opt] attributes[opt]
    if (Tok.isOneOf(tok::kw_asm, tok::kw___attribute))
      return TPResult::True;

    // initializer[opt]
    if (Tok.is(tok::l_paren)) {
      // Parse through the parens.
      ConsumeParen();
      if (!SkipUntil(tok::r_paren, StopAtSemi))
        return TPResult::Error;
    } else if (Tok.is(tok::l_brace)) {
      // A left-brace here is sufficient to disambiguate the parse; an
      // expression can never be followed directly by a braced-init-list.
      return TPResult::True;
    } else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
      // MSVC and g++ won't examine the rest of declarators if '=' is
      // encountered; they just conclude that we have a declaration.
      // EDG parses the initializer completely, which is the proper behavior
      // for this case.
      //
      // At present, Clang follows MSVC and g++, since the parser does not have
      // the ability to parse an expression fully without recording the
      // results of that parse.
      // FIXME: Handle this case correctly.
      //
      // Also allow 'in' after an Objective-C declaration as in:
      // for (int (^b)(void) in array). Ideally this should be done in the
      // context of parsing for-init-statement of a foreach statement only. But,
      // in any other context 'in' is invalid after a declaration and parser
      // issues the error regardless of outcome of this decision.
      // FIXME: Change if above assumption does not hold.
      return TPResult::True;
    }

    if (!TryConsumeToken(tok::comma))
      break;
  }

  return TPResult::Ambiguous;
}

struct Parser::ConditionDeclarationOrInitStatementState {
  Parser &P;
  bool CanBeExpression = true;
  bool CanBeCondition = true;
  bool CanBeInitStatement;
  bool CanBeForRangeDecl;

  ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement,
                                           bool CanBeForRangeDecl)
      : P(P), CanBeInitStatement(CanBeInitStatement),
        CanBeForRangeDecl(CanBeForRangeDecl) {}

  bool resolved() {
    return CanBeExpression + CanBeCondition + CanBeInitStatement +
               CanBeForRangeDecl < 2;
  }

  void markNotExpression() {
    CanBeExpression = false;

    if (!resolved()) {
      // FIXME: Unify the parsing codepaths for condition variables and
      // simple-declarations so that we don't need to eagerly figure out which
      // kind we have here. (Just parse init-declarators until we reach a
      // semicolon or right paren.)
      RevertingTentativeParsingAction PA(P);
      if (CanBeForRangeDecl) {
        // Skip until we hit a ')', ';', or a ':' with no matching '?'.
        // The final case is a for range declaration, the rest are not.
        unsigned QuestionColonDepth = 0;
        while (true) {
          P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
                      StopBeforeMatch);
          if (P.Tok.is(tok::question))
            ++QuestionColonDepth;
          else if (P.Tok.is(tok::colon)) {
            if (QuestionColonDepth)
              --QuestionColonDepth;
            else {
              CanBeCondition = CanBeInitStatement = false;
              return;
            }
          } else {
            CanBeForRangeDecl = false;
            break;
          }
          P.ConsumeToken();
        }
      } else {
        // Just skip until we hit a ')' or ';'.
        P.SkipUntil(tok::r_paren, tok::semi, StopBeforeMatch);
      }
      if (P.Tok.isNot(tok::r_paren))
        CanBeCondition = CanBeForRangeDecl = false;
      if (P.Tok.isNot(tok::semi))
        CanBeInitStatement = false;
    }
  }

  bool markNotCondition() {
    CanBeCondition = false;
    return resolved();
  }

  bool markNotForRangeDecl() {
    CanBeForRangeDecl = false;
    return resolved();
  }

  bool update(TPResult IsDecl) {
    switch (IsDecl) {
    case TPResult::True:
      markNotExpression();
      assert(resolved() && "can't continue after tentative parsing bails out");
      break;
    case TPResult::False:
      CanBeCondition = CanBeInitStatement = CanBeForRangeDecl = false;
      break;
    case TPResult::Ambiguous:
      break;
    case TPResult::Error:
      CanBeExpression = CanBeCondition = CanBeInitStatement =
          CanBeForRangeDecl = false;
      break;
    }
    return resolved();
  }

  ConditionOrInitStatement result() const {
    assert(CanBeExpression + CanBeCondition + CanBeInitStatement +
                   CanBeForRangeDecl < 2 &&
           "result called but not yet resolved");
    if (CanBeExpression)
      return ConditionOrInitStatement::Expression;
    if (CanBeCondition)
      return ConditionOrInitStatement::ConditionDecl;
    if (CanBeInitStatement)
      return ConditionOrInitStatement::InitStmtDecl;
    if (CanBeForRangeDecl)
      return ConditionOrInitStatement::ForRangeDecl;
    return ConditionOrInitStatement::Error;
  }
};

bool Parser::isEnumBase(bool AllowSemi) {
  assert(Tok.is(tok::colon) && "should be looking at the ':'");

  RevertingTentativeParsingAction PA(*this);
  // ':'
  ConsumeToken();

  // type-specifier-seq
  bool InvalidAsDeclSpec = false;
  // FIXME: We could disallow non-type decl-specifiers here, but it makes no
  // difference: those specifiers are ill-formed regardless of the
  // interpretation.
  TPResult R = isCXXDeclarationSpecifier(ImplicitTypenameContext::No,
                                         /*BracedCastResult=*/TPResult::True,
                                         &InvalidAsDeclSpec);
  if (R == TPResult::Ambiguous) {
    // We either have a decl-specifier followed by '(' or an undeclared
    // identifier.
    if (TryConsumeDeclarationSpecifier() == TPResult::Error)
      return true;

    // If we get to the end of the enum-base, we hit either a '{' or a ';'.
    // Don't bother checking the enumerator-list.
    if (Tok.is(tok::l_brace) || (AllowSemi && Tok.is(tok::semi)))
      return true;

    // A second decl-specifier unambiguously indicatges an enum-base.
    R = isCXXDeclarationSpecifier(ImplicitTypenameContext::No, TPResult::True,
                                  &InvalidAsDeclSpec);
  }

  return R != TPResult::False;
}

Parser::ConditionOrInitStatement
Parser::isCXXConditionDeclarationOrInitStatement(bool CanBeInitStatement,
                                                 bool CanBeForRangeDecl) {
  ConditionDeclarationOrInitStatementState State(*this, CanBeInitStatement,
                                                 CanBeForRangeDecl);

  if (CanBeInitStatement && Tok.is(tok::kw_using))
    return ConditionOrInitStatement::InitStmtDecl;
  if (State.update(isCXXDeclarationSpecifier(ImplicitTypenameContext::No)))
    return State.result();

  // It might be a declaration; we need tentative parsing.
  RevertingTentativeParsingAction PA(*this);

  // FIXME: A tag definition unambiguously tells us this is an init-statement.
  bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
  if (State.update(TryConsumeDeclarationSpecifier()))
    return State.result();
  assert(Tok.is(tok::l_paren) && "Expected '('");

  while (true) {
    // Consume a declarator.
    if (State.update(TryParseDeclarator(
            /*mayBeAbstract=*/false,
            /*mayHaveIdentifier=*/true,
            /*mayHaveDirectInit=*/false,
            /*mayHaveTrailingReturnType=*/MayHaveTrailingReturnType)))
      return State.result();

    // Attributes, asm label, or an initializer imply this is not an expression.
    // FIXME: Disambiguate properly after an = instead of assuming that it's a
    // valid declaration.
    if (Tok.isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
        (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))) {
      State.markNotExpression();
      return State.result();
    }

    // A colon here identifies a for-range declaration.
    if (State.CanBeForRangeDecl && Tok.is(tok::colon))
      return ConditionOrInitStatement::ForRangeDecl;

    // At this point, it can't be a condition any more, because a condition
    // must have a brace-or-equal-initializer.
    if (State.markNotCondition())
      return State.result();

    // Likewise, it can't be a for-range declaration any more.
    if (State.markNotForRangeDecl())
      return State.result();

    // A parenthesized initializer could be part of an expression or a
    // simple-declaration.
    if (Tok.is(tok::l_paren)) {
      ConsumeParen();
      SkipUntil(tok::r_paren, StopAtSemi);
    }

    if (!TryConsumeToken(tok::comma))
      break;
  }

  // We reached the end. If it can now be some kind of decl, then it is.
  if (State.CanBeCondition && Tok.is(tok::r_paren))
    return ConditionOrInitStatement::ConditionDecl;
  else if (State.CanBeInitStatement && Tok.is(tok::semi))
    return ConditionOrInitStatement::InitStmtDecl;
  else
    return ConditionOrInitStatement::Expression;
}

bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {

  isAmbiguous = false;

  // C++ 8.2p2:
  // The ambiguity arising from the similarity between a function-style cast and
  // a type-id can occur in different contexts. The ambiguity appears as a
  // choice between a function-style cast expression and a declaration of a
  // type. The resolution is that any construct that could possibly be a type-id
  // in its syntactic context shall be considered a type-id.

  TPResult TPR = isCXXDeclarationSpecifier(ImplicitTypenameContext::No);
  if (TPR != TPResult::Ambiguous)
    return TPR != TPResult::False; // Returns true for TPResult::True or
                                     // TPResult::Error.

  // FIXME: Add statistics about the number of ambiguous statements encountered
  // and how they were resolved (number of declarations+number of expressions).

  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
  // We need tentative parsing...

  RevertingTentativeParsingAction PA(*this);
  bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);

  // type-specifier-seq
  TryConsumeDeclarationSpecifier();
  assert(Tok.is(tok::l_paren) && "Expected '('");

  // declarator
  TPR = TryParseDeclarator(true /*mayBeAbstract*/, false /*mayHaveIdentifier*/,
                           /*mayHaveDirectInit=*/false,
                           MayHaveTrailingReturnType);

  // In case of an error, let the declaration parsing code handle it.
  if (TPR == TPResult::Error)
    TPR = TPResult::True;

  if (TPR == TPResult::Ambiguous) {
    // We are supposed to be inside parens, so if after the abstract declarator
    // we encounter a ')' this is a type-id, otherwise it's an expression.
    if (Context == TentativeCXXTypeIdContext::InParens &&
        Tok.is(tok::r_paren)) {
      TPR = TPResult::True;
      isAmbiguous = true;
    // We are supposed to be inside the first operand to a _Generic selection
    // expression, so if we find a comma after the declarator, we've found a
    // type and not an expression.
    } else if (Context ==
                   TentativeCXXTypeIdContext::AsGenericSelectionArgument &&
               Tok.is(tok::comma)) {
      TPR = TPResult::True;
      isAmbiguous = true;
    // We are supposed to be inside a template argument, so if after
    // the abstract declarator we encounter a '>', '>>' (in C++0x), or
    // ','; or, in C++0x, an ellipsis immediately preceding such, this
    // is a type-id. Otherwise, it's an expression.
    } else if (Context == TentativeCXXTypeIdContext::AsTemplateArgument &&
               (Tok.isOneOf(tok::greater, tok::comma) ||
                (getLangOpts().CPlusPlus11 &&
                 (Tok.isOneOf(tok::greatergreater,
                              tok::greatergreatergreater) ||
                  (Tok.is(tok::ellipsis) &&
                   NextToken().isOneOf(tok::greater, tok::greatergreater,
                                       tok::greatergreatergreater,
                                       tok::comma)))))) {
      TPR = TPResult::True;
      isAmbiguous = true;

    } else if (Context == TentativeCXXTypeIdContext::InTrailingReturnType) {
      TPR = TPResult::True;
      isAmbiguous = true;
    } else
      TPR = TPResult::False;
  }

  assert(TPR == TPResult::True || TPR == TPResult::False);
  return TPR == TPResult::True;
}

CXX11AttributeKind
Parser::isCXX11AttributeSpecifier(bool Disambiguate,
                                  bool OuterMightBeMessageSend) {
  // alignas is an attribute specifier in C++ but not in C23.
  if (Tok.is(tok::kw_alignas) && !getLangOpts().C23)
    return CXX11AttributeKind::AttributeSpecifier;

  if (Tok.isRegularKeywordAttribute())
    return CXX11AttributeKind::AttributeSpecifier;

  if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square))
    return CXX11AttributeKind::NotAttributeSpecifier;

  // No tentative parsing if we don't need to look for ']]' or a lambda.
  if (!Disambiguate && !getLangOpts().ObjC)
    return CXX11AttributeKind::AttributeSpecifier;

  // '[[using ns: ...]]' is an attribute.
  if (GetLookAheadToken(2).is(tok::kw_using))
    return CXX11AttributeKind::AttributeSpecifier;

  RevertingTentativeParsingAction PA(*this);

  // Opening brackets were checked for above.
  ConsumeBracket();

  if (!getLangOpts().ObjC) {
    ConsumeBracket();

    bool IsAttribute = SkipUntil(tok::r_square);
    IsAttribute &= Tok.is(tok::r_square);

    return IsAttribute ? CXX11AttributeKind::AttributeSpecifier
                       : CXX11AttributeKind::InvalidAttributeSpecifier;
  }

  // In Obj-C++11, we need to distinguish four situations:
  //  1a) int x[[attr]];                     C++11 attribute.
  //  1b) [[attr]];                          C++11 statement attribute.
  //   2) int x[[obj](){ return 1; }()];     Lambda in array size/index.
  //  3a) int x[[obj get]];                  Message send in array size/index.
  //  3b) [[Class alloc] init];              Message send in message send.
  //   4) [[obj]{ return self; }() doStuff]; Lambda in message send.
  // (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted.

  // Check to see if this is a lambda-expression.
  // FIXME: If this disambiguation is too slow, fold the tentative lambda parse
  // into the tentative attribute parse below.
  {
    RevertingTentativeParsingAction LambdaTPA(*this);
    LambdaIntroducer Intro;
    LambdaIntroducerTentativeParse Tentative;
    if (ParseLambdaIntroducer(Intro, &Tentative)) {
      // We hit a hard error after deciding this was not an attribute.
      // FIXME: Don't parse and annotate expressions when disambiguating
      // against an attribute.
      return CXX11AttributeKind::NotAttributeSpecifier;
    }

    switch (Tentative) {
    case LambdaIntroducerTentativeParse::MessageSend:
      // Case 3: The inner construct is definitely a message send, so the
      // outer construct is definitely not an attribute.
      return CXX11AttributeKind::NotAttributeSpecifier;

    case LambdaIntroducerTentativeParse::Success:
    case LambdaIntroducerTentativeParse::Incomplete:
      // This is a lambda-introducer or attribute-specifier.
      if (Tok.is(tok::r_square))
        // Case 1: C++11 attribute.
        return CXX11AttributeKind::AttributeSpecifier;

      if (OuterMightBeMessageSend)
        // Case 4: Lambda in message send.
        return CXX11AttributeKind::NotAttributeSpecifier;

      // Case 2: Lambda in array size / index.
      return CXX11AttributeKind::InvalidAttributeSpecifier;

    case LambdaIntroducerTentativeParse::Invalid:
      // No idea what this is; we couldn't parse it as a lambda-introducer.
      // Might still be an attribute-specifier or a message send.
      break;
    }
  }

  ConsumeBracket();

  // If we don't have a lambda-introducer, then we have an attribute or a
  // message-send.
  bool IsAttribute = true;
  while (Tok.isNot(tok::r_square)) {
    if (Tok.is(tok::comma)) {
      // Case 1: Stray commas can only occur in attributes.
      return CXX11AttributeKind::AttributeSpecifier;
    }

    // Parse the attribute-token, if present.
    // C++11 [dcl.attr.grammar]:
    //   If a keyword or an alternative token that satisfies the syntactic
    //   requirements of an identifier is contained in an attribute-token,
    //   it is considered an identifier.
    SourceLocation Loc;
    if (!TryParseCXX11AttributeIdentifier(Loc)) {
      IsAttribute = false;
      break;
    }
    if (Tok.is(tok::coloncolon)) {
      ConsumeToken();
      if (!TryParseCXX11AttributeIdentifier(Loc)) {
        IsAttribute = false;
        break;
      }
    }

    // Parse the attribute-argument-clause, if present.
    if (Tok.is(tok::l_paren)) {
      ConsumeParen();
      if (!SkipUntil(tok::r_paren)) {
        IsAttribute = false;
        break;
      }
    }

    TryConsumeToken(tok::ellipsis);

    if (!TryConsumeToken(tok::comma))
      break;
  }

  // An attribute must end ']]'.
  if (IsAttribute) {
    if (Tok.is(tok::r_square)) {
      ConsumeBracket();
      IsAttribute = Tok.is(tok::r_square);
    } else {
      IsAttribute = false;
    }
  }

  if (IsAttribute)
    // Case 1: C++11 statement attribute.
    return CXX11AttributeKind::AttributeSpecifier;

  // Case 3: Message send.
  return CXX11AttributeKind::NotAttributeSpecifier;
}

bool Parser::TrySkipAttributes() {
  while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
                     tok::kw_alignas) ||
         Tok.isRegularKeywordAttribute()) {
    if (Tok.is(tok::l_square)) {
      ConsumeBracket();
      if (Tok.isNot(tok::l_square))
        return false;
      ConsumeBracket();
      if (!SkipUntil(tok::r_square) || Tok.isNot(tok::r_square))
        return false;
      // Note that explicitly checking for `[[` and `]]` allows to fail as
      // expected in the case of the Objective-C message send syntax.
      ConsumeBracket();
    } else if (Tok.isRegularKeywordAttribute() &&
               !doesKeywordAttributeTakeArgs(Tok.getKind())) {
      ConsumeToken();
    } else {
      ConsumeToken();
      if (Tok.isNot(tok::l_paren))
        return false;
      ConsumeParen();
      if (!SkipUntil(tok::r_paren))
        return false;
    }
  }

  return true;
}

Parser::TPResult Parser::TryParsePtrOperatorSeq() {
  while (true) {
    if (TryAnnotateOptionalCXXScopeToken(true))
      return TPResult::Error;

    if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
        (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {
      // ptr-operator
      ConsumeAnyToken();

      // Skip attributes.
      if (!TrySkipAttributes())
        return TPResult::Error;

      while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
                         tok::kw__Nonnull, tok::kw__Nullable,
                         tok::kw__Nullable_result, tok::kw__Null_unspecified,
                         tok::kw__Atomic))
        ConsumeToken();
    } else {
      return TPResult::True;
    }
  }
}

Parser::TPResult Parser::TryParseOperatorId() {
  assert(Tok.is(tok::kw_operator));
  ConsumeToken();

  // Maybe this is an operator-function-id.
  switch (Tok.getKind()) {
  case tok::kw_new: case tok::kw_delete:
    ConsumeToken();
    if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) {
      ConsumeBracket();
      ConsumeBracket();
    }
    return TPResult::True;

#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
  case tok::Token:
#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
#include "clang/Basic/OperatorKinds.def"
    ConsumeToken();
    return TPResult::True;

  case tok::l_square:
    if (NextToken().is(tok::r_square)) {
      ConsumeBracket();
      ConsumeBracket();
      return TPResult::True;
    }
    break;

  case tok::l_paren:
    if (NextToken().is(tok::r_paren)) {
      ConsumeParen();
      ConsumeParen();
      return TPResult::True;
    }
    break;

  default:
    break;
  }

  // Maybe this is a literal-operator-id.
  if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) {
    bool FoundUDSuffix = false;
    do {
      FoundUDSuffix |= Tok.hasUDSuffix();
      ConsumeStringToken();
    } while (isTokenStringLiteral());

    if (!FoundUDSuffix) {
      if (Tok.is(tok::identifier))
        ConsumeToken();
      else
        return TPResult::Error;
    }
    return TPResult::True;
  }

  // Maybe this is a conversion-function-id.
  bool AnyDeclSpecifiers = false;
  while (true) {
    TPResult TPR = isCXXDeclarationSpecifier(ImplicitTypenameContext::No);
    if (TPR == TPResult::Error)
      return TPR;
    if (TPR == TPResult::False) {
      if (!AnyDeclSpecifiers)
        return TPResult::Error;
      break;
    }
    if (TryConsumeDeclarationSpecifier() == TPResult::Error)
      return TPResult::Error;
    AnyDeclSpecifiers = true;
  }
  return TryParsePtrOperatorSeq();
}

Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
                                            bool mayHaveIdentifier,
                                            bool mayHaveDirectInit,
                                            bool mayHaveTrailingReturnType) {
  // declarator:
  //   direct-declarator
  //   ptr-operator declarator
  if (TryParsePtrOperatorSeq() == TPResult::Error)
    return TPResult::Error;

  // direct-declarator:
  // direct-abstract-declarator:
  if (Tok.is(tok::ellipsis))
    ConsumeToken();

  if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||
       (Tok.is(tok::annot_cxxscope) && (NextToken().is(tok::identifier) ||
                                        NextToken().is(tok::kw_operator)))) &&
      mayHaveIdentifier) {
    // declarator-id
    if (Tok.is(tok::annot_cxxscope)) {
      CXXScopeSpec SS;
      Actions.RestoreNestedNameSpecifierAnnotation(
          Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
      if (SS.isInvalid())
        return TPResult::Error;
      ConsumeAnnotationToken();
    } else if (Tok.is(tok::identifier)) {
      TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
    }
    if (Tok.is(tok::kw_operator)) {
      if (TryParseOperatorId() == TPResult::Error)
        return TPResult::Error;
    } else
      ConsumeToken();
  } else if (Tok.is(tok::l_paren)) {
    ConsumeParen();
    if (mayBeAbstract &&
        (Tok.is(tok::r_paren) || // 'int()' is a function.
                                 // 'int(...)' is a function.
         (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) ||
         isDeclarationSpecifier(
             ImplicitTypenameContext::No))) { // 'int(int)' is a function.
      // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
      //        exception-specification[opt]
      TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
      if (TPR != TPResult::Ambiguous)
        return TPR;
    } else {
      // '(' declarator ')'
      // '(' attributes declarator ')'
      // '(' abstract-declarator ')'
      if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
                      tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
                      tok::kw___regcall, tok::kw___vectorcall))
        return TPResult::True; // attributes indicate declaration
      TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
      if (TPR != TPResult::Ambiguous)
        return TPR;
      if (Tok.isNot(tok::r_paren))
        return TPResult::False;
      ConsumeParen();
    }
  } else if (!mayBeAbstract) {
    return TPResult::False;
  }

  if (mayHaveDirectInit)
    return TPResult::Ambiguous;

  while (true) {
    TPResult TPR(TPResult::Ambiguous);

    if (Tok.is(tok::l_paren)) {
      // Check whether we have a function declarator or a possible ctor-style
      // initializer that follows the declarator. Note that ctor-style
      // initializers are not possible in contexts where abstract declarators
      // are allowed.
      if (!mayBeAbstract && !isCXXFunctionDeclarator())
        break;

      // direct-declarator '(' parameter-declaration-clause ')'
      //        cv-qualifier-seq[opt] exception-specification[opt]
      ConsumeParen();
      TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
    } else if (Tok.is(tok::l_square)) {
      // direct-declarator '[' constant-expression[opt] ']'
      // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
      TPR = TryParseBracketDeclarator();
    } else if (Tok.is(tok::kw_requires)) {
      // declarator requires-clause
      // A requires clause indicates a function declaration.
      TPR = TPResult::True;
    } else {
      break;
    }

    if (TPR != TPResult::Ambiguous)
      return TPR;
  }

  return TPResult::Ambiguous;
}

bool Parser::isTentativelyDeclared(IdentifierInfo *II) {
  return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
}

namespace {
class TentativeParseCCC final : public CorrectionCandidateCallback {
public:
  TentativeParseCCC(const Token &Next) {
    WantRemainingKeywords = false;
    WantTypeSpecifiers =
        Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
                     tok::identifier, tok::comma);
  }

  bool ValidateCandidate(const TypoCorrection &Candidate) override {
    // Reject any candidate that only resolves to instance members since they
    // aren't viable as standalone identifiers instead of member references.
    if (Candidate.isResolved() && !Candidate.isKeyword() &&
        llvm::all_of(Candidate,
                     [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
      return false;

    return CorrectionCandidateCallback::ValidateCandidate(Candidate);
  }

  std::unique_ptr<CorrectionCandidateCallback> clone() override {
    return std::make_unique<TentativeParseCCC>(*this);
  }
};
}

Parser::TPResult
Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
                                  Parser::TPResult BracedCastResult,
                                  bool *InvalidAsDeclSpec) {
  auto IsPlaceholderSpecifier = [&](TemplateIdAnnotation *TemplateId,
                                    int Lookahead) {
    // We have a placeholder-constraint (we check for 'auto' or 'decltype' to
    // distinguish 'C<int>;' from 'C<int> auto c = 1;')
    return TemplateId->Kind == TNK_Concept_template &&
           (GetLookAheadToken(Lookahead + 1)
                .isOneOf(tok::kw_auto, tok::kw_decltype,
                         // If we have an identifier here, the user probably
                         // forgot the 'auto' in the placeholder constraint,
                         // e.g. 'C<int> x = 2;' This will be diagnosed nicely
                         // later, so disambiguate as a declaration.
                         tok::identifier,
                         // CVR qualifierslikely the same situation for the
                         // user, so let this be diagnosed nicely later. We
                         // cannot handle references here, as `C<int> & Other`
                         // and `C<int> && Other` are both legal.
                         tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
            // While `C<int> && Other` is legal, doing so while not specifying a
            // template argument is NOT, so see if we can fix up in that case at
            // minimum. Concepts require at least 1 template parameter, so we
            // can count on the argument count.
            // FIXME: In the future, we migth be able to have SEMA look up the
            // declaration for this concept, and see how many template
            // parameters it has.  If the concept isn't fully specified, it is
            // possibly a situation where we want deduction, such as:
            // `BinaryConcept<int> auto f = bar();`
            (TemplateId->NumArgs == 0 &&
             GetLookAheadToken(Lookahead + 1).isOneOf(tok::amp, tok::ampamp)));
  };
  switch (Tok.getKind()) {
  case tok::identifier: {
    if (GetLookAheadToken(1).is(tok::ellipsis) &&
        GetLookAheadToken(2).is(tok::l_square)) {

      if (TryAnnotateTypeOrScopeToken())
        return TPResult::Error;
      if (Tok.is(tok::identifier))
        return TPResult::False;
      return isCXXDeclarationSpecifier(ImplicitTypenameContext::No,
                                       BracedCastResult, InvalidAsDeclSpec);
    }

    // Check for need to substitute AltiVec __vector keyword
    // for "vector" identifier.
    if (TryAltiVecVectorToken())
      return TPResult::True;

    const Token &Next = NextToken();
    // In 'foo bar', 'foo' is always a type name outside of Objective-C.
    if (!getLangOpts().ObjC && Next.is(tok::identifier))
      return TPResult::True;

    // If this identifier was reverted from a token ID, and the next token
    // is a '(', we assume it to be a use of a type trait, so this
    // can never be a type name.
    if (Next.is(tok::l_paren) &&
        Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier() &&
        isRevertibleTypeTrait(Tok.getIdentifierInfo())) {
      return TPResult::False;
    }

    if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
      // Determine whether this is a valid expression. If not, we will hit
      // a parse error one way or another. In that case, tell the caller that
      // this is ambiguous. Typo-correct to type and expression keywords and
      // to types and identifiers, in order to try to recover from errors.
      TentativeParseCCC CCC(Next);
      switch (TryAnnotateName(&CCC)) {
      case AnnotatedNameKind::Error:
        return TPResult::Error;
      case AnnotatedNameKind::TentativeDecl:
        return TPResult::False;
      case AnnotatedNameKind::TemplateName:
        // In C++17, this could be a type template for class template argument
        // deduction. Try to form a type annotation for it. If we're in a
        // template template argument, we'll undo this when checking the
        // validity of the argument.
        if (getLangOpts().CPlusPlus17) {
          if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))
            return TPResult::Error;
          if (Tok.isNot(tok::identifier))
            break;
        }

        // A bare type template-name which can't be a template template
        // argument is an error, and was probably intended to be a type.
        return GreaterThanIsOperator ? TPResult::True : TPResult::False;
      case AnnotatedNameKind::Unresolved:
        return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
      case AnnotatedNameKind::Success:
        break;
      }
      assert(Tok.isNot(tok::identifier) &&
             "TryAnnotateName succeeded without producing an annotation");
    } else {
      // This might possibly be a type with a dependent scope specifier and
      // a missing 'typename' keyword. Don't use TryAnnotateName in this case,
      // since it will annotate as a primary expression, and we want to use the
      // "missing 'typename'" logic.
      if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))
        return TPResult::Error;
      // If annotation failed, assume it's a non-type.
      // FIXME: If this happens due to an undeclared identifier, treat it as
      // ambiguous.
      if (Tok.is(tok::identifier))
        return TPResult::False;
    }

    // We annotated this token as something. Recurse to handle whatever we got.
    return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
                                     InvalidAsDeclSpec);
  }

  case tok::kw_typename:  // typename T::type
    // Annotate typenames and C++ scope specifiers.  If we get one, just
    // recurse to handle whatever we get.
    if (TryAnnotateTypeOrScopeToken(ImplicitTypenameContext::Yes))
      return TPResult::Error;
    return isCXXDeclarationSpecifier(ImplicitTypenameContext::Yes,
                                     BracedCastResult, InvalidAsDeclSpec);

  case tok::kw_auto: {
    if (!getLangOpts().CPlusPlus23)
      return TPResult::True;
    if (NextToken().is(tok::l_brace))
      return TPResult::False;
    if (NextToken().is(tok::l_paren))
      return TPResult::Ambiguous;
    return TPResult::True;
  }

  case tok::coloncolon: {    // ::foo::bar
    const Token &Next = NextToken();
    if (Next.isOneOf(tok::kw_new,       // ::new
                     tok::kw_delete))   // ::delete
      return TPResult::False;
    [[fallthrough]];
  }
  case tok::kw___super:
  case tok::kw_decltype:
    // Annotate typenames and C++ scope specifiers.  If we get one, just
    // recurse to handle whatever we get.
    if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))
      return TPResult::Error;
    return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
                                     InvalidAsDeclSpec);

    // decl-specifier:
    //   storage-class-specifier
    //   type-specifier
    //   function-specifier
    //   'friend'
    //   'typedef'
    //   'constexpr'
  case tok::kw_friend:
  case tok::kw_typedef:
  case tok::kw_constexpr:
  case tok::kw_consteval:
  case tok::kw_constinit:
    // storage-class-specifier
  case tok::kw_register:
  case tok::kw_static:
  case tok::kw_extern:
  case tok::kw_mutable:
  case tok::kw___thread:
  case tok::kw_thread_local:
  case tok::kw__Thread_local:
    // function-specifier
  case tok::kw_inline:
  case tok::kw_virtual:
  case tok::kw_explicit:

    // Modules
  case tok::kw___module_private__:

    // Debugger support
  case tok::kw___unknown_anytype:

    // type-specifier:
    //   simple-type-specifier
    //   class-specifier
    //   enum-specifier
    //   elaborated-type-specifier
    //   typename-specifier
    //   cv-qualifier

    // class-specifier
    // elaborated-type-specifier
  case tok::kw_class:
  case tok::kw_struct:
  case tok::kw_union:
  case tok::kw___interface:
    // enum-specifier
  case tok::kw_enum:
    // cv-qualifier
  case tok::kw_const:
  case tok::kw_volatile:
    return TPResult::True;

    // OpenCL address space qualifiers
  case tok::kw_private:
    if (!getLangOpts().OpenCL)
      return TPResult::False;
    [[fallthrough]];
  case tok::kw___private:
  case tok::kw___local:
  case tok::kw___global:
  case tok::kw___constant:
  case tok::kw___generic:
    // OpenCL access qualifiers
  case tok::kw___read_only:
  case tok::kw___write_only:
  case tok::kw___read_write:
    // OpenCL pipe
  case tok::kw_pipe:

    // HLSL address space qualifiers
  case tok::kw_groupshared:
  case tok::kw_in:
  case tok::kw_inout:
  case tok::kw_out:

    // GNU
  case tok::kw_restrict:
  case tok::kw__Complex:
  case tok::kw___attribute:
  case tok::kw___auto_type:
    return TPResult::True;

    // Microsoft
  case tok::kw___declspec:
  case tok::kw___cdecl:
  case tok::kw___stdcall:
  case tok::kw___fastcall:
  case tok::kw___thiscall:
  case tok::kw___regcall:
  case tok::kw___vectorcall:
  case tok::kw___w64:
  case tok::kw___sptr:
  case tok::kw___uptr:
  case tok::kw___ptr64:
  case tok::kw___ptr32:
  case tok::kw___forceinline:
  case tok::kw___unaligned:
  case tok::kw__Nonnull:
  case tok::kw__Nullable:
  case tok::kw__Nullable_result:
  case tok::kw__Null_unspecified:
  case tok::kw___kindof:
    return TPResult::True;

    // WebAssemblyFuncref
  case tok::kw___funcref:
    return TPResult::True;

    // Borland
  case tok::kw___pascal:
    return TPResult::True;

    // AltiVec
  case tok::kw___vector:
    return TPResult::True;

  case tok::kw_this: {
    // Try to parse a C++23 Explicit Object Parameter
    // We do that in all language modes to produce a better diagnostic.
    if (getLangOpts().CPlusPlus) {
      RevertingTentativeParsingAction PA(*this);
      ConsumeToken();
      return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
                                       InvalidAsDeclSpec);
    }
    return TPResult::False;
  }
  case tok::annot_template_id: {
    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
    // If lookup for the template-name found nothing, don't assume we have a
    // definitive disambiguation result yet.
    if ((TemplateId->hasInvalidName() ||
         TemplateId->Kind == TNK_Undeclared_template) &&
        InvalidAsDeclSpec) {
      // 'template-id(' can be a valid expression but not a valid decl spec if
      // the template-name is not declared, but we don't consider this to be a
      // definitive disambiguation. In any other context, it's an error either
      // way.
      *InvalidAsDeclSpec = NextToken().is(tok::l_paren);
      return TPResult::Ambiguous;
    }
    if (TemplateId->hasInvalidName())
      return TPResult::Error;
    if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/0))
      return TPResult::True;
    if (TemplateId->Kind != TNK_Type_template)
      return TPResult::False;
    CXXScopeSpec SS;
    AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
    assert(Tok.is(tok::annot_typename));
    goto case_typename;
  }

  case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
    // We've already annotated a scope; try to annotate a type.
    if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))
      return TPResult::Error;
    if (!Tok.is(tok::annot_typename)) {
      if (Tok.is(tok::annot_cxxscope) &&
          NextToken().is(tok::annot_template_id)) {
        TemplateIdAnnotation *TemplateId =
            takeTemplateIdAnnotation(NextToken());
        if (TemplateId->hasInvalidName()) {
          if (InvalidAsDeclSpec) {
            *InvalidAsDeclSpec = NextToken().is(tok::l_paren);
            return TPResult::Ambiguous;
          }
          return TPResult::Error;
        }
        if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/1))
          return TPResult::True;
      }
      // If the next token is an identifier or a type qualifier, then this
      // can't possibly be a valid expression either.
      if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) {
        CXXScopeSpec SS;
        Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
                                                     Tok.getAnnotationRange(),
                                                     SS);
        if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) {
          RevertingTentativeParsingAction PA(*this);
          ConsumeAnnotationToken();
          ConsumeToken();
          bool isIdentifier = Tok.is(tok::identifier);
          TPResult TPR = TPResult::False;
          if (!isIdentifier)
            TPR = isCXXDeclarationSpecifier(
                AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);

          if (isIdentifier ||
              TPR == TPResult::True || TPR == TPResult::Error)
            return TPResult::Error;

          if (InvalidAsDeclSpec) {
            // We can't tell whether this is a missing 'typename' or a valid
            // expression.
            *InvalidAsDeclSpec = true;
            return TPResult::Ambiguous;
          } else {
            // In MS mode, if InvalidAsDeclSpec is not provided, and the tokens
            // are or the form *) or &) *> or &> &&>, this can't be an expression.
            // The typename must be missing.
            if (getLangOpts().MSVCCompat) {
              if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
                   (NextToken().is(tok::r_paren) ||
                    NextToken().is(tok::greater))) ||
                  (Tok.is(tok::ampamp) && NextToken().is(tok::greater)))
                return TPResult::True;
            }
          }
        } else {
          // Try to resolve the name. If it doesn't exist, assume it was
          // intended to name a type and keep disambiguating.
          switch (TryAnnotateName(/*CCC=*/nullptr, AllowImplicitTypename)) {
          case AnnotatedNameKind::Error:
            return TPResult::Error;
          case AnnotatedNameKind::TentativeDecl:
            return TPResult::False;
          case AnnotatedNameKind::TemplateName:
            // In C++17, this could be a type template for class template
            // argument deduction.
            if (getLangOpts().CPlusPlus17) {
              if (TryAnnotateTypeOrScopeToken())
                return TPResult::Error;
              // If we annotated then the current token should not still be ::
              // FIXME we may want to also check for tok::annot_typename but
              // currently don't have a test case.
              if (Tok.isNot(tok::annot_cxxscope))
                break;
            }

            // A bare type template-name which can't be a template template
            // argument is an error, and was probably intended to be a type.
            // In C++17, this could be class template argument deduction.
            return (getLangOpts().CPlusPlus17 || GreaterThanIsOperator)
                       ? TPResult::True
                       : TPResult::False;
          case AnnotatedNameKind::Unresolved:
            return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
          case AnnotatedNameKind::Success:
            break;
          }

          // Annotated it, check again.
          assert(Tok.isNot(tok::annot_cxxscope) ||
                 NextToken().isNot(tok::identifier));
          return isCXXDeclarationSpecifier(AllowImplicitTypename,
                                           BracedCastResult, InvalidAsDeclSpec);
        }
      }
      return TPResult::False;
    }
    // If that succeeded, fallthrough into the generic simple-type-id case.
    [[fallthrough]];

    // The ambiguity resides in a simple-type-specifier/typename-specifier
    // followed by a '('. The '(' could either be the start of:
    //
    //   direct-declarator:
    //     '(' declarator ')'
    //
    //   direct-abstract-declarator:
    //     '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
    //              exception-specification[opt]
    //     '(' abstract-declarator ')'
    //
    // or part of a function-style cast expression:
    //
    //     simple-type-specifier '(' expression-list[opt] ')'
    //

    // simple-type-specifier:

  case tok::annot_typename:
  case_typename:
    // In Objective-C, we might have a protocol-qualified type.
    if (getLangOpts().ObjC && NextToken().is(tok::less)) {
      // Tentatively parse the protocol qualifiers.
      RevertingTentativeParsingAction PA(*this);
      ConsumeAnyToken(); // The type token

      TPResult TPR = TryParseProtocolQualifiers();
      bool isFollowedByParen = Tok.is(tok::l_paren);
      bool isFollowedByBrace = Tok.is(tok::l_brace);

      if (TPR == TPResult::Error)
        return TPResult::Error;

      if (isFollowedByParen)
        return TPResult::Ambiguous;

      if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
        return BracedCastResult;

      return TPResult::True;
    }

    [[fallthrough]];

  case tok::kw_char:
  case tok::kw_wchar_t:
  case tok::kw_char8_t:
  case tok::kw_char16_t:
  case tok::kw_char32_t:
  case tok::kw_bool:
  case tok::kw_short:
  case tok::kw_int:
  case tok::kw_long:
  case tok::kw___int64:
  case tok::kw___int128:
  case tok::kw_signed:
  case tok::kw_unsigned:
  case tok::kw_half:
  case tok::kw_float:
  case tok::kw_double:
  case tok::kw___bf16:
  case tok::kw__Float16:
  case tok::kw___float128:
  case tok::kw___ibm128:
  case tok::kw_void:
  case tok::annot_decltype:
  case tok::kw__Accum:
  case tok::kw__Fract:
  case tok::kw__Sat:
  case tok::annot_pack_indexing_type:
#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
#include "clang/Basic/OpenCLImageTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
#include "clang/Basic/HLSLIntangibleTypes.def"
    if (NextToken().is(tok::l_paren))
      return TPResult::Ambiguous;

    // This is a function-style cast in all cases we disambiguate other than
    // one:
    //   struct S {
    //     enum E : int { a = 4 }; // enum
    //     enum E : int { 4 };     // bit-field
    //   };
    if (getLangOpts().CPlusPlus11 && NextToken().is(tok::l_brace))
      return BracedCastResult;

    if (isStartOfObjCClassMessageMissingOpenBracket())
      return TPResult::False;

    return TPResult::True;

  // GNU typeof support.
  case tok::kw_typeof: {
    if (NextToken().isNot(tok::l_paren))
      return TPResult::True;

    RevertingTentativeParsingAction PA(*this);

    TPResult TPR = TryParseTypeofSpecifier();
    bool isFollowedByParen = Tok.is(tok::l_paren);
    bool isFollowedByBrace = Tok.is(tok::l_brace);

    if (TPR == TPResult::Error)
      return TPResult::Error;

    if (isFollowedByParen)
      return TPResult::Ambiguous;

    if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
      return BracedCastResult;

    return TPResult::True;
  }

#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
#include "clang/Basic/TransformTypeTraits.def"
    return TPResult::True;

  // C11 _Alignas
  case tok::kw__Alignas:
    return TPResult::True;
  // C11 _Atomic
  case tok::kw__Atomic:
    return TPResult::True;

  case tok::kw__BitInt:
  case tok::kw__ExtInt: {
    if (NextToken().isNot(tok::l_paren))
      return TPResult::Error;
    RevertingTentativeParsingAction PA(*this);
    ConsumeToken();
    ConsumeParen();

    if (!SkipUntil(tok::r_paren, StopAtSemi))
      return TPResult::Error;

    if (Tok.is(tok::l_paren))
      return TPResult::Ambiguous;

    if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))
      return BracedCastResult;

    return TPResult::True;
  }
  default:
    return TPResult::False;
  }
}

bool Parser::isCXXDeclarationSpecifierAType() {
  switch (Tok.getKind()) {
    // typename-specifier
  case tok::annot_decltype:
  case tok::annot_pack_indexing_type:
  case tok::annot_template_id:
  case tok::annot_typename:
  case tok::kw_typeof:
#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
#include "clang/Basic/TransformTypeTraits.def"
    return true;

    // elaborated-type-specifier
  case tok::kw_class:
  case tok::kw_struct:
  case tok::kw_union:
  case tok::kw___interface:
  case tok::kw_enum:
    return true;

    // simple-type-specifier
  case tok::kw_char:
  case tok::kw_wchar_t:
  case tok::kw_char8_t:
  case tok::kw_char16_t:
  case tok::kw_char32_t:
  case tok::kw_bool:
  case tok::kw_short:
  case tok::kw_int:
  case tok::kw__ExtInt:
  case tok::kw__BitInt:
  case tok::kw_long:
  case tok::kw___int64:
  case tok::kw___int128:
  case tok::kw_signed:
  case tok::kw_unsigned:
  case tok::kw_half:
  case tok::kw_float:
  case tok::kw_double:
  case tok::kw___bf16:
  case tok::kw__Float16:
  case tok::kw___float128:
  case tok::kw___ibm128:
  case tok::kw_void:
  case tok::kw___unknown_anytype:
  case tok::kw___auto_type:
  case tok::kw__Accum:
  case tok::kw__Fract:
  case tok::kw__Sat:
#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
#include "clang/Basic/OpenCLImageTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
#include "clang/Basic/HLSLIntangibleTypes.def"
    return true;

  case tok::kw_auto:
    return getLangOpts().CPlusPlus11;

  case tok::kw__Atomic:
    // "_Atomic foo"
    return NextToken().is(tok::l_paren);

  default:
    return false;
  }
}

Parser::TPResult Parser::TryParseTypeofSpecifier() {
  assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
  ConsumeToken();

  assert(Tok.is(tok::l_paren) && "Expected '('");
  // Parse through the parens after 'typeof'.
  ConsumeParen();
  if (!SkipUntil(tok::r_paren, StopAtSemi))
    return TPResult::Error;

  return TPResult::Ambiguous;
}

Parser::TPResult Parser::TryParseProtocolQualifiers() {
  assert(Tok.is(tok::less) && "Expected '<' for qualifier list");
  ConsumeToken();
  do {
    if (Tok.isNot(tok::identifier))
      return TPResult::Error;
    ConsumeToken();

    if (Tok.is(tok::comma)) {
      ConsumeToken();
      continue;
    }

    if (Tok.is(tok::greater)) {
      ConsumeToken();
      return TPResult::Ambiguous;
    }
  } while (false);

  return TPResult::Error;
}

bool Parser::isCXXFunctionDeclarator(
    bool *IsAmbiguous, ImplicitTypenameContext AllowImplicitTypename) {

  // C++ 8.2p1:
  // The ambiguity arising from the similarity between a function-style cast and
  // a declaration mentioned in 6.8 can also occur in the context of a
  // declaration. In that context, the choice is between a function declaration
  // with a redundant set of parentheses around a parameter name and an object
  // declaration with a function-style cast as the initializer. Just as for the
  // ambiguities mentioned in 6.8, the resolution is to consider any construct
  // that could possibly be a declaration a declaration.

  RevertingTentativeParsingAction PA(*this);

  ConsumeParen();
  bool InvalidAsDeclaration = false;
  TPResult TPR = TryParseParameterDeclarationClause(
      &InvalidAsDeclaration, /*VersusTemplateArgument=*/false,
      AllowImplicitTypename);
  if (TPR == TPResult::Ambiguous) {
    if (Tok.isNot(tok::r_paren))
      TPR = TPResult::False;
    else {
      const Token &Next = NextToken();
      if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
                       tok::kw_throw, tok::kw_noexcept, tok::l_square,
                       tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
          isCXX11VirtSpecifier(Next))
        // The next token cannot appear after a constructor-style initializer,
        // and can appear next in a function definition. This must be a function
        // declarator.
        TPR = TPResult::True;
      else if (InvalidAsDeclaration)
        // Use the absence of 'typename' as a tie-breaker.
        TPR = TPResult::False;
    }
  }

  if (IsAmbiguous && TPR == TPResult::Ambiguous)
    *IsAmbiguous = true;

  // In case of an error, let the declaration parsing code handle it.
  return TPR != TPResult::False;
}

Parser::TPResult Parser::TryParseParameterDeclarationClause(
    bool *InvalidAsDeclaration, bool VersusTemplateArgument,
    ImplicitTypenameContext AllowImplicitTypename) {

  if (Tok.is(tok::r_paren))
    return TPResult::Ambiguous;

  //   parameter-declaration-list[opt] '...'[opt]
  //   parameter-declaration-list ',' '...'
  //
  // parameter-declaration-list:
  //   parameter-declaration
  //   parameter-declaration-list ',' parameter-declaration
  //
  while (true) {
    // '...'[opt]
    if (Tok.is(tok::ellipsis)) {
      ConsumeToken();
      if (Tok.is(tok::r_paren))
        return TPResult::True; // '...)' is a sign of a function declarator.
      else
        return TPResult::False;
    }

    // An attribute-specifier-seq here is a sign of a function declarator.
    if (isCXX11AttributeSpecifier(/*Disambiguate*/ false,
                                  /*OuterMightBeMessageSend*/ true) !=
        CXX11AttributeKind::NotAttributeSpecifier)
      return TPResult::True;

    ParsedAttributes attrs(AttrFactory);
    MaybeParseMicrosoftAttributes(attrs);

    // decl-specifier-seq
    // A parameter-declaration's initializer must be preceded by an '=', so
    // decl-specifier-seq '{' is not a parameter in C++11.
    TPResult TPR = isCXXDeclarationSpecifier(
        AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
    // A declaration-specifier (not followed by '(' or '{') means this can't be
    // an expression, but it could still be a template argument.
    if (TPR != TPResult::Ambiguous &&
        !(VersusTemplateArgument && TPR == TPResult::True))
      return TPR;

    bool SeenType = false;
    bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
    do {
      SeenType |= isCXXDeclarationSpecifierAType();
      if (TryConsumeDeclarationSpecifier() == TPResult::Error)
        return TPResult::Error;

      // If we see a parameter name, this can't be a template argument.
      if (SeenType && Tok.is(tok::identifier))
        return TPResult::True;

      TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
                                      InvalidAsDeclaration);
      if (TPR == TPResult::Error)
        return TPR;

      // Two declaration-specifiers means this can't be an expression.
      if (TPR == TPResult::True && !VersusTemplateArgument)
        return TPR;
    } while (TPR != TPResult::False);

    // declarator
    // abstract-declarator[opt]
    TPR = TryParseDeclarator(
        /*mayBeAbstract=*/true,
        /*mayHaveIdentifier=*/true,
        /*mayHaveDirectInit=*/false,
        /*mayHaveTrailingReturnType=*/DeclarationSpecifierIsAuto);
    if (TPR != TPResult::Ambiguous)
      return TPR;

    // [GNU] attributes[opt]
    if (Tok.is(tok::kw___attribute))
      return TPResult::True;

    // If we're disambiguating a template argument in a default argument in
    // a class definition versus a parameter declaration, an '=' here
    // disambiguates the parse one way or the other.
    // If this is a parameter, it must have a default argument because
    //   (a) the previous parameter did, and
    //   (b) this must be the first declaration of the function, so we can't
    //       inherit any default arguments from elsewhere.
    // FIXME: If we reach a ')' without consuming any '>'s, then this must
    // also be a function parameter (that's missing its default argument).
    if (VersusTemplateArgument)
      return Tok.is(tok::equal) ? TPResult::True : TPResult::False;

    if (Tok.is(tok::equal)) {
      // '=' assignment-expression
      // Parse through assignment-expression.
      if (!SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch))
        return TPResult::Error;
    }

    if (Tok.is(tok::ellipsis)) {
      ConsumeToken();
      if (Tok.is(tok::r_paren))
        return TPResult::True; // '...)' is a sign of a function declarator.
      else
        return TPResult::False;
    }

    if (!TryConsumeToken(tok::comma))
      break;
  }

  return TPResult::Ambiguous;
}

Parser::TPResult
Parser::TryParseFunctionDeclarator(bool MayHaveTrailingReturnType) {
  // The '(' is already parsed.

  TPResult TPR = TryParseParameterDeclarationClause();
  if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
    TPR = TPResult::False;

  if (TPR == TPResult::False || TPR == TPResult::Error)
    return TPR;

  // Parse through the parens.
  if (!SkipUntil(tok::r_paren, StopAtSemi))
    return TPResult::Error;

  // cv-qualifier-seq
  while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
                     tok::kw_restrict))
    ConsumeToken();

  // ref-qualifier[opt]
  if (Tok.isOneOf(tok::amp, tok::ampamp))
    ConsumeToken();

  // exception-specification
  if (Tok.is(tok::kw_throw)) {
    ConsumeToken();
    if (Tok.isNot(tok::l_paren))
      return TPResult::Error;

    // Parse through the parens after 'throw'.
    ConsumeParen();
    if (!SkipUntil(tok::r_paren, StopAtSemi))
      return TPResult::Error;
  }
  if (Tok.is(tok::kw_noexcept)) {
    ConsumeToken();
    // Possibly an expression as well.
    if (Tok.is(tok::l_paren)) {
      // Find the matching rparen.
      ConsumeParen();
      if (!SkipUntil(tok::r_paren, StopAtSemi))
        return TPResult::Error;
    }
  }

  // attribute-specifier-seq
  if (!TrySkipAttributes())
    return TPResult::Ambiguous;

  // trailing-return-type
  if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
    if (TPR == TPResult::True)
      return TPR;
    ConsumeToken();
    if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
      return TPResult::False;
    }
    if (isCXXTypeId(TentativeCXXTypeIdContext::InTrailingReturnType))
      return TPResult::True;
  }

  return TPResult::Ambiguous;
}

bool Parser::NameAfterArrowIsNonType() {
  assert(Tok.is(tok::identifier));
  Token Next = NextToken();
  if (Next.is(tok::coloncolon))
    return false;
  IdentifierInfo *Name = Tok.getIdentifierInfo();
  SourceLocation NameLoc = Tok.getLocation();
  CXXScopeSpec SS;
  TentativeParseCCC CCC(Next);
  Sema::NameClassification Classification =
      Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next, &CCC);
  switch (Classification.getKind()) {
  case NameClassificationKind::OverloadSet:
  case NameClassificationKind::NonType:
  case NameClassificationKind::VarTemplate:
  case NameClassificationKind::FunctionTemplate:
    return true;
  default:
    break;
  }
  return false;
}

Parser::TPResult Parser::TryParseBracketDeclarator() {
  ConsumeBracket();

  // A constant-expression cannot begin with a '{', but the
  // expr-or-braced-init-list of a postfix-expression can.
  if (Tok.is(tok::l_brace))
    return TPResult::False;

  if (!SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch))
    return TPResult::Error;

  // If we hit a comma before the ']', this is not a constant-expression,
  // but might still be the expr-or-braced-init-list of a postfix-expression.
  if (Tok.isNot(tok::r_square))
    return TPResult::False;

  ConsumeBracket();
  return TPResult::Ambiguous;
}

Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip) {
  if (!TokensToSkip) {
    if (Tok.isNot(tok::less))
      return TPResult::False;
    if (NextToken().is(tok::greater))
      return TPResult::True;
  }

  RevertingTentativeParsingAction PA(*this);

  while (TokensToSkip) {
    ConsumeAnyToken();
    --TokensToSkip;
  }

  if (!TryConsumeToken(tok::less))
    return TPResult::False;

  // We can't do much to tell an expression apart from a template-argument,
  // but one good distinguishing factor is that a "decl-specifier" not
  // followed by '(' or '{' can't appear in an expression.
  bool InvalidAsTemplateArgumentList = false;
  if (isCXXDeclarationSpecifier(ImplicitTypenameContext::No, TPResult::False,
                                &InvalidAsTemplateArgumentList) ==
      TPResult::True)
    return TPResult::True;
  if (InvalidAsTemplateArgumentList)
    return TPResult::False;

  // FIXME: In many contexts, X<thing1, Type> can only be a
  // template-argument-list. But that's not true in general:
  //
  // using b = int;
  // void f() {
  //   int a = A<B, b, c = C>D; // OK, declares b, not a template-id.
  //
  // X<Y<0, int> // ', int>' might be end of X's template argument list
  //
  // We might be able to disambiguate a few more cases if we're careful.

  // A template-argument-list must be terminated by a '>'.
  if (SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
                StopAtSemi | StopBeforeMatch))
    return TPResult::Ambiguous;
  return TPResult::False;
}

Parser::TPResult Parser::isExplicitBool() {
  assert(Tok.is(tok::l_paren) && "expected to be looking at a '(' token");

  RevertingTentativeParsingAction PA(*this);
  ConsumeParen();

  // We can only have 'explicit' on a constructor, conversion function, or
  // deduction guide. The declarator of a deduction guide cannot be
  // parenthesized, so we know this isn't a deduction guide. So the only
  // thing we need to check for is some number of parens followed by either
  // the current class name or 'operator'.
  while (Tok.is(tok::l_paren))
    ConsumeParen();

  if (TryAnnotateOptionalCXXScopeToken())
    return TPResult::Error;

  // Class-scope constructor and conversion function names can't really be
  // qualified, but we get better diagnostics if we assume they can be.
  CXXScopeSpec SS;
  if (Tok.is(tok::annot_cxxscope)) {
    Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
                                                 Tok.getAnnotationRange(),
                                                 SS);
    ConsumeAnnotationToken();
  }

  // 'explicit(operator' might be explicit(bool) or the declaration of a
  // conversion function, but it's probably a conversion function.
  if (Tok.is(tok::kw_operator))
    return TPResult::Ambiguous;

  // If this can't be a constructor name, it can only be explicit(bool).
  if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
    return TPResult::True;
  if (!Actions.isCurrentClassName(Tok.is(tok::identifier)
                                      ? *Tok.getIdentifierInfo()
                                      : *takeTemplateIdAnnotation(Tok)->Name,
                                  getCurScope(), &SS))
    return TPResult::True;
  // Formally, we must have a right-paren after the constructor name to match
  // the grammar for a constructor. But clang permits a parenthesized
  // constructor declarator, so also allow a constructor declarator to follow
  // with no ')' token after the constructor name.
  if (!NextToken().is(tok::r_paren) &&
      !isConstructorDeclarator(/*Unqualified=*/SS.isEmpty(),
                               /*DeductionGuide=*/false))
    return TPResult::True;

  // Might be explicit(bool) or a parenthesized constructor name.
  return TPResult::Ambiguous;
}
