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