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(
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) {
742 return CAK_AttributeSpecifier;
745 return CAK_AttributeSpecifier;
748 return CAK_NotAttributeSpecifier;
752 return CAK_AttributeSpecifier;
755 if (GetLookAheadToken(2).is(tok::kw_using))
756 return CAK_AttributeSpecifier;
758 RevertingTentativeParsingAction PA(*
this);
766 bool IsAttribute =
SkipUntil(tok::r_square);
767 IsAttribute &= Tok.
is(tok::r_square);
769 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
785 RevertingTentativeParsingAction LambdaTPA(*
this);
787 LambdaIntroducerTentativeParse Tentative;
788 if (ParseLambdaIntroducer(Intro, &Tentative)) {
792 return CAK_NotAttributeSpecifier;
796 case LambdaIntroducerTentativeParse::MessageSend:
799 return CAK_NotAttributeSpecifier;
801 case LambdaIntroducerTentativeParse::Success:
802 case LambdaIntroducerTentativeParse::Incomplete:
804 if (Tok.
is(tok::r_square))
806 return CAK_AttributeSpecifier;
808 if (OuterMightBeMessageSend)
810 return CAK_NotAttributeSpecifier;
813 return CAK_InvalidAttributeSpecifier;
815 case LambdaIntroducerTentativeParse::Invalid:
826 bool IsAttribute =
true;
827 while (Tok.
isNot(tok::r_square)) {
828 if (Tok.
is(tok::comma)) {
830 return CAK_AttributeSpecifier;
839 if (!TryParseCXX11AttributeIdentifier(
Loc)) {
843 if (Tok.
is(tok::coloncolon)) {
845 if (!TryParseCXX11AttributeIdentifier(
Loc)) {
852 if (Tok.
is(tok::l_paren)) {
868 if (Tok.
is(tok::r_square)) {
870 IsAttribute = Tok.
is(tok::r_square);
878 return CAK_AttributeSpecifier;
881 return CAK_NotAttributeSpecifier;
884bool Parser::TrySkipAttributes() {
885 while (Tok.
isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
888 if (Tok.
is(tok::l_square)) {
890 if (Tok.
isNot(tok::l_square))
903 if (Tok.
isNot(tok::l_paren))
914Parser::TPResult Parser::TryParsePtrOperatorSeq() {
917 return TPResult::Error;
919 if (Tok.
isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
920 (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::star))) {
925 if (!TrySkipAttributes())
926 return TPResult::Error;
928 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
929 tok::kw__Nonnull, tok::kw__Nullable,
930 tok::kw__Nullable_result, tok::kw__Null_unspecified,
934 return TPResult::True;
957Parser::TPResult Parser::TryParseOperatorId() {
958 assert(Tok.
is(tok::kw_operator));
963 case tok::kw_new:
case tok::kw_delete:
965 if (Tok.
is(tok::l_square) &&
NextToken().is(tok::r_square)) {
969 return TPResult::True;
971#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
973#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
974#include "clang/Basic/OperatorKinds.def"
976 return TPResult::True;
982 return TPResult::True;
990 return TPResult::True;
1000 bool FoundUDSuffix =
false;
1003 ConsumeStringToken();
1004 }
while (isTokenStringLiteral());
1006 if (!FoundUDSuffix) {
1007 if (Tok.
is(tok::identifier))
1010 return TPResult::Error;
1012 return TPResult::True;
1016 bool AnyDeclSpecifiers =
false;
1019 if (TPR == TPResult::Error)
1021 if (TPR == TPResult::False) {
1022 if (!AnyDeclSpecifiers)
1023 return TPResult::Error;
1026 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1027 return TPResult::Error;
1028 AnyDeclSpecifiers =
true;
1030 return TryParsePtrOperatorSeq();
1086Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
1087 bool mayHaveIdentifier,
1088 bool mayHaveDirectInit,
1089 bool mayHaveTrailingReturnType) {
1093 if (TryParsePtrOperatorSeq() == TPResult::Error)
1094 return TPResult::Error;
1098 if (Tok.
is(tok::ellipsis))
1101 if ((Tok.
isOneOf(tok::identifier, tok::kw_operator) ||
1102 (Tok.
is(tok::annot_cxxscope) && (
NextToken().is(tok::identifier) ||
1104 mayHaveIdentifier) {
1106 if (Tok.
is(tok::annot_cxxscope)) {
1111 return TPResult::Error;
1112 ConsumeAnnotationToken();
1113 }
else if (Tok.
is(tok::identifier)) {
1116 if (Tok.
is(tok::kw_operator)) {
1117 if (TryParseOperatorId() == TPResult::Error)
1118 return TPResult::Error;
1121 }
else if (Tok.
is(tok::l_paren)) {
1123 if (mayBeAbstract &&
1124 (Tok.
is(tok::r_paren) ||
1126 (Tok.
is(tok::ellipsis) &&
NextToken().is(tok::r_paren)) ||
1127 isDeclarationSpecifier(
1131 TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
1132 if (TPR != TPResult::Ambiguous)
1138 if (Tok.
isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
1139 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
1140 tok::kw___regcall, tok::kw___vectorcall))
1141 return TPResult::True;
1142 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
1143 if (TPR != TPResult::Ambiguous)
1145 if (Tok.
isNot(tok::r_paren))
1146 return TPResult::False;
1149 }
else if (!mayBeAbstract) {
1150 return TPResult::False;
1153 if (mayHaveDirectInit)
1154 return TPResult::Ambiguous;
1157 TPResult TPR(TPResult::Ambiguous);
1159 if (Tok.
is(tok::l_paren)) {
1164 if (!mayBeAbstract && !isCXXFunctionDeclarator())
1170 TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
1171 }
else if (Tok.
is(tok::l_square)) {
1174 TPR = TryParseBracketDeclarator();
1175 }
else if (Tok.
is(tok::kw_requires)) {
1178 TPR = TPResult::True;
1183 if (TPR != TPResult::Ambiguous)
1187 return TPResult::Ambiguous;
1191 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
1197 TentativeParseCCC(
const Token &Next) {
1198 WantRemainingKeywords =
false;
1199 WantTypeSpecifiers =
1200 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
1201 tok::identifier, tok::comma);
1204 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1208 llvm::all_of(Candidate,
1209 [](
NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
1215 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
1216 return std::make_unique<TentativeParseCCC>(*
this);
1334 Parser::TPResult BracedCastResult,
1335 bool *InvalidAsDeclSpec) {
1341 (GetLookAheadToken(Lookahead + 1)
1342 .
isOneOf(tok::kw_auto, tok::kw_decltype,
1352 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
1363 GetLookAheadToken(Lookahead + 1).
isOneOf(tok::amp, tok::ampamp)));
1366 case tok::identifier: {
1367 if (GetLookAheadToken(1).is(tok::ellipsis) &&
1368 GetLookAheadToken(2).is(tok::l_square)) {
1371 return TPResult::Error;
1372 if (Tok.
is(tok::identifier))
1373 return TPResult::False;
1375 BracedCastResult, InvalidAsDeclSpec);
1380 if (TryAltiVecVectorToken())
1381 return TPResult::True;
1386 return TPResult::True;
1391 if (Next.is(tok::l_paren) &&
1394 return TPResult::False;
1397 if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
1402 TentativeParseCCC CCC(Next);
1403 switch (TryAnnotateName(&CCC)) {
1405 return TPResult::Error;
1406 case ANK_TentativeDecl:
1407 return TPResult::False;
1408 case ANK_TemplateName:
1415 return TPResult::Error;
1416 if (Tok.
isNot(tok::identifier))
1422 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1423 case ANK_Unresolved:
1424 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1428 assert(Tok.
isNot(tok::identifier) &&
1429 "TryAnnotateName succeeded without producing an annotation");
1436 return TPResult::Error;
1440 if (Tok.
is(tok::identifier))
1441 return TPResult::False;
1445 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1449 case tok::kw_typename:
1453 return TPResult::Error;
1455 BracedCastResult, InvalidAsDeclSpec);
1457 case tok::kw_auto: {
1459 return TPResult::True;
1461 return TPResult::False;
1463 return TPResult::Ambiguous;
1464 return TPResult::True;
1467 case tok::coloncolon: {
1469 if (Next.isOneOf(tok::kw_new,
1471 return TPResult::False;
1474 case tok::kw___super:
1475 case tok::kw_decltype:
1479 return TPResult::Error;
1480 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1490 case tok::kw_friend:
1491 case tok::kw_typedef:
1492 case tok::kw_constexpr:
1493 case tok::kw_consteval:
1494 case tok::kw_constinit:
1496 case tok::kw_register:
1497 case tok::kw_static:
1498 case tok::kw_extern:
1499 case tok::kw_mutable:
1500 case tok::kw___thread:
1501 case tok::kw_thread_local:
1502 case tok::kw__Thread_local:
1504 case tok::kw_inline:
1505 case tok::kw_virtual:
1506 case tok::kw_explicit:
1509 case tok::kw___module_private__:
1512 case tok::kw___unknown_anytype:
1525 case tok::kw_struct:
1527 case tok::kw___interface:
1532 case tok::kw_volatile:
1533 return TPResult::True;
1536 case tok::kw_private:
1538 return TPResult::False;
1540 case tok::kw___private:
1541 case tok::kw___local:
1542 case tok::kw___global:
1543 case tok::kw___constant:
1544 case tok::kw___generic:
1546 case tok::kw___read_only:
1547 case tok::kw___write_only:
1548 case tok::kw___read_write:
1553 case tok::kw_groupshared:
1559 case tok::kw_restrict:
1560 case tok::kw__Complex:
1561 case tok::kw___attribute:
1562 case tok::kw___auto_type:
1563 return TPResult::True;
1566 case tok::kw___declspec:
1567 case tok::kw___cdecl:
1568 case tok::kw___stdcall:
1569 case tok::kw___fastcall:
1570 case tok::kw___thiscall:
1571 case tok::kw___regcall:
1572 case tok::kw___vectorcall:
1574 case tok::kw___sptr:
1575 case tok::kw___uptr:
1576 case tok::kw___ptr64:
1577 case tok::kw___ptr32:
1578 case tok::kw___forceinline:
1579 case tok::kw___unaligned:
1580 case tok::kw__Nonnull:
1581 case tok::kw__Nullable:
1582 case tok::kw__Nullable_result:
1583 case tok::kw__Null_unspecified:
1584 case tok::kw___kindof:
1585 return TPResult::True;
1588 case tok::kw___funcref:
1589 return TPResult::True;
1592 case tok::kw___pascal:
1593 return TPResult::True;
1596 case tok::kw___vector:
1597 return TPResult::True;
1599 case tok::kw_this: {
1603 RevertingTentativeParsingAction PA(*
this);
1605 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1608 return TPResult::False;
1610 case tok::annot_template_id: {
1616 InvalidAsDeclSpec) {
1621 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1622 return TPResult::Ambiguous;
1625 return TPResult::Error;
1626 if (IsPlaceholderSpecifier(TemplateId, 0))
1627 return TPResult::True;
1629 return TPResult::False;
1631 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1632 assert(Tok.
is(tok::annot_typename));
1636 case tok::annot_cxxscope:
1639 return TPResult::Error;
1640 if (!Tok.
is(tok::annot_typename)) {
1641 if (Tok.
is(tok::annot_cxxscope) &&
1642 NextToken().is(tok::annot_template_id)) {
1646 if (InvalidAsDeclSpec) {
1647 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1648 return TPResult::Ambiguous;
1650 return TPResult::Error;
1652 if (IsPlaceholderSpecifier(TemplateId, 1))
1653 return TPResult::True;
1657 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::identifier)) {
1663 RevertingTentativeParsingAction PA(*
this);
1664 ConsumeAnnotationToken();
1666 bool isIdentifier = Tok.
is(tok::identifier);
1667 TPResult TPR = TPResult::False;
1669 TPR = isCXXDeclarationSpecifier(
1670 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1673 TPR == TPResult::True || TPR == TPResult::Error)
1674 return TPResult::Error;
1676 if (InvalidAsDeclSpec) {
1679 *InvalidAsDeclSpec =
true;
1680 return TPResult::Ambiguous;
1686 if (((Tok.
is(tok::amp) || Tok.
is(tok::star)) &&
1689 (Tok.
is(tok::ampamp) &&
NextToken().is(tok::greater)))
1690 return TPResult::True;
1696 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1698 return TPResult::Error;
1699 case ANK_TentativeDecl:
1700 return TPResult::False;
1701 case ANK_TemplateName:
1706 return TPResult::Error;
1710 if (Tok.
isNot(tok::annot_cxxscope))
1720 case ANK_Unresolved:
1721 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1727 assert(Tok.
isNot(tok::annot_cxxscope) ||
1729 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1730 BracedCastResult, InvalidAsDeclSpec);
1733 return TPResult::False;
1756 case tok::annot_typename:
1761 RevertingTentativeParsingAction PA(*
this);
1764 TPResult TPR = TryParseProtocolQualifiers();
1765 bool isFollowedByParen = Tok.
is(tok::l_paren);
1766 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1768 if (TPR == TPResult::Error)
1769 return TPResult::Error;
1771 if (isFollowedByParen)
1772 return TPResult::Ambiguous;
1775 return BracedCastResult;
1777 return TPResult::True;
1783 case tok::kw_wchar_t:
1784 case tok::kw_char8_t:
1785 case tok::kw_char16_t:
1786 case tok::kw_char32_t:
1791 case tok::kw___int64:
1792 case tok::kw___int128:
1793 case tok::kw_signed:
1794 case tok::kw_unsigned:
1797 case tok::kw_double:
1798 case tok::kw___bf16:
1799 case tok::kw__Float16:
1800 case tok::kw___float128:
1801 case tok::kw___ibm128:
1803 case tok::annot_decltype:
1804 case tok::kw__Accum:
1805 case tok::kw__Fract:
1807 case tok::annot_pack_indexing_type:
1808#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1809#include "clang/Basic/OpenCLImageTypes.def"
1810#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1811#include "clang/Basic/HLSLIntangibleTypes.def"
1813 return TPResult::Ambiguous;
1822 return BracedCastResult;
1824 if (isStartOfObjCClassMessageMissingOpenBracket())
1825 return TPResult::False;
1827 return TPResult::True;
1830 case tok::kw_typeof: {
1832 return TPResult::True;
1834 RevertingTentativeParsingAction PA(*
this);
1836 TPResult TPR = TryParseTypeofSpecifier();
1837 bool isFollowedByParen = Tok.
is(tok::l_paren);
1838 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1840 if (TPR == TPResult::Error)
1841 return TPResult::Error;
1843 if (isFollowedByParen)
1844 return TPResult::Ambiguous;
1847 return BracedCastResult;
1849 return TPResult::True;
1852#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1853#include "clang/Basic/TransformTypeTraits.def"
1854 return TPResult::True;
1857 case tok::kw__Alignas:
1858 return TPResult::True;
1860 case tok::kw__Atomic:
1861 return TPResult::True;
1863 case tok::kw__BitInt:
1864 case tok::kw__ExtInt: {
1866 return TPResult::Error;
1867 RevertingTentativeParsingAction PA(*
this);
1872 return TPResult::Error;
1874 if (Tok.
is(tok::l_paren))
1875 return TPResult::Ambiguous;
1878 return BracedCastResult;
1880 return TPResult::True;
1883 return TPResult::False;
1887bool Parser::isCXXDeclarationSpecifierAType() {
1890 case tok::annot_decltype:
1891 case tok::annot_pack_indexing_type:
1892 case tok::annot_template_id:
1893 case tok::annot_typename:
1894 case tok::kw_typeof:
1895#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1896#include "clang/Basic/TransformTypeTraits.def"
1901 case tok::kw_struct:
1903 case tok::kw___interface:
1909 case tok::kw_wchar_t:
1910 case tok::kw_char8_t:
1911 case tok::kw_char16_t:
1912 case tok::kw_char32_t:
1916 case tok::kw__ExtInt:
1917 case tok::kw__BitInt:
1919 case tok::kw___int64:
1920 case tok::kw___int128:
1921 case tok::kw_signed:
1922 case tok::kw_unsigned:
1925 case tok::kw_double:
1926 case tok::kw___bf16:
1927 case tok::kw__Float16:
1928 case tok::kw___float128:
1929 case tok::kw___ibm128:
1931 case tok::kw___unknown_anytype:
1932 case tok::kw___auto_type:
1933 case tok::kw__Accum:
1934 case tok::kw__Fract:
1936#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1937#include "clang/Basic/OpenCLImageTypes.def"
1938#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1939#include "clang/Basic/HLSLIntangibleTypes.def"
1945 case tok::kw__Atomic:
1958Parser::TPResult Parser::TryParseTypeofSpecifier() {
1959 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1962 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1966 return TPResult::Error;
1968 return TPResult::Ambiguous;
1973Parser::TPResult Parser::TryParseProtocolQualifiers() {
1974 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1977 if (Tok.
isNot(tok::identifier))
1978 return TPResult::Error;
1981 if (Tok.
is(tok::comma)) {
1986 if (Tok.
is(tok::greater)) {
1988 return TPResult::Ambiguous;
1992 return TPResult::Error;
2005bool Parser::isCXXFunctionDeclarator(
2017 RevertingTentativeParsingAction PA(*
this);
2020 bool InvalidAsDeclaration =
false;
2021 TPResult TPR = TryParseParameterDeclarationClause(
2022 &InvalidAsDeclaration,
false,
2023 AllowImplicitTypename);
2024 if (TPR == TPResult::Ambiguous) {
2025 if (Tok.
isNot(tok::r_paren))
2026 TPR = TPResult::False;
2029 if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
2030 tok::kw_throw, tok::kw_noexcept, tok::l_square,
2031 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
2032 isCXX11VirtSpecifier(Next))
2036 TPR = TPResult::True;
2037 else if (InvalidAsDeclaration)
2039 TPR = TPResult::False;
2043 if (IsAmbiguous && TPR == TPResult::Ambiguous)
2044 *IsAmbiguous =
true;
2047 return TPR != TPResult::False;
2067Parser::TPResult Parser::TryParseParameterDeclarationClause(
2068 bool *InvalidAsDeclaration,
bool VersusTemplateArgument,
2071 if (Tok.
is(tok::r_paren))
2072 return TPResult::Ambiguous;
2083 if (Tok.
is(tok::ellipsis)) {
2085 if (Tok.
is(tok::r_paren))
2086 return TPResult::True;
2088 return TPResult::False;
2092 if (isCXX11AttributeSpecifier(
false,
2094 return TPResult::True;
2097 MaybeParseMicrosoftAttributes(attrs);
2102 TPResult TPR = isCXXDeclarationSpecifier(
2103 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
2106 if (TPR != TPResult::Ambiguous &&
2107 !(VersusTemplateArgument && TPR == TPResult::True))
2110 bool SeenType =
false;
2111 bool DeclarationSpecifierIsAuto = Tok.
is(tok::kw_auto);
2113 SeenType |= isCXXDeclarationSpecifierAType();
2114 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
2115 return TPResult::Error;
2118 if (SeenType && Tok.
is(tok::identifier))
2119 return TPResult::True;
2121 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
2122 InvalidAsDeclaration);
2123 if (TPR == TPResult::Error)
2127 if (TPR == TPResult::True && !VersusTemplateArgument)
2129 }
while (TPR != TPResult::False);
2133 TPR = TryParseDeclarator(
2137 DeclarationSpecifierIsAuto);
2138 if (TPR != TPResult::Ambiguous)
2142 if (Tok.
is(tok::kw___attribute))
2143 return TPResult::True;
2154 if (VersusTemplateArgument)
2155 return Tok.
is(tok::equal) ? TPResult::True : TPResult::False;
2157 if (Tok.
is(tok::equal)) {
2161 return TPResult::Error;
2164 if (Tok.
is(tok::ellipsis)) {
2166 if (Tok.
is(tok::r_paren))
2167 return TPResult::True;
2169 return TPResult::False;
2176 return TPResult::Ambiguous;
2192Parser::TryParseFunctionDeclarator(
bool MayHaveTrailingReturnType) {
2195 TPResult TPR = TryParseParameterDeclarationClause();
2196 if (TPR == TPResult::Ambiguous && Tok.
isNot(tok::r_paren))
2197 TPR = TPResult::False;
2199 if (TPR == TPResult::False || TPR == TPResult::Error)
2204 return TPResult::Error;
2207 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
2212 if (Tok.
isOneOf(tok::amp, tok::ampamp))
2216 if (Tok.
is(tok::kw_throw)) {
2218 if (Tok.
isNot(tok::l_paren))
2219 return TPResult::Error;
2224 return TPResult::Error;
2226 if (Tok.
is(tok::kw_noexcept)) {
2229 if (Tok.
is(tok::l_paren)) {
2233 return TPResult::Error;
2238 if (!TrySkipAttributes())
2239 return TPResult::Ambiguous;
2242 if (Tok.
is(tok::arrow) && MayHaveTrailingReturnType) {
2243 if (TPR == TPResult::True)
2246 if (Tok.
is(tok::identifier) && NameAfterArrowIsNonType()) {
2247 return TPResult::False;
2249 if (isCXXTypeId(TentativeCXXTypeIdContext::TypeIdInTrailingReturnType))
2250 return TPResult::True;
2253 return TPResult::Ambiguous;
2260bool Parser::NameAfterArrowIsNonType() {
2261 assert(Tok.
is(tok::identifier));
2263 if (Next.is(tok::coloncolon))
2268 TentativeParseCCC CCC(Next);
2271 switch (Classification.
getKind()) {
2285Parser::TPResult Parser::TryParseBracketDeclarator() {
2290 if (Tok.
is(tok::l_brace))
2291 return TPResult::False;
2294 return TPResult::Error;
2298 if (Tok.
isNot(tok::r_square))
2299 return TPResult::False;
2302 return TPResult::Ambiguous;
2309Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
2310 if (!TokensToSkip) {
2311 if (Tok.
isNot(tok::less))
2312 return TPResult::False;
2314 return TPResult::True;
2317 RevertingTentativeParsingAction PA(*
this);
2319 while (TokensToSkip) {
2325 return TPResult::False;
2330 bool InvalidAsTemplateArgumentList =
false;
2332 &InvalidAsTemplateArgumentList) ==
2334 return TPResult::True;
2335 if (InvalidAsTemplateArgumentList)
2336 return TPResult::False;
2350 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2352 return TPResult::Ambiguous;
2353 return TPResult::False;
2358Parser::TPResult Parser::isExplicitBool() {
2359 assert(Tok.
is(tok::l_paren) &&
"expected to be looking at a '(' token");
2361 RevertingTentativeParsingAction PA(*
this);
2369 while (Tok.
is(tok::l_paren))
2373 return TPResult::Error;
2378 if (Tok.
is(tok::annot_cxxscope)) {
2382 ConsumeAnnotationToken();
2387 if (Tok.
is(tok::kw_operator))
2388 return TPResult::Ambiguous;
2391 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::annot_template_id))
2392 return TPResult::True;
2395 : *takeTemplateIdAnnotation(Tok)->Name,
2397 return TPResult::True;
2403 !isConstructorDeclarator(SS.
isEmpty(),
2405 return TPResult::True;
2408 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.
bool hasRevertedTokenIDToIdentifier() const
True if revertTokenIDToIdentifier() was called.
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.
The JSON file list parser is used to communicate input to InstallAPI.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
@ 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.