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;
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;
1876bool 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:
1945Parser::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;
1960Parser::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;
1992bool 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;
2054Parser::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;
2179Parser::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;
2247bool Parser::NameAfterArrowIsNonType() {
2248 assert(Tok.
is(tok::identifier));
2250 if (Next.is(tok::coloncolon))
2255 TentativeParseCCC CCC(Next);
2258 switch (Classification.
getKind()) {
2272Parser::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;
2296Parser::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;
2345Parser::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;
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.
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.