17 using namespace clang;
49 bool 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(
84 DeclSpec::FriendSpecified::No))
100 case tok::kw_operator:
112 return isCXXSimpleDeclaration(
false);
136 bool 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;
202 Parser::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;
276 Parser::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;
332 Parser::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;
488 bool 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;
539 Parser::ConditionOrInitStatement
540 Parser::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;
627 bool 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;
737 Parser::CXX11AttributeKind
738 Parser::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;
884 bool 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))
914 Parser::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;
957 Parser::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();
1086 Parser::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;
1385 if (!
getLangOpts().ObjC && Next.is(tok::identifier))
1386 return TPResult::True;
1388 if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
1393 TentativeParseCCC CCC(Next);
1394 switch (TryAnnotateName(&CCC)) {
1396 return TPResult::Error;
1397 case ANK_TentativeDecl:
1398 return TPResult::False;
1399 case ANK_TemplateName:
1406 return TPResult::Error;
1407 if (Tok.
isNot(tok::identifier))
1413 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1414 case ANK_Unresolved:
1415 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1419 assert(Tok.
isNot(tok::identifier) &&
1420 "TryAnnotateName succeeded without producing an annotation");
1427 return TPResult::Error;
1431 if (Tok.
is(tok::identifier))
1432 return TPResult::False;
1436 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1440 case tok::kw_typename:
1444 return TPResult::Error;
1446 BracedCastResult, InvalidAsDeclSpec);
1448 case tok::kw_auto: {
1450 return TPResult::True;
1452 return TPResult::False;
1454 return TPResult::Ambiguous;
1455 return TPResult::True;
1458 case tok::coloncolon: {
1460 if (Next.isOneOf(tok::kw_new,
1462 return TPResult::False;
1465 case tok::kw___super:
1466 case tok::kw_decltype:
1470 return TPResult::Error;
1471 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1481 case tok::kw_friend:
1482 case tok::kw_typedef:
1483 case tok::kw_constexpr:
1484 case tok::kw_consteval:
1485 case tok::kw_constinit:
1487 case tok::kw_register:
1488 case tok::kw_static:
1489 case tok::kw_extern:
1490 case tok::kw_mutable:
1491 case tok::kw___thread:
1492 case tok::kw_thread_local:
1493 case tok::kw__Thread_local:
1495 case tok::kw_inline:
1496 case tok::kw_virtual:
1497 case tok::kw_explicit:
1500 case tok::kw___module_private__:
1503 case tok::kw___unknown_anytype:
1516 case tok::kw_struct:
1518 case tok::kw___interface:
1523 case tok::kw_volatile:
1524 return TPResult::True;
1527 case tok::kw_private:
1529 return TPResult::False;
1531 case tok::kw___private:
1532 case tok::kw___local:
1533 case tok::kw___global:
1534 case tok::kw___constant:
1535 case tok::kw___generic:
1537 case tok::kw___read_only:
1538 case tok::kw___write_only:
1539 case tok::kw___read_write:
1544 case tok::kw_groupshared:
1550 case tok::kw_restrict:
1551 case tok::kw__Complex:
1552 case tok::kw___attribute:
1553 case tok::kw___auto_type:
1554 return TPResult::True;
1557 case tok::kw___declspec:
1558 case tok::kw___cdecl:
1559 case tok::kw___stdcall:
1560 case tok::kw___fastcall:
1561 case tok::kw___thiscall:
1562 case tok::kw___regcall:
1563 case tok::kw___vectorcall:
1565 case tok::kw___sptr:
1566 case tok::kw___uptr:
1567 case tok::kw___ptr64:
1568 case tok::kw___ptr32:
1569 case tok::kw___forceinline:
1570 case tok::kw___unaligned:
1571 case tok::kw__Nonnull:
1572 case tok::kw__Nullable:
1573 case tok::kw__Nullable_result:
1574 case tok::kw__Null_unspecified:
1575 case tok::kw___kindof:
1576 return TPResult::True;
1579 case tok::kw___funcref:
1580 return TPResult::True;
1583 case tok::kw___pascal:
1584 return TPResult::True;
1587 case tok::kw___vector:
1588 return TPResult::True;
1590 case tok::kw_this: {
1594 RevertingTentativeParsingAction PA(*
this);
1596 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1599 return TPResult::False;
1601 case tok::annot_template_id: {
1607 InvalidAsDeclSpec) {
1612 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1613 return TPResult::Ambiguous;
1616 return TPResult::Error;
1617 if (IsPlaceholderSpecifier(TemplateId, 0))
1618 return TPResult::True;
1620 return TPResult::False;
1622 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1623 assert(Tok.
is(tok::annot_typename));
1627 case tok::annot_cxxscope:
1630 return TPResult::Error;
1631 if (!Tok.
is(tok::annot_typename)) {
1632 if (Tok.
is(tok::annot_cxxscope) &&
1633 NextToken().is(tok::annot_template_id)) {
1637 if (InvalidAsDeclSpec) {
1638 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1639 return TPResult::Ambiguous;
1641 return TPResult::Error;
1643 if (IsPlaceholderSpecifier(TemplateId, 1))
1644 return TPResult::True;
1648 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::identifier)) {
1654 RevertingTentativeParsingAction PA(*
this);
1655 ConsumeAnnotationToken();
1657 bool isIdentifier = Tok.
is(tok::identifier);
1658 TPResult TPR = TPResult::False;
1660 TPR = isCXXDeclarationSpecifier(
1661 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1664 TPR == TPResult::True || TPR == TPResult::Error)
1665 return TPResult::Error;
1667 if (InvalidAsDeclSpec) {
1670 *InvalidAsDeclSpec =
true;
1671 return TPResult::Ambiguous;
1677 if (((Tok.
is(tok::amp) || Tok.
is(tok::star)) &&
1680 (Tok.
is(tok::ampamp) &&
NextToken().is(tok::greater)))
1681 return TPResult::True;
1687 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1689 return TPResult::Error;
1690 case ANK_TentativeDecl:
1691 return TPResult::False;
1692 case ANK_TemplateName:
1697 return TPResult::Error;
1701 if (Tok.
isNot(tok::annot_cxxscope))
1711 case ANK_Unresolved:
1712 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1718 assert(Tok.
isNot(tok::annot_cxxscope) ||
1720 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1721 BracedCastResult, InvalidAsDeclSpec);
1724 return TPResult::False;
1747 case tok::annot_typename:
1752 RevertingTentativeParsingAction PA(*
this);
1755 TPResult TPR = TryParseProtocolQualifiers();
1756 bool isFollowedByParen = Tok.
is(tok::l_paren);
1757 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1759 if (TPR == TPResult::Error)
1760 return TPResult::Error;
1762 if (isFollowedByParen)
1763 return TPResult::Ambiguous;
1766 return BracedCastResult;
1768 return TPResult::True;
1774 case tok::kw_wchar_t:
1775 case tok::kw_char8_t:
1776 case tok::kw_char16_t:
1777 case tok::kw_char32_t:
1782 case tok::kw___int64:
1783 case tok::kw___int128:
1784 case tok::kw_signed:
1785 case tok::kw_unsigned:
1788 case tok::kw_double:
1789 case tok::kw___bf16:
1790 case tok::kw__Float16:
1791 case tok::kw___float128:
1792 case tok::kw___ibm128:
1794 case tok::annot_decltype:
1795 case tok::kw__Accum:
1796 case tok::kw__Fract:
1798 case tok::annot_pack_indexing_type:
1799 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1800 #include "clang/Basic/OpenCLImageTypes.def"
1802 return TPResult::Ambiguous;
1811 return BracedCastResult;
1813 if (isStartOfObjCClassMessageMissingOpenBracket())
1814 return TPResult::False;
1816 return TPResult::True;
1819 case tok::kw_typeof: {
1821 return TPResult::True;
1823 RevertingTentativeParsingAction PA(*
this);
1825 TPResult TPR = TryParseTypeofSpecifier();
1826 bool isFollowedByParen = Tok.
is(tok::l_paren);
1827 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1829 if (TPR == TPResult::Error)
1830 return TPResult::Error;
1832 if (isFollowedByParen)
1833 return TPResult::Ambiguous;
1836 return BracedCastResult;
1838 return TPResult::True;
1841 #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1842 #include "clang/Basic/TransformTypeTraits.def"
1843 return TPResult::True;
1846 case tok::kw__Alignas:
1847 return TPResult::True;
1849 case tok::kw__Atomic:
1850 return TPResult::True;
1852 case tok::kw__BitInt:
1853 case tok::kw__ExtInt: {
1855 return TPResult::Error;
1856 RevertingTentativeParsingAction PA(*
this);
1861 return TPResult::Error;
1863 if (Tok.
is(tok::l_paren))
1864 return TPResult::Ambiguous;
1867 return BracedCastResult;
1869 return TPResult::True;
1872 return TPResult::False;
1876 bool Parser::isCXXDeclarationSpecifierAType() {
1879 case tok::annot_decltype:
1880 case tok::annot_pack_indexing_type:
1881 case tok::annot_template_id:
1882 case tok::annot_typename:
1883 case tok::kw_typeof:
1884 #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1885 #include "clang/Basic/TransformTypeTraits.def"
1890 case tok::kw_struct:
1892 case tok::kw___interface:
1898 case tok::kw_wchar_t:
1899 case tok::kw_char8_t:
1900 case tok::kw_char16_t:
1901 case tok::kw_char32_t:
1905 case tok::kw__ExtInt:
1906 case tok::kw__BitInt:
1908 case tok::kw___int64:
1909 case tok::kw___int128:
1910 case tok::kw_signed:
1911 case tok::kw_unsigned:
1914 case tok::kw_double:
1915 case tok::kw___bf16:
1916 case tok::kw__Float16:
1917 case tok::kw___float128:
1918 case tok::kw___ibm128:
1920 case tok::kw___unknown_anytype:
1921 case tok::kw___auto_type:
1922 case tok::kw__Accum:
1923 case tok::kw__Fract:
1925 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1926 #include "clang/Basic/OpenCLImageTypes.def"
1932 case tok::kw__Atomic:
1945 Parser::TPResult Parser::TryParseTypeofSpecifier() {
1946 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1949 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1953 return TPResult::Error;
1955 return TPResult::Ambiguous;
1960 Parser::TPResult Parser::TryParseProtocolQualifiers() {
1961 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1964 if (Tok.
isNot(tok::identifier))
1965 return TPResult::Error;
1968 if (Tok.
is(tok::comma)) {
1973 if (Tok.
is(tok::greater)) {
1975 return TPResult::Ambiguous;
1979 return TPResult::Error;
1992 bool Parser::isCXXFunctionDeclarator(
2004 RevertingTentativeParsingAction PA(*
this);
2007 bool InvalidAsDeclaration =
false;
2008 TPResult TPR = TryParseParameterDeclarationClause(
2009 &InvalidAsDeclaration,
false,
2010 AllowImplicitTypename);
2011 if (TPR == TPResult::Ambiguous) {
2012 if (Tok.
isNot(tok::r_paren))
2013 TPR = TPResult::False;
2016 if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
2017 tok::kw_throw, tok::kw_noexcept, tok::l_square,
2018 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
2019 isCXX11VirtSpecifier(Next))
2023 TPR = TPResult::True;
2024 else if (InvalidAsDeclaration)
2026 TPR = TPResult::False;
2030 if (IsAmbiguous && TPR == TPResult::Ambiguous)
2031 *IsAmbiguous =
true;
2034 return TPR != TPResult::False;
2054 Parser::TPResult Parser::TryParseParameterDeclarationClause(
2055 bool *InvalidAsDeclaration,
bool VersusTemplateArgument,
2058 if (Tok.
is(tok::r_paren))
2059 return TPResult::Ambiguous;
2070 if (Tok.
is(tok::ellipsis)) {
2072 if (Tok.
is(tok::r_paren))
2073 return TPResult::True;
2075 return TPResult::False;
2079 if (isCXX11AttributeSpecifier(
false,
2081 return TPResult::True;
2084 MaybeParseMicrosoftAttributes(attrs);
2089 TPResult TPR = isCXXDeclarationSpecifier(
2090 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
2093 if (TPR != TPResult::Ambiguous &&
2094 !(VersusTemplateArgument && TPR == TPResult::True))
2097 bool SeenType =
false;
2098 bool DeclarationSpecifierIsAuto = Tok.
is(tok::kw_auto);
2100 SeenType |= isCXXDeclarationSpecifierAType();
2101 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
2102 return TPResult::Error;
2105 if (SeenType && Tok.
is(tok::identifier))
2106 return TPResult::True;
2108 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
2109 InvalidAsDeclaration);
2110 if (TPR == TPResult::Error)
2114 if (TPR == TPResult::True && !VersusTemplateArgument)
2116 }
while (TPR != TPResult::False);
2120 TPR = TryParseDeclarator(
2124 DeclarationSpecifierIsAuto);
2125 if (TPR != TPResult::Ambiguous)
2129 if (Tok.
is(tok::kw___attribute))
2130 return TPResult::True;
2141 if (VersusTemplateArgument)
2142 return Tok.
is(tok::equal) ? TPResult::True : TPResult::False;
2144 if (Tok.
is(tok::equal)) {
2148 return TPResult::Error;
2151 if (Tok.
is(tok::ellipsis)) {
2153 if (Tok.
is(tok::r_paren))
2154 return TPResult::True;
2156 return TPResult::False;
2163 return TPResult::Ambiguous;
2179 Parser::TryParseFunctionDeclarator(
bool MayHaveTrailingReturnType) {
2182 TPResult TPR = TryParseParameterDeclarationClause();
2183 if (TPR == TPResult::Ambiguous && Tok.
isNot(tok::r_paren))
2184 TPR = TPResult::False;
2186 if (TPR == TPResult::False || TPR == TPResult::Error)
2191 return TPResult::Error;
2194 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
2199 if (Tok.
isOneOf(tok::amp, tok::ampamp))
2203 if (Tok.
is(tok::kw_throw)) {
2205 if (Tok.
isNot(tok::l_paren))
2206 return TPResult::Error;
2211 return TPResult::Error;
2213 if (Tok.
is(tok::kw_noexcept)) {
2216 if (Tok.
is(tok::l_paren)) {
2220 return TPResult::Error;
2225 if (!TrySkipAttributes())
2226 return TPResult::Ambiguous;
2229 if (Tok.
is(tok::arrow) && MayHaveTrailingReturnType) {
2230 if (TPR == TPResult::True)
2233 if (Tok.
is(tok::identifier) && NameAfterArrowIsNonType()) {
2234 return TPResult::False;
2236 if (isCXXTypeId(TentativeCXXTypeIdContext::TypeIdInTrailingReturnType))
2237 return TPResult::True;
2240 return TPResult::Ambiguous;
2247 bool Parser::NameAfterArrowIsNonType() {
2248 assert(Tok.
is(tok::identifier));
2250 if (Next.is(tok::coloncolon))
2255 TentativeParseCCC CCC(Next);
2258 switch (Classification.
getKind()) {
2272 Parser::TPResult Parser::TryParseBracketDeclarator() {
2277 if (Tok.
is(tok::l_brace))
2278 return TPResult::False;
2281 return TPResult::Error;
2285 if (Tok.
isNot(tok::r_square))
2286 return TPResult::False;
2289 return TPResult::Ambiguous;
2296 Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
2297 if (!TokensToSkip) {
2298 if (Tok.
isNot(tok::less))
2299 return TPResult::False;
2301 return TPResult::True;
2304 RevertingTentativeParsingAction PA(*
this);
2306 while (TokensToSkip) {
2312 return TPResult::False;
2317 bool InvalidAsTemplateArgumentList =
false;
2319 &InvalidAsTemplateArgumentList) ==
2321 return TPResult::True;
2322 if (InvalidAsTemplateArgumentList)
2323 return TPResult::False;
2337 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2339 return TPResult::Ambiguous;
2340 return TPResult::False;
2345 Parser::TPResult Parser::isExplicitBool() {
2346 assert(Tok.
is(tok::l_paren) &&
"expected to be looking at a '(' token");
2348 RevertingTentativeParsingAction PA(*
this);
2356 while (Tok.
is(tok::l_paren))
2360 return TPResult::Error;
2365 if (Tok.
is(tok::annot_cxxscope)) {
2369 ConsumeAnnotationToken();
2374 if (Tok.
is(tok::kw_operator))
2375 return TPResult::Ambiguous;
2378 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::annot_template_id))
2379 return TPResult::True;
2382 : *takeTemplateIdAnnotation(Tok)->Name,
2384 return TPResult::True;
2390 !isConstructorDeclarator(SS.
isEmpty(),
2392 return TPResult::True;
2395 return TPResult::Ambiguous;
constexpr static 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 isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
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.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext=false)
Scope * getCurScope() const
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
bool TryConsumeToken(tok::TokenKind Expected)
const LangOptions & getLangOpts() 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 ...
@ 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...
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.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
void * getAnnotationValue() const
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)) {....
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,...
IdentifierInfo * getIdentifierInfo() 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.
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.