49bool Parser::isCXXDeclarationStatement(
50 bool DisambiguatingWithExpression ) {
57 case tok::kw_namespace:
62 case tok::kw_static_assert:
63 case tok::kw__Static_assert:
66 case tok::identifier: {
67 if (DisambiguatingWithExpression) {
68 RevertingTentativeParsingAction TPA(*
this);
71 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
76 case tok::identifier: {
82 if (isConstructorDeclarator(SS.
isEmpty(),
100 case tok::kw_operator:
112 return isCXXSimpleDeclaration(
false);
136bool Parser::isCXXSimpleDeclaration(
bool AllowForRangeDecl) {
161 bool InvalidAsDeclaration =
false;
162 TPResult TPR = isCXXDeclarationSpecifier(
164 if (TPR != TPResult::Ambiguous)
165 return TPR != TPResult::False;
173 if (InvalidAsDeclaration)
184 RevertingTentativeParsingAction PA(*
this);
185 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
189 if (TPR == TPResult::Error)
193 if (TPR == TPResult::Ambiguous)
194 TPR = TPResult::True;
196 assert(TPR == TPResult::True || TPR == TPResult::False);
197 return TPR == TPResult::True;
202Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
204 case tok::kw__Atomic:
211 case tok::kw___attribute:
212#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
213#include "clang/Basic/TransformTypeTraits.def"
216 if (Tok.
isNot(tok::l_paren))
217 return TPResult::Error;
220 return TPResult::Error;
227 case tok::kw___interface:
239 if (!TrySkipAttributes())
240 return TPResult::Error;
243 return TPResult::Error;
244 if (Tok.
is(tok::annot_cxxscope))
245 ConsumeAnnotationToken();
246 if (Tok.
is(tok::identifier))
248 else if (Tok.
is(tok::annot_template_id))
249 ConsumeAnnotationToken();
251 return TPResult::Error;
254 case tok::annot_cxxscope:
255 ConsumeAnnotationToken();
261 return TryParseProtocolQualifiers();
265 return TPResult::Ambiguous;
276Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
277 bool DeclSpecifierIsAuto = Tok.
is(tok::kw_auto);
278 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
279 return TPResult::Error;
284 if (Tok.
isNot(tok::l_paren)) {
286 if (TPR == TPResult::Ambiguous)
287 return TPResult::True;
288 if (TPR == TPResult::True || TPR == TPResult::Error)
290 assert(TPR == TPResult::False);
293 TPResult TPR = TryParseInitDeclaratorList(
294 DeclSpecifierIsAuto);
295 if (TPR != TPResult::Ambiguous)
298 if (Tok.
isNot(tok::semi) && (!AllowForRangeDecl || Tok.
isNot(tok::colon)))
299 return TPResult::False;
301 return TPResult::Ambiguous;
332Parser::TryParseInitDeclaratorList(
bool MayHaveTrailingReturnType) {
335 TPResult TPR = TryParseDeclarator(
339 MayHaveTrailingReturnType);
340 if (TPR != TPResult::Ambiguous)
344 if (Tok.
isOneOf(tok::kw_asm, tok::kw___attribute))
345 return TPResult::True;
348 if (Tok.
is(tok::l_paren)) {
352 return TPResult::Error;
353 }
else if (Tok.
is(tok::l_brace)) {
356 return TPResult::True;
357 }
else if (Tok.
is(tok::equal) || isTokIdentifier_in()) {
374 return TPResult::True;
381 return TPResult::Ambiguous;
409 RevertingTentativeParsingAction PA(
P);
413 unsigned QuestionColonDepth = 0;
415 P.
SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
417 if (
P.Tok.
is(tok::question))
418 ++QuestionColonDepth;
419 else if (
P.Tok.
is(tok::colon)) {
420 if (QuestionColonDepth)
421 --QuestionColonDepth;
436 if (
P.Tok.
isNot(tok::r_paren))
438 if (
P.Tok.
isNot(tok::semi))
457 assert(
resolved() &&
"can't continue after tentative parsing bails out");
459 case TPResult::False:
462 case TPResult::Ambiguous:
464 case TPResult::Error:
472 ConditionOrInitStatement
result()
const {
475 "result called but not yet resolved");
477 return ConditionOrInitStatement::Expression;
479 return ConditionOrInitStatement::ConditionDecl;
481 return ConditionOrInitStatement::InitStmtDecl;
483 return ConditionOrInitStatement::ForRangeDecl;
484 return ConditionOrInitStatement::Error;
488bool Parser::isEnumBase(
bool AllowSemi) {
489 assert(Tok.
is(tok::colon) &&
"should be looking at the ':'");
491 RevertingTentativeParsingAction PA(*
this);
496 bool InvalidAsDeclSpec =
false;
503 if (R == TPResult::Ambiguous) {
506 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
511 if (Tok.
is(tok::l_brace) || (AllowSemi && Tok.
is(tok::semi)))
519 return R != TPResult::False;
539Parser::ConditionOrInitStatement
540Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement,
541 bool CanBeForRangeDecl) {
542 ConditionDeclarationOrInitStatementState State(*
this, CanBeInitStatement,
545 if (CanBeInitStatement && Tok.
is(tok::kw_using))
546 return ConditionOrInitStatement::InitStmtDecl;
548 return State.result();
551 RevertingTentativeParsingAction PA(*
this);
554 bool MayHaveTrailingReturnType = Tok.
is(tok::kw_auto);
555 if (State.update(TryConsumeDeclarationSpecifier()))
556 return State.result();
557 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
561 if (State.update(TryParseDeclarator(
565 MayHaveTrailingReturnType)))
566 return State.result();
571 if (Tok.
isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
573 State.markNotExpression();
574 return State.result();
578 if (State.CanBeForRangeDecl && Tok.
is(tok::colon))
579 return ConditionOrInitStatement::ForRangeDecl;
583 if (State.markNotCondition())
584 return State.result();
587 if (State.markNotForRangeDecl())
588 return State.result();
592 if (Tok.
is(tok::l_paren)) {
602 if (State.CanBeCondition && Tok.
is(tok::r_paren))
603 return ConditionOrInitStatement::ConditionDecl;
604 else if (State.CanBeInitStatement && Tok.
is(tok::semi))
605 return ConditionOrInitStatement::InitStmtDecl;
607 return ConditionOrInitStatement::Expression;
627bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context,
bool &isAmbiguous) {
639 if (TPR != TPResult::Ambiguous)
640 return TPR != TPResult::False;
649 RevertingTentativeParsingAction PA(*
this);
650 bool MayHaveTrailingReturnType = Tok.
is(tok::kw_auto);
653 TryConsumeDeclarationSpecifier();
654 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
657 TPR = TryParseDeclarator(
true ,
false ,
659 MayHaveTrailingReturnType);
662 if (TPR == TPResult::Error)
663 TPR = TPResult::True;
665 if (TPR == TPResult::Ambiguous) {
668 if (Context == TypeIdInParens && Tok.
is(tok::r_paren)) {
669 TPR = TPResult::True;
674 }
else if (Context == TypeIdAsGenericSelectionArgument && Tok.
is(tok::comma)) {
675 TPR = TPResult::True;
681 }
else if (Context == TypeIdAsTemplateArgument &&
682 (Tok.
isOneOf(tok::greater, tok::comma) ||
684 (Tok.
isOneOf(tok::greatergreater,
685 tok::greatergreatergreater) ||
686 (Tok.
is(tok::ellipsis) &&
688 tok::greatergreatergreater,
690 TPR = TPResult::True;
693 }
else if (Context == TypeIdInTrailingReturnType) {
694 TPR = TPResult::True;
697 TPR = TPResult::False;
700 assert(TPR == TPResult::True || TPR == TPResult::False);
701 return TPR == TPResult::True;
737Parser::CXX11AttributeKind
738Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
739 bool OuterMightBeMessageSend) {
740 if (Tok.
is(tok::kw_alignas))
741 return CAK_AttributeSpecifier;
744 return CAK_AttributeSpecifier;
747 return CAK_NotAttributeSpecifier;
751 return CAK_AttributeSpecifier;
754 if (GetLookAheadToken(2).is(tok::kw_using))
755 return CAK_AttributeSpecifier;
757 RevertingTentativeParsingAction PA(*
this);
765 bool IsAttribute =
SkipUntil(tok::r_square);
766 IsAttribute &= Tok.
is(tok::r_square);
768 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
784 RevertingTentativeParsingAction LambdaTPA(*
this);
786 LambdaIntroducerTentativeParse Tentative;
787 if (ParseLambdaIntroducer(Intro, &Tentative)) {
791 return CAK_NotAttributeSpecifier;
795 case LambdaIntroducerTentativeParse::MessageSend:
798 return CAK_NotAttributeSpecifier;
800 case LambdaIntroducerTentativeParse::Success:
801 case LambdaIntroducerTentativeParse::Incomplete:
803 if (Tok.
is(tok::r_square))
805 return CAK_AttributeSpecifier;
807 if (OuterMightBeMessageSend)
809 return CAK_NotAttributeSpecifier;
812 return CAK_InvalidAttributeSpecifier;
814 case LambdaIntroducerTentativeParse::Invalid:
825 bool IsAttribute =
true;
826 while (Tok.
isNot(tok::r_square)) {
827 if (Tok.
is(tok::comma)) {
829 return CAK_AttributeSpecifier;
838 if (!TryParseCXX11AttributeIdentifier(Loc)) {
842 if (Tok.
is(tok::coloncolon)) {
844 if (!TryParseCXX11AttributeIdentifier(Loc)) {
851 if (Tok.
is(tok::l_paren)) {
867 if (Tok.
is(tok::r_square)) {
869 IsAttribute = Tok.
is(tok::r_square);
877 return CAK_AttributeSpecifier;
880 return CAK_NotAttributeSpecifier;
883bool Parser::TrySkipAttributes() {
884 while (Tok.
isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
887 if (Tok.
is(tok::l_square)) {
889 if (Tok.
isNot(tok::l_square))
901 if (Tok.
isNot(tok::l_paren))
912Parser::TPResult Parser::TryParsePtrOperatorSeq() {
915 return TPResult::Error;
917 if (Tok.
isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
918 (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::star))) {
923 if (!TrySkipAttributes())
924 return TPResult::Error;
926 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
927 tok::kw__Nonnull, tok::kw__Nullable,
928 tok::kw__Nullable_result, tok::kw__Null_unspecified,
932 return TPResult::True;
955Parser::TPResult Parser::TryParseOperatorId() {
956 assert(Tok.
is(tok::kw_operator));
961 case tok::kw_new:
case tok::kw_delete:
963 if (Tok.
is(tok::l_square) &&
NextToken().is(tok::r_square)) {
967 return TPResult::True;
969#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
971#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
972#include "clang/Basic/OperatorKinds.def"
974 return TPResult::True;
980 return TPResult::True;
988 return TPResult::True;
998 bool FoundUDSuffix =
false;
1001 ConsumeStringToken();
1002 }
while (isTokenStringLiteral());
1004 if (!FoundUDSuffix) {
1005 if (Tok.
is(tok::identifier))
1008 return TPResult::Error;
1010 return TPResult::True;
1014 bool AnyDeclSpecifiers =
false;
1017 if (TPR == TPResult::Error)
1019 if (TPR == TPResult::False) {
1020 if (!AnyDeclSpecifiers)
1021 return TPResult::Error;
1024 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1025 return TPResult::Error;
1026 AnyDeclSpecifiers =
true;
1028 return TryParsePtrOperatorSeq();
1084Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
1085 bool mayHaveIdentifier,
1086 bool mayHaveDirectInit,
1087 bool mayHaveTrailingReturnType) {
1091 if (TryParsePtrOperatorSeq() == TPResult::Error)
1092 return TPResult::Error;
1096 if (Tok.
is(tok::ellipsis))
1099 if ((Tok.
isOneOf(tok::identifier, tok::kw_operator) ||
1100 (Tok.
is(tok::annot_cxxscope) && (
NextToken().is(tok::identifier) ||
1102 mayHaveIdentifier) {
1104 if (Tok.
is(tok::annot_cxxscope)) {
1109 return TPResult::Error;
1110 ConsumeAnnotationToken();
1111 }
else if (Tok.
is(tok::identifier)) {
1114 if (Tok.
is(tok::kw_operator)) {
1115 if (TryParseOperatorId() == TPResult::Error)
1116 return TPResult::Error;
1119 }
else if (Tok.
is(tok::l_paren)) {
1121 if (mayBeAbstract &&
1122 (Tok.
is(tok::r_paren) ||
1124 (Tok.
is(tok::ellipsis) &&
NextToken().is(tok::r_paren)) ||
1125 isDeclarationSpecifier(
1129 TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
1130 if (TPR != TPResult::Ambiguous)
1136 if (Tok.
isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
1137 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
1138 tok::kw___regcall, tok::kw___vectorcall))
1139 return TPResult::True;
1140 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
1141 if (TPR != TPResult::Ambiguous)
1143 if (Tok.
isNot(tok::r_paren))
1144 return TPResult::False;
1147 }
else if (!mayBeAbstract) {
1148 return TPResult::False;
1151 if (mayHaveDirectInit)
1152 return TPResult::Ambiguous;
1155 TPResult TPR(TPResult::Ambiguous);
1157 if (Tok.
is(tok::l_paren)) {
1162 if (!mayBeAbstract && !isCXXFunctionDeclarator())
1168 TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
1169 }
else if (Tok.
is(tok::l_square)) {
1172 TPR = TryParseBracketDeclarator();
1173 }
else if (Tok.
is(tok::kw_requires)) {
1176 TPR = TPResult::True;
1181 if (TPR != TPResult::Ambiguous)
1185 return TPResult::Ambiguous;
1189 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
1195 TentativeParseCCC(
const Token &Next) {
1196 WantRemainingKeywords =
false;
1197 WantTypeSpecifiers =
1198 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
1199 tok::identifier, tok::comma);
1202 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1206 llvm::all_of(Candidate,
1207 [](
NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
1213 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
1214 return std::make_unique<TentativeParseCCC>(*
this);
1332 Parser::TPResult BracedCastResult,
1333 bool *InvalidAsDeclSpec) {
1339 (GetLookAheadToken(Lookahead + 1)
1340 .
isOneOf(tok::kw_auto, tok::kw_decltype,
1350 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
1361 GetLookAheadToken(Lookahead + 1).
isOneOf(tok::amp, tok::ampamp)));
1364 case tok::identifier: {
1367 if (TryAltiVecVectorToken())
1368 return TPResult::True;
1373 return TPResult::True;
1375 if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
1380 TentativeParseCCC CCC(Next);
1381 switch (TryAnnotateName(&CCC)) {
1383 return TPResult::Error;
1384 case ANK_TentativeDecl:
1385 return TPResult::False;
1386 case ANK_TemplateName:
1393 return TPResult::Error;
1394 if (Tok.
isNot(tok::identifier))
1400 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1401 case ANK_Unresolved:
1402 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1406 assert(Tok.
isNot(tok::identifier) &&
1407 "TryAnnotateName succeeded without producing an annotation");
1414 return TPResult::Error;
1418 if (Tok.
is(tok::identifier))
1419 return TPResult::False;
1423 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1427 case tok::kw_typename:
1431 return TPResult::Error;
1433 BracedCastResult, InvalidAsDeclSpec);
1435 case tok::kw_auto: {
1437 return TPResult::True;
1439 return TPResult::False;
1441 return TPResult::Ambiguous;
1442 return TPResult::True;
1445 case tok::coloncolon: {
1447 if (Next.isOneOf(tok::kw_new,
1449 return TPResult::False;
1452 case tok::kw___super:
1453 case tok::kw_decltype:
1457 return TPResult::Error;
1458 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1468 case tok::kw_friend:
1469 case tok::kw_typedef:
1470 case tok::kw_constexpr:
1471 case tok::kw_consteval:
1472 case tok::kw_constinit:
1474 case tok::kw_register:
1475 case tok::kw_static:
1476 case tok::kw_extern:
1477 case tok::kw_mutable:
1478 case tok::kw___thread:
1479 case tok::kw_thread_local:
1480 case tok::kw__Thread_local:
1482 case tok::kw_inline:
1483 case tok::kw_virtual:
1484 case tok::kw_explicit:
1487 case tok::kw___module_private__:
1490 case tok::kw___unknown_anytype:
1503 case tok::kw_struct:
1505 case tok::kw___interface:
1510 case tok::kw_volatile:
1511 return TPResult::True;
1514 case tok::kw_private:
1516 return TPResult::False;
1518 case tok::kw___private:
1519 case tok::kw___local:
1520 case tok::kw___global:
1521 case tok::kw___constant:
1522 case tok::kw___generic:
1524 case tok::kw___read_only:
1525 case tok::kw___write_only:
1526 case tok::kw___read_write:
1531 case tok::kw_groupshared:
1534 case tok::kw_restrict:
1535 case tok::kw__Complex:
1536 case tok::kw___attribute:
1537 case tok::kw___auto_type:
1538 return TPResult::True;
1541 case tok::kw___declspec:
1542 case tok::kw___cdecl:
1543 case tok::kw___stdcall:
1544 case tok::kw___fastcall:
1545 case tok::kw___thiscall:
1546 case tok::kw___regcall:
1547 case tok::kw___vectorcall:
1549 case tok::kw___sptr:
1550 case tok::kw___uptr:
1551 case tok::kw___ptr64:
1552 case tok::kw___ptr32:
1553 case tok::kw___forceinline:
1554 case tok::kw___unaligned:
1555 case tok::kw__Nonnull:
1556 case tok::kw__Nullable:
1557 case tok::kw__Nullable_result:
1558 case tok::kw__Null_unspecified:
1559 case tok::kw___kindof:
1560 return TPResult::True;
1563 case tok::kw___funcref:
1564 return TPResult::True;
1567 case tok::kw___pascal:
1568 return TPResult::True;
1571 case tok::kw___vector:
1572 return TPResult::True;
1574 case tok::annot_template_id: {
1580 InvalidAsDeclSpec) {
1585 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1586 return TPResult::Ambiguous;
1589 return TPResult::Error;
1590 if (IsPlaceholderSpecifier(TemplateId, 0))
1591 return TPResult::True;
1593 return TPResult::False;
1595 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1596 assert(Tok.
is(tok::annot_typename));
1600 case tok::annot_cxxscope:
1603 return TPResult::Error;
1604 if (!Tok.
is(tok::annot_typename)) {
1605 if (Tok.
is(tok::annot_cxxscope) &&
1606 NextToken().is(tok::annot_template_id)) {
1610 if (InvalidAsDeclSpec) {
1611 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1612 return TPResult::Ambiguous;
1614 return TPResult::Error;
1616 if (IsPlaceholderSpecifier(TemplateId, 1))
1617 return TPResult::True;
1621 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::identifier)) {
1627 RevertingTentativeParsingAction PA(*
this);
1628 ConsumeAnnotationToken();
1630 bool isIdentifier = Tok.
is(tok::identifier);
1631 TPResult TPR = TPResult::False;
1633 TPR = isCXXDeclarationSpecifier(
1634 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1637 TPR == TPResult::True || TPR == TPResult::Error)
1638 return TPResult::Error;
1640 if (InvalidAsDeclSpec) {
1643 *InvalidAsDeclSpec =
true;
1644 return TPResult::Ambiguous;
1650 if (((Tok.
is(tok::amp) || Tok.
is(tok::star)) &&
1653 (Tok.
is(tok::ampamp) &&
NextToken().is(tok::greater)))
1654 return TPResult::True;
1660 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1662 return TPResult::Error;
1663 case ANK_TentativeDecl:
1664 return TPResult::False;
1665 case ANK_TemplateName:
1670 return TPResult::Error;
1674 if (Tok.
isNot(tok::annot_cxxscope))
1684 case ANK_Unresolved:
1685 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1691 assert(Tok.
isNot(tok::annot_cxxscope) ||
1693 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1694 BracedCastResult, InvalidAsDeclSpec);
1697 return TPResult::False;
1720 case tok::annot_typename:
1725 RevertingTentativeParsingAction PA(*
this);
1728 TPResult TPR = TryParseProtocolQualifiers();
1729 bool isFollowedByParen = Tok.
is(tok::l_paren);
1730 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1732 if (TPR == TPResult::Error)
1733 return TPResult::Error;
1735 if (isFollowedByParen)
1736 return TPResult::Ambiguous;
1739 return BracedCastResult;
1741 return TPResult::True;
1746 case tok::kw_wchar_t:
1747 case tok::kw_char8_t:
1748 case tok::kw_char16_t:
1749 case tok::kw_char32_t:
1754 case tok::kw___int64:
1755 case tok::kw___int128:
1756 case tok::kw_signed:
1757 case tok::kw_unsigned:
1760 case tok::kw_double:
1761 case tok::kw___bf16:
1762 case tok::kw__Float16:
1763 case tok::kw___float128:
1764 case tok::kw___ibm128:
1766 case tok::annot_decltype:
1767 case tok::kw__Accum:
1768 case tok::kw__Fract:
1770#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1771#include "clang/Basic/OpenCLImageTypes.def"
1773 return TPResult::Ambiguous;
1782 return BracedCastResult;
1784 if (isStartOfObjCClassMessageMissingOpenBracket())
1785 return TPResult::False;
1787 return TPResult::True;
1790 case tok::kw_typeof: {
1792 return TPResult::True;
1794 RevertingTentativeParsingAction PA(*
this);
1796 TPResult TPR = TryParseTypeofSpecifier();
1797 bool isFollowedByParen = Tok.
is(tok::l_paren);
1798 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1800 if (TPR == TPResult::Error)
1801 return TPResult::Error;
1803 if (isFollowedByParen)
1804 return TPResult::Ambiguous;
1807 return BracedCastResult;
1809 return TPResult::True;
1812#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1813#include "clang/Basic/TransformTypeTraits.def"
1814 return TPResult::True;
1817 case tok::kw__Atomic:
1818 return TPResult::True;
1820 case tok::kw__BitInt:
1821 case tok::kw__ExtInt: {
1823 return TPResult::Error;
1824 RevertingTentativeParsingAction PA(*
this);
1829 return TPResult::Error;
1831 if (Tok.
is(tok::l_paren))
1832 return TPResult::Ambiguous;
1835 return BracedCastResult;
1837 return TPResult::True;
1840 return TPResult::False;
1844bool Parser::isCXXDeclarationSpecifierAType() {
1847 case tok::annot_decltype:
1848 case tok::annot_template_id:
1849 case tok::annot_typename:
1850 case tok::kw_typeof:
1851#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1852#include "clang/Basic/TransformTypeTraits.def"
1857 case tok::kw_struct:
1859 case tok::kw___interface:
1865 case tok::kw_wchar_t:
1866 case tok::kw_char8_t:
1867 case tok::kw_char16_t:
1868 case tok::kw_char32_t:
1872 case tok::kw__ExtInt:
1873 case tok::kw__BitInt:
1875 case tok::kw___int64:
1876 case tok::kw___int128:
1877 case tok::kw_signed:
1878 case tok::kw_unsigned:
1881 case tok::kw_double:
1882 case tok::kw___bf16:
1883 case tok::kw__Float16:
1884 case tok::kw___float128:
1885 case tok::kw___ibm128:
1887 case tok::kw___unknown_anytype:
1888 case tok::kw___auto_type:
1889 case tok::kw__Accum:
1890 case tok::kw__Fract:
1892#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1893#include "clang/Basic/OpenCLImageTypes.def"
1899 case tok::kw__Atomic:
1912Parser::TPResult Parser::TryParseTypeofSpecifier() {
1913 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1916 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1920 return TPResult::Error;
1922 return TPResult::Ambiguous;
1927Parser::TPResult Parser::TryParseProtocolQualifiers() {
1928 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1931 if (Tok.
isNot(tok::identifier))
1932 return TPResult::Error;
1935 if (Tok.
is(tok::comma)) {
1940 if (Tok.
is(tok::greater)) {
1942 return TPResult::Ambiguous;
1946 return TPResult::Error;
1959bool Parser::isCXXFunctionDeclarator(
1971 RevertingTentativeParsingAction PA(*
this);
1974 bool InvalidAsDeclaration =
false;
1975 TPResult TPR = TryParseParameterDeclarationClause(
1976 &InvalidAsDeclaration,
false,
1977 AllowImplicitTypename);
1978 if (TPR == TPResult::Ambiguous) {
1979 if (Tok.
isNot(tok::r_paren))
1980 TPR = TPResult::False;
1983 if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1984 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1985 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1986 isCXX11VirtSpecifier(Next))
1990 TPR = TPResult::True;
1991 else if (InvalidAsDeclaration)
1993 TPR = TPResult::False;
1997 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1998 *IsAmbiguous =
true;
2001 return TPR != TPResult::False;
2021Parser::TPResult Parser::TryParseParameterDeclarationClause(
2022 bool *InvalidAsDeclaration,
bool VersusTemplateArgument,
2025 if (Tok.
is(tok::r_paren))
2026 return TPResult::Ambiguous;
2037 if (Tok.
is(tok::ellipsis)) {
2039 if (Tok.
is(tok::r_paren))
2040 return TPResult::True;
2042 return TPResult::False;
2046 if (isCXX11AttributeSpecifier(
false,
2048 return TPResult::True;
2051 MaybeParseMicrosoftAttributes(attrs);
2056 TPResult TPR = isCXXDeclarationSpecifier(
2057 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
2060 if (TPR != TPResult::Ambiguous &&
2061 !(VersusTemplateArgument && TPR == TPResult::True))
2064 bool SeenType =
false;
2065 bool DeclarationSpecifierIsAuto = Tok.
is(tok::kw_auto);
2067 SeenType |= isCXXDeclarationSpecifierAType();
2068 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
2069 return TPResult::Error;
2072 if (SeenType && Tok.
is(tok::identifier))
2073 return TPResult::True;
2075 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
2076 InvalidAsDeclaration);
2077 if (TPR == TPResult::Error)
2081 if (TPR == TPResult::True && !VersusTemplateArgument)
2083 }
while (TPR != TPResult::False);
2087 TPR = TryParseDeclarator(
2091 DeclarationSpecifierIsAuto);
2092 if (TPR != TPResult::Ambiguous)
2096 if (Tok.
is(tok::kw___attribute))
2097 return TPResult::True;
2108 if (VersusTemplateArgument)
2109 return Tok.
is(tok::equal) ? TPResult::True : TPResult::False;
2111 if (Tok.
is(tok::equal)) {
2115 return TPResult::Error;
2118 if (Tok.
is(tok::ellipsis)) {
2120 if (Tok.
is(tok::r_paren))
2121 return TPResult::True;
2123 return TPResult::False;
2130 return TPResult::Ambiguous;
2146Parser::TryParseFunctionDeclarator(
bool MayHaveTrailingReturnType) {
2149 TPResult TPR = TryParseParameterDeclarationClause();
2150 if (TPR == TPResult::Ambiguous && Tok.
isNot(tok::r_paren))
2151 TPR = TPResult::False;
2153 if (TPR == TPResult::False || TPR == TPResult::Error)
2158 return TPResult::Error;
2161 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
2166 if (Tok.
isOneOf(tok::amp, tok::ampamp))
2170 if (Tok.
is(tok::kw_throw)) {
2172 if (Tok.
isNot(tok::l_paren))
2173 return TPResult::Error;
2178 return TPResult::Error;
2180 if (Tok.
is(tok::kw_noexcept)) {
2183 if (Tok.
is(tok::l_paren)) {
2187 return TPResult::Error;
2192 if (!TrySkipAttributes())
2193 return TPResult::Ambiguous;
2196 if (Tok.
is(tok::arrow) && MayHaveTrailingReturnType) {
2197 if (TPR == TPResult::True)
2200 if (Tok.
is(tok::identifier) && NameAfterArrowIsNonType()) {
2201 return TPResult::False;
2203 if (isCXXTypeId(TentativeCXXTypeIdContext::TypeIdInTrailingReturnType))
2204 return TPResult::True;
2207 return TPResult::Ambiguous;
2214bool Parser::NameAfterArrowIsNonType() {
2215 assert(Tok.
is(tok::identifier));
2217 if (Next.is(tok::coloncolon))
2222 TentativeParseCCC CCC(Next);
2225 switch (Classification.
getKind()) {
2239Parser::TPResult Parser::TryParseBracketDeclarator() {
2244 if (Tok.
is(tok::l_brace))
2245 return TPResult::False;
2248 return TPResult::Error;
2252 if (Tok.
isNot(tok::r_square))
2253 return TPResult::False;
2256 return TPResult::Ambiguous;
2263Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
2264 if (!TokensToSkip) {
2265 if (Tok.
isNot(tok::less))
2266 return TPResult::False;
2268 return TPResult::True;
2271 RevertingTentativeParsingAction PA(*
this);
2273 while (TokensToSkip) {
2279 return TPResult::False;
2284 bool InvalidAsTemplateArgumentList =
false;
2286 &InvalidAsTemplateArgumentList) ==
2288 return TPResult::True;
2289 if (InvalidAsTemplateArgumentList)
2290 return TPResult::False;
2304 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2306 return TPResult::Ambiguous;
2307 return TPResult::False;
2312Parser::TPResult Parser::isExplicitBool() {
2313 assert(Tok.
is(tok::l_paren) &&
"expected to be looking at a '(' token");
2315 RevertingTentativeParsingAction PA(*
this);
2323 while (Tok.
is(tok::l_paren))
2327 return TPResult::Error;
2332 if (Tok.
is(tok::annot_cxxscope)) {
2336 ConsumeAnnotationToken();
2341 if (Tok.
is(tok::kw_operator))
2342 return TPResult::Ambiguous;
2345 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::annot_template_id))
2346 return TPResult::True;
2349 : *takeTemplateIdAnnotation(Tok)->Name,
2351 return TPResult::True;
2357 !isConstructorDeclarator(SS.
isEmpty(),
2359 return TPResult::True;
2362 return TPResult::Ambiguous;
static constexpr bool isOneOf()
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
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.
NameClassificationKind getKind() const
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...
@ NC_VarTemplate
The name was classified as a variable template name.
@ NC_NonType
The name was classified as a specific non-type, non-template declaration.
@ NC_FunctionTemplate
The name was classified as a function template name.
@ NC_OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, const Token &NextToken, CorrectionCandidateCallback *CCC=nullptr)
Perform name lookup on the given name, classifying it based on the results of name lookup and the fol...
void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)
Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure.
bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, SourceLocation NameLoc, CXXScopeSpec &SS, ParsedTemplateTy *Template=nullptr)
Determine whether a particular identifier might be the name in a C++1z deduction-guide declaration.
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
bool isRegularKeywordAttribute() const
Return true if the token is a keyword that is parsed in the same position as a standard attribute,...
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.