49bool Parser::isCXXDeclarationStatement(
50 bool DisambiguatingWithExpression ) {
57 case tok::kw_namespace:
62 case tok::kw_static_assert:
63 case tok::kw__Static_assert:
65 case tok::identifier: {
66 if (DisambiguatingWithExpression) {
67 RevertingTentativeParsingAction TPA(*
this);
70 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
75 case tok::identifier: {
77 bool isDeductionGuide =
82 if (isConstructorDeclarator(SS.
isEmpty(),
89 case tok::kw_operator:
91 case tok::annot_cxxscope:
103 return isCXXSimpleDeclaration(
false);
127bool Parser::isCXXSimpleDeclaration(
bool AllowForRangeDecl) {
152 bool InvalidAsDeclaration =
false;
153 TPResult TPR = isCXXDeclarationSpecifier(
155 if (TPR != TPResult::Ambiguous)
156 return TPR != TPResult::False;
164 if (InvalidAsDeclaration)
175 RevertingTentativeParsingAction PA(*
this);
176 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
180 if (TPR == TPResult::Error)
184 if (TPR == TPResult::Ambiguous)
185 TPR = TPResult::True;
187 assert(TPR == TPResult::True || TPR == TPResult::False);
188 return TPR == TPResult::True;
193Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
195 case tok::kw__Atomic:
202 case tok::kw___attribute:
203#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
204#include "clang/Basic/TransformTypeTraits.def"
207 if (Tok.
isNot(tok::l_paren))
208 return TPResult::Error;
211 return TPResult::Error;
218 case tok::kw___interface:
230 if (!TrySkipAttributes())
231 return TPResult::Error;
234 return TPResult::Error;
235 if (Tok.
is(tok::annot_cxxscope))
236 ConsumeAnnotationToken();
237 if (Tok.
is(tok::identifier))
239 else if (Tok.
is(tok::annot_template_id))
240 ConsumeAnnotationToken();
242 return TPResult::Error;
245 case tok::annot_cxxscope:
246 ConsumeAnnotationToken();
252 return TryParseProtocolQualifiers();
256 return TPResult::Ambiguous;
267Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
268 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
269 return TPResult::Error;
274 if (Tok.
isNot(tok::l_paren)) {
276 if (TPR == TPResult::Ambiguous)
277 return TPResult::True;
278 if (TPR == TPResult::True || TPR == TPResult::Error)
280 assert(TPR == TPResult::False);
283 TPResult TPR = TryParseInitDeclaratorList();
284 if (TPR != TPResult::Ambiguous)
287 if (Tok.
isNot(tok::semi) && (!AllowForRangeDecl || Tok.
isNot(tok::colon)))
288 return TPResult::False;
290 return TPResult::Ambiguous;
320Parser::TPResult Parser::TryParseInitDeclaratorList() {
323 TPResult TPR = TryParseDeclarator(
false);
324 if (TPR != TPResult::Ambiguous)
328 if (Tok.
isOneOf(tok::kw_asm, tok::kw___attribute))
329 return TPResult::True;
332 if (Tok.
is(tok::l_paren)) {
336 return TPResult::Error;
337 }
else if (Tok.
is(tok::l_brace)) {
340 return TPResult::True;
341 }
else if (Tok.
is(tok::equal) || isTokIdentifier_in()) {
358 return TPResult::True;
365 return TPResult::Ambiguous;
393 RevertingTentativeParsingAction PA(
P);
397 unsigned QuestionColonDepth = 0;
399 P.
SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
401 if (
P.Tok.
is(tok::question))
402 ++QuestionColonDepth;
403 else if (
P.Tok.
is(tok::colon)) {
404 if (QuestionColonDepth)
405 --QuestionColonDepth;
420 if (
P.Tok.
isNot(tok::r_paren))
422 if (
P.Tok.
isNot(tok::semi))
441 assert(
resolved() &&
"can't continue after tentative parsing bails out");
443 case TPResult::False:
446 case TPResult::Ambiguous:
448 case TPResult::Error:
456 ConditionOrInitStatement
result()
const {
459 "result called but not yet resolved");
461 return ConditionOrInitStatement::Expression;
463 return ConditionOrInitStatement::ConditionDecl;
465 return ConditionOrInitStatement::InitStmtDecl;
467 return ConditionOrInitStatement::ForRangeDecl;
468 return ConditionOrInitStatement::Error;
472bool Parser::isEnumBase(
bool AllowSemi) {
473 assert(Tok.
is(tok::colon) &&
"should be looking at the ':'");
475 RevertingTentativeParsingAction PA(*
this);
480 bool InvalidAsDeclSpec =
false;
487 if (R == TPResult::Ambiguous) {
490 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
495 if (Tok.
is(tok::l_brace) || (AllowSemi && Tok.
is(tok::semi)))
503 return R != TPResult::False;
523Parser::ConditionOrInitStatement
524Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement,
525 bool CanBeForRangeDecl) {
526 ConditionDeclarationOrInitStatementState State(*
this, CanBeInitStatement,
529 if (CanBeInitStatement && Tok.
is(tok::kw_using))
530 return ConditionOrInitStatement::InitStmtDecl;
532 return State.result();
535 RevertingTentativeParsingAction PA(*
this);
538 if (State.update(TryConsumeDeclarationSpecifier()))
539 return State.result();
540 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
544 if (State.update(TryParseDeclarator(
false)))
545 return State.result();
550 if (Tok.
isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
552 State.markNotExpression();
553 return State.result();
557 if (State.CanBeForRangeDecl && Tok.
is(tok::colon))
558 return ConditionOrInitStatement::ForRangeDecl;
562 if (State.markNotCondition())
563 return State.result();
566 if (State.markNotForRangeDecl())
567 return State.result();
571 if (Tok.
is(tok::l_paren)) {
581 if (State.CanBeCondition && Tok.
is(tok::r_paren))
582 return ConditionOrInitStatement::ConditionDecl;
583 else if (State.CanBeInitStatement && Tok.
is(tok::semi))
584 return ConditionOrInitStatement::InitStmtDecl;
586 return ConditionOrInitStatement::Expression;
606bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context,
bool &isAmbiguous) {
618 if (TPR != TPResult::Ambiguous)
619 return TPR != TPResult::False;
628 RevertingTentativeParsingAction PA(*
this);
631 TryConsumeDeclarationSpecifier();
632 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
635 TPR = TryParseDeclarator(
true,
false);
638 if (TPR == TPResult::Error)
639 TPR = TPResult::True;
641 if (TPR == TPResult::Ambiguous) {
644 if (Context == TypeIdInParens && Tok.
is(tok::r_paren)) {
645 TPR = TPResult::True;
652 }
else if (Context == TypeIdAsTemplateArgument &&
653 (Tok.
isOneOf(tok::greater, tok::comma) ||
655 (Tok.
isOneOf(tok::greatergreater,
656 tok::greatergreatergreater) ||
657 (Tok.
is(tok::ellipsis) &&
659 tok::greatergreatergreater,
661 TPR = TPResult::True;
665 TPR = TPResult::False;
668 assert(TPR == TPResult::True || TPR == TPResult::False);
669 return TPR == TPResult::True;
705Parser::CXX11AttributeKind
706Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
707 bool OuterMightBeMessageSend) {
708 if (Tok.
is(tok::kw_alignas))
709 return CAK_AttributeSpecifier;
712 return CAK_NotAttributeSpecifier;
716 return CAK_AttributeSpecifier;
719 if (GetLookAheadToken(2).is(tok::kw_using))
720 return CAK_AttributeSpecifier;
722 RevertingTentativeParsingAction PA(*
this);
730 bool IsAttribute =
SkipUntil(tok::r_square);
731 IsAttribute &= Tok.
is(tok::r_square);
733 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
749 RevertingTentativeParsingAction LambdaTPA(*
this);
751 LambdaIntroducerTentativeParse Tentative;
752 if (ParseLambdaIntroducer(Intro, &Tentative)) {
756 return CAK_NotAttributeSpecifier;
760 case LambdaIntroducerTentativeParse::MessageSend:
763 return CAK_NotAttributeSpecifier;
765 case LambdaIntroducerTentativeParse::Success:
766 case LambdaIntroducerTentativeParse::Incomplete:
768 if (Tok.
is(tok::r_square))
770 return CAK_AttributeSpecifier;
772 if (OuterMightBeMessageSend)
774 return CAK_NotAttributeSpecifier;
777 return CAK_InvalidAttributeSpecifier;
779 case LambdaIntroducerTentativeParse::Invalid:
790 bool IsAttribute =
true;
791 while (Tok.
isNot(tok::r_square)) {
792 if (Tok.
is(tok::comma)) {
794 return CAK_AttributeSpecifier;
803 if (!TryParseCXX11AttributeIdentifier(Loc)) {
807 if (Tok.
is(tok::coloncolon)) {
809 if (!TryParseCXX11AttributeIdentifier(Loc)) {
816 if (Tok.
is(tok::l_paren)) {
832 if (Tok.
is(tok::r_square)) {
834 IsAttribute = Tok.
is(tok::r_square);
842 return CAK_AttributeSpecifier;
845 return CAK_NotAttributeSpecifier;
848bool Parser::TrySkipAttributes() {
849 while (Tok.
isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
851 if (Tok.
is(tok::l_square)) {
853 if (Tok.
isNot(tok::l_square))
863 if (Tok.
isNot(tok::l_paren))
874Parser::TPResult Parser::TryParsePtrOperatorSeq() {
877 return TPResult::Error;
879 if (Tok.
isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
880 (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::star))) {
885 if (!TrySkipAttributes())
886 return TPResult::Error;
888 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
889 tok::kw__Nonnull, tok::kw__Nullable,
890 tok::kw__Nullable_result, tok::kw__Null_unspecified,
894 return TPResult::True;
917Parser::TPResult Parser::TryParseOperatorId() {
918 assert(Tok.
is(tok::kw_operator));
923 case tok::kw_new:
case tok::kw_delete:
925 if (Tok.
is(tok::l_square) &&
NextToken().is(tok::r_square)) {
929 return TPResult::True;
931#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
933#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
934#include "clang/Basic/OperatorKinds.def"
936 return TPResult::True;
942 return TPResult::True;
950 return TPResult::True;
960 bool FoundUDSuffix =
false;
963 ConsumeStringToken();
964 }
while (isTokenStringLiteral());
966 if (!FoundUDSuffix) {
967 if (Tok.
is(tok::identifier))
970 return TPResult::Error;
972 return TPResult::True;
976 bool AnyDeclSpecifiers =
false;
979 if (TPR == TPResult::Error)
981 if (TPR == TPResult::False) {
982 if (!AnyDeclSpecifiers)
983 return TPResult::Error;
986 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
987 return TPResult::Error;
988 AnyDeclSpecifiers =
true;
990 return TryParsePtrOperatorSeq();
1046Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
1047 bool mayHaveIdentifier,
1048 bool mayHaveDirectInit) {
1052 if (TryParsePtrOperatorSeq() == TPResult::Error)
1053 return TPResult::Error;
1057 if (Tok.
is(tok::ellipsis))
1060 if ((Tok.
isOneOf(tok::identifier, tok::kw_operator) ||
1061 (Tok.
is(tok::annot_cxxscope) && (
NextToken().is(tok::identifier) ||
1063 mayHaveIdentifier) {
1065 if (Tok.
is(tok::annot_cxxscope)) {
1070 return TPResult::Error;
1071 ConsumeAnnotationToken();
1072 }
else if (Tok.
is(tok::identifier)) {
1075 if (Tok.
is(tok::kw_operator)) {
1076 if (TryParseOperatorId() == TPResult::Error)
1077 return TPResult::Error;
1080 }
else if (Tok.
is(tok::l_paren)) {
1082 if (mayBeAbstract &&
1083 (Tok.
is(tok::r_paren) ||
1085 (Tok.
is(tok::ellipsis) &&
NextToken().is(tok::r_paren)) ||
1086 isDeclarationSpecifier(
1090 TPResult TPR = TryParseFunctionDeclarator();
1091 if (TPR != TPResult::Ambiguous)
1097 if (Tok.
isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
1098 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
1099 tok::kw___regcall, tok::kw___vectorcall))
1100 return TPResult::True;
1101 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
1102 if (TPR != TPResult::Ambiguous)
1104 if (Tok.
isNot(tok::r_paren))
1105 return TPResult::False;
1108 }
else if (!mayBeAbstract) {
1109 return TPResult::False;
1112 if (mayHaveDirectInit)
1113 return TPResult::Ambiguous;
1116 TPResult TPR(TPResult::Ambiguous);
1118 if (Tok.
is(tok::l_paren)) {
1123 if (!mayBeAbstract && !isCXXFunctionDeclarator())
1129 TPR = TryParseFunctionDeclarator();
1130 }
else if (Tok.
is(tok::l_square)) {
1133 TPR = TryParseBracketDeclarator();
1134 }
else if (Tok.
is(tok::kw_requires)) {
1137 TPR = TPResult::True;
1142 if (TPR != TPResult::Ambiguous)
1146 return TPResult::Ambiguous;
1150 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
1156 TentativeParseCCC(
const Token &Next) {
1157 WantRemainingKeywords =
false;
1158 WantTypeSpecifiers =
1159 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
1160 tok::identifier, tok::comma);
1163 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1167 llvm::all_of(Candidate,
1168 [](
NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
1174 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
1175 return std::make_unique<TentativeParseCCC>(*
this);
1293 Parser::TPResult BracedCastResult,
1294 bool *InvalidAsDeclSpec) {
1300 (GetLookAheadToken(Lookahead + 1)
1301 .
isOneOf(tok::kw_auto, tok::kw_decltype,
1311 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
1322 GetLookAheadToken(Lookahead + 1).
isOneOf(tok::amp, tok::ampamp)));
1325 case tok::identifier: {
1328 if (TryAltiVecVectorToken())
1329 return TPResult::True;
1334 return TPResult::True;
1336 if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
1341 TentativeParseCCC CCC(Next);
1342 switch (TryAnnotateName(&CCC)) {
1344 return TPResult::Error;
1345 case ANK_TentativeDecl:
1346 return TPResult::False;
1347 case ANK_TemplateName:
1354 return TPResult::Error;
1355 if (Tok.
isNot(tok::identifier))
1361 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1362 case ANK_Unresolved:
1363 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1367 assert(Tok.
isNot(tok::identifier) &&
1368 "TryAnnotateName succeeded without producing an annotation");
1375 return TPResult::Error;
1379 if (Tok.
is(tok::identifier))
1380 return TPResult::False;
1384 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1388 case tok::kw_typename:
1392 return TPResult::Error;
1394 BracedCastResult, InvalidAsDeclSpec);
1396 case tok::coloncolon: {
1398 if (Next.isOneOf(tok::kw_new,
1400 return TPResult::False;
1403 case tok::kw___super:
1404 case tok::kw_decltype:
1408 return TPResult::Error;
1409 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1419 case tok::kw_friend:
1420 case tok::kw_typedef:
1421 case tok::kw_constexpr:
1422 case tok::kw_consteval:
1423 case tok::kw_constinit:
1425 case tok::kw_register:
1426 case tok::kw_static:
1427 case tok::kw_extern:
1428 case tok::kw_mutable:
1430 case tok::kw___thread:
1431 case tok::kw_thread_local:
1432 case tok::kw__Thread_local:
1434 case tok::kw_inline:
1435 case tok::kw_virtual:
1436 case tok::kw_explicit:
1439 case tok::kw___module_private__:
1442 case tok::kw___unknown_anytype:
1455 case tok::kw_struct:
1457 case tok::kw___interface:
1462 case tok::kw_volatile:
1463 return TPResult::True;
1466 case tok::kw_private:
1468 return TPResult::False;
1470 case tok::kw___private:
1471 case tok::kw___local:
1472 case tok::kw___global:
1473 case tok::kw___constant:
1474 case tok::kw___generic:
1476 case tok::kw___read_only:
1477 case tok::kw___write_only:
1478 case tok::kw___read_write:
1483 case tok::kw_groupshared:
1486 case tok::kw_restrict:
1487 case tok::kw__Complex:
1488 case tok::kw___attribute:
1489 case tok::kw___auto_type:
1490 return TPResult::True;
1493 case tok::kw___declspec:
1494 case tok::kw___cdecl:
1495 case tok::kw___stdcall:
1496 case tok::kw___fastcall:
1497 case tok::kw___thiscall:
1498 case tok::kw___regcall:
1499 case tok::kw___vectorcall:
1501 case tok::kw___sptr:
1502 case tok::kw___uptr:
1503 case tok::kw___ptr64:
1504 case tok::kw___ptr32:
1505 case tok::kw___forceinline:
1506 case tok::kw___unaligned:
1507 case tok::kw__Nonnull:
1508 case tok::kw__Nullable:
1509 case tok::kw__Nullable_result:
1510 case tok::kw__Null_unspecified:
1511 case tok::kw___kindof:
1512 return TPResult::True;
1515 case tok::kw___funcref:
1516 return TPResult::True;
1519 case tok::kw___pascal:
1520 return TPResult::True;
1523 case tok::kw___vector:
1524 return TPResult::True;
1526 case tok::annot_template_id: {
1532 InvalidAsDeclSpec) {
1537 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1538 return TPResult::Ambiguous;
1541 return TPResult::Error;
1542 if (IsPlaceholderSpecifier(TemplateId, 0))
1543 return TPResult::True;
1545 return TPResult::False;
1547 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1548 assert(Tok.
is(tok::annot_typename));
1552 case tok::annot_cxxscope:
1555 return TPResult::Error;
1556 if (!Tok.
is(tok::annot_typename)) {
1557 if (Tok.
is(tok::annot_cxxscope) &&
1558 NextToken().is(tok::annot_template_id)) {
1562 if (InvalidAsDeclSpec) {
1563 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1564 return TPResult::Ambiguous;
1566 return TPResult::Error;
1568 if (IsPlaceholderSpecifier(TemplateId, 1))
1569 return TPResult::True;
1573 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::identifier)) {
1579 RevertingTentativeParsingAction PA(*
this);
1580 ConsumeAnnotationToken();
1582 bool isIdentifier = Tok.
is(tok::identifier);
1583 TPResult TPR = TPResult::False;
1585 TPR = isCXXDeclarationSpecifier(
1586 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1589 TPR == TPResult::True || TPR == TPResult::Error)
1590 return TPResult::Error;
1592 if (InvalidAsDeclSpec) {
1595 *InvalidAsDeclSpec =
true;
1596 return TPResult::Ambiguous;
1602 if (((Tok.
is(tok::amp) || Tok.
is(tok::star)) &&
1605 (Tok.
is(tok::ampamp) &&
NextToken().is(tok::greater)))
1606 return TPResult::True;
1612 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1614 return TPResult::Error;
1615 case ANK_TentativeDecl:
1616 return TPResult::False;
1617 case ANK_TemplateName:
1622 return TPResult::Error;
1623 if (Tok.
isNot(tok::identifier))
1633 case ANK_Unresolved:
1634 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1640 assert(Tok.
isNot(tok::annot_cxxscope) ||
1642 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1643 BracedCastResult, InvalidAsDeclSpec);
1646 return TPResult::False;
1669 case tok::annot_typename:
1674 RevertingTentativeParsingAction PA(*
this);
1677 TPResult TPR = TryParseProtocolQualifiers();
1678 bool isFollowedByParen = Tok.
is(tok::l_paren);
1679 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1681 if (TPR == TPResult::Error)
1682 return TPResult::Error;
1684 if (isFollowedByParen)
1685 return TPResult::Ambiguous;
1688 return BracedCastResult;
1690 return TPResult::True;
1695 case tok::kw_wchar_t:
1696 case tok::kw_char8_t:
1697 case tok::kw_char16_t:
1698 case tok::kw_char32_t:
1703 case tok::kw___int64:
1704 case tok::kw___int128:
1705 case tok::kw_signed:
1706 case tok::kw_unsigned:
1709 case tok::kw_double:
1710 case tok::kw___bf16:
1711 case tok::kw__Float16:
1712 case tok::kw___float128:
1713 case tok::kw___ibm128:
1715 case tok::annot_decltype:
1716#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1717#include "clang/Basic/OpenCLImageTypes.def"
1719 return TPResult::Ambiguous;
1728 return BracedCastResult;
1730 if (isStartOfObjCClassMessageMissingOpenBracket())
1731 return TPResult::False;
1733 return TPResult::True;
1736 case tok::kw_typeof: {
1738 return TPResult::True;
1740 RevertingTentativeParsingAction PA(*
this);
1742 TPResult TPR = TryParseTypeofSpecifier();
1743 bool isFollowedByParen = Tok.
is(tok::l_paren);
1744 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1746 if (TPR == TPResult::Error)
1747 return TPResult::Error;
1749 if (isFollowedByParen)
1750 return TPResult::Ambiguous;
1753 return BracedCastResult;
1755 return TPResult::True;
1758#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1759#include "clang/Basic/TransformTypeTraits.def"
1760 return TPResult::True;
1763 case tok::kw__Atomic:
1764 return TPResult::True;
1766 case tok::kw__BitInt:
1767 case tok::kw__ExtInt: {
1769 return TPResult::Error;
1770 RevertingTentativeParsingAction PA(*
this);
1775 return TPResult::Error;
1777 if (Tok.
is(tok::l_paren))
1778 return TPResult::Ambiguous;
1781 return BracedCastResult;
1783 return TPResult::True;
1786 return TPResult::False;
1790bool Parser::isCXXDeclarationSpecifierAType() {
1793 case tok::annot_decltype:
1794 case tok::annot_template_id:
1795 case tok::annot_typename:
1796 case tok::kw_typeof:
1797#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1798#include "clang/Basic/TransformTypeTraits.def"
1803 case tok::kw_struct:
1805 case tok::kw___interface:
1811 case tok::kw_wchar_t:
1812 case tok::kw_char8_t:
1813 case tok::kw_char16_t:
1814 case tok::kw_char32_t:
1818 case tok::kw__ExtInt:
1819 case tok::kw__BitInt:
1821 case tok::kw___int64:
1822 case tok::kw___int128:
1823 case tok::kw_signed:
1824 case tok::kw_unsigned:
1827 case tok::kw_double:
1828 case tok::kw___bf16:
1829 case tok::kw__Float16:
1830 case tok::kw___float128:
1831 case tok::kw___ibm128:
1833 case tok::kw___unknown_anytype:
1834 case tok::kw___auto_type:
1835#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1836#include "clang/Basic/OpenCLImageTypes.def"
1842 case tok::kw__Atomic:
1855Parser::TPResult Parser::TryParseTypeofSpecifier() {
1856 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1859 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1863 return TPResult::Error;
1865 return TPResult::Ambiguous;
1870Parser::TPResult Parser::TryParseProtocolQualifiers() {
1871 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1874 if (Tok.
isNot(tok::identifier))
1875 return TPResult::Error;
1878 if (Tok.
is(tok::comma)) {
1883 if (Tok.
is(tok::greater)) {
1885 return TPResult::Ambiguous;
1889 return TPResult::Error;
1902bool Parser::isCXXFunctionDeclarator(
1914 RevertingTentativeParsingAction PA(*
this);
1917 bool InvalidAsDeclaration =
false;
1918 TPResult TPR = TryParseParameterDeclarationClause(
1919 &InvalidAsDeclaration,
false,
1920 AllowImplicitTypename);
1921 if (TPR == TPResult::Ambiguous) {
1922 if (Tok.
isNot(tok::r_paren))
1923 TPR = TPResult::False;
1926 if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1927 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1928 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1929 isCXX11VirtSpecifier(Next))
1933 TPR = TPResult::True;
1934 else if (InvalidAsDeclaration)
1936 TPR = TPResult::False;
1940 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1941 *IsAmbiguous =
true;
1944 return TPR != TPResult::False;
1964Parser::TPResult Parser::TryParseParameterDeclarationClause(
1965 bool *InvalidAsDeclaration,
bool VersusTemplateArgument,
1968 if (Tok.
is(tok::r_paren))
1969 return TPResult::Ambiguous;
1980 if (Tok.
is(tok::ellipsis)) {
1982 if (Tok.
is(tok::r_paren))
1983 return TPResult::True;
1985 return TPResult::False;
1989 if (isCXX11AttributeSpecifier(
false,
1991 return TPResult::True;
1994 MaybeParseMicrosoftAttributes(attrs);
1999 TPResult TPR = isCXXDeclarationSpecifier(
2000 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
2003 if (TPR != TPResult::Ambiguous &&
2004 !(VersusTemplateArgument && TPR == TPResult::True))
2007 bool SeenType =
false;
2009 SeenType |= isCXXDeclarationSpecifierAType();
2010 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
2011 return TPResult::Error;
2014 if (SeenType && Tok.
is(tok::identifier))
2015 return TPResult::True;
2017 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
2018 InvalidAsDeclaration);
2019 if (TPR == TPResult::Error)
2023 if (TPR == TPResult::True && !VersusTemplateArgument)
2025 }
while (TPR != TPResult::False);
2029 TPR = TryParseDeclarator(
true);
2030 if (TPR != TPResult::Ambiguous)
2034 if (Tok.
is(tok::kw___attribute))
2035 return TPResult::True;
2046 if (VersusTemplateArgument)
2047 return Tok.
is(tok::equal) ? TPResult::True : TPResult::False;
2049 if (Tok.
is(tok::equal)) {
2053 return TPResult::Error;
2056 if (Tok.
is(tok::ellipsis)) {
2058 if (Tok.
is(tok::r_paren))
2059 return TPResult::True;
2061 return TPResult::False;
2068 return TPResult::Ambiguous;
2083Parser::TPResult Parser::TryParseFunctionDeclarator() {
2086 TPResult TPR = TryParseParameterDeclarationClause();
2087 if (TPR == TPResult::Ambiguous && Tok.
isNot(tok::r_paren))
2088 TPR = TPResult::False;
2090 if (TPR == TPResult::False || TPR == TPResult::Error)
2095 return TPResult::Error;
2098 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
2103 if (Tok.
isOneOf(tok::amp, tok::ampamp))
2107 if (Tok.
is(tok::kw_throw)) {
2109 if (Tok.
isNot(tok::l_paren))
2110 return TPResult::Error;
2115 return TPResult::Error;
2117 if (Tok.
is(tok::kw_noexcept)) {
2120 if (Tok.
is(tok::l_paren)) {
2124 return TPResult::Error;
2128 return TPResult::Ambiguous;
2133Parser::TPResult Parser::TryParseBracketDeclarator() {
2138 if (Tok.
is(tok::l_brace))
2139 return TPResult::False;
2142 return TPResult::Error;
2146 if (Tok.
isNot(tok::r_square))
2147 return TPResult::False;
2150 return TPResult::Ambiguous;
2157Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
2158 if (!TokensToSkip) {
2159 if (Tok.
isNot(tok::less))
2160 return TPResult::False;
2162 return TPResult::True;
2165 RevertingTentativeParsingAction PA(*
this);
2167 while (TokensToSkip) {
2173 return TPResult::False;
2178 bool InvalidAsTemplateArgumentList =
false;
2180 &InvalidAsTemplateArgumentList) ==
2182 return TPResult::True;
2183 if (InvalidAsTemplateArgumentList)
2184 return TPResult::False;
2198 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2200 return TPResult::Ambiguous;
2201 return TPResult::False;
2206Parser::TPResult Parser::isExplicitBool() {
2207 assert(Tok.
is(tok::l_paren) &&
"expected to be looking at a '(' token");
2209 RevertingTentativeParsingAction PA(*
this);
2217 while (Tok.
is(tok::l_paren))
2221 return TPResult::Error;
2226 if (Tok.
is(tok::annot_cxxscope)) {
2230 ConsumeAnnotationToken();
2235 if (Tok.
is(tok::kw_operator))
2236 return TPResult::Ambiguous;
2239 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::annot_template_id))
2240 return TPResult::True;
2243 : *takeTemplateIdAnnotation(Tok)->Name,
2245 return TPResult::True;
2251 !isConstructorDeclarator(SS.
isEmpty(),
2253 return TPResult::True;
2256 return TPResult::Ambiguous;
static constexpr bool isOneOf()
Represents a C++ nested-name-specifier or a global scope specifier.
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
bool isEmpty() const
No scope specifier.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
One of these records is kept for each identifier that is lexed.
This represents a decl that may have a name.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
ParsedAttributes - A collection of parsed attributes.
Parser - This implements a parser for the C family of languages.
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext=false)
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
const LangOptions & getLangOpts() const
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtSemi
Stop skipping at semicolon.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS=nullptr)
isCurrentClassName - Determine whether the identifier II is the name of the class type currently bein...
bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, SourceLocation NameLoc, ParsedTemplateTy *Template=nullptr)
Determine whether a particular identifier might be the name in a C++1z deduction-guide declaration.
void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)
Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure.
Encodes a location in the source.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
SourceRange getAnnotationRange() const
SourceRange of the group of tokens that this annotation token represents.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
Simple class containing the result of Sema::CorrectTypo.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
bool markNotForRangeDecl()
ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement, bool CanBeForRangeDecl)
bool update(TPResult IsDecl)
ConditionOrInitStatement result() const
Represents a complete lambda introducer.
Information about a template-id annotation token.
bool hasInvalidName() const
TemplateNameKind Kind
The kind of template that Template refers to.
unsigned NumArgs
NumArgs - The number of template arguments.