17 using namespace clang;
49 bool Parser::isCXXDeclarationStatement() {
54 case tok::kw_namespace:
59 case tok::kw_static_assert:
60 case tok::kw__Static_assert:
64 return isCXXSimpleDeclaration(
false);
88 bool Parser::isCXXSimpleDeclaration(
bool AllowForRangeDecl) {
113 bool InvalidAsDeclaration =
false;
114 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
115 &InvalidAsDeclaration);
116 if (TPR != TPResult::Ambiguous)
117 return TPR != TPResult::False;
125 if (InvalidAsDeclaration)
136 RevertingTentativeParsingAction PA(*
this);
137 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
141 if (TPR == TPResult::Error)
145 if (TPR == TPResult::Ambiguous)
146 TPR = TPResult::True;
148 assert(TPR == TPResult::True || TPR == TPResult::False);
149 return TPR == TPResult::True;
154 Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
156 case tok::kw__Atomic:
163 case tok::kw___attribute:
164 case tok::kw___underlying_type: {
166 if (Tok.
isNot(tok::l_paren))
167 return TPResult::Error;
170 return TPResult::Error;
177 case tok::kw___interface:
189 while (Tok.
isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
191 if (Tok.
is(tok::l_square)) {
194 return TPResult::Error;
197 if (Tok.
isNot(tok::l_paren))
198 return TPResult::Error;
201 return TPResult::Error;
206 return TPResult::Error;
207 if (Tok.
is(tok::annot_cxxscope))
208 ConsumeAnnotationToken();
209 if (Tok.
is(tok::identifier))
211 else if (Tok.
is(tok::annot_template_id))
212 ConsumeAnnotationToken();
214 return TPResult::Error;
217 case tok::annot_cxxscope:
218 ConsumeAnnotationToken();
224 return TryParseProtocolQualifiers();
228 return TPResult::Ambiguous;
239 Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
240 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
241 return TPResult::Error;
246 if (Tok.
isNot(tok::l_paren)) {
247 TPResult TPR = isCXXDeclarationSpecifier();
248 if (TPR == TPResult::Ambiguous)
249 return TPResult::True;
250 if (TPR == TPResult::True || TPR == TPResult::Error)
252 assert(TPR == TPResult::False);
255 TPResult TPR = TryParseInitDeclaratorList();
256 if (TPR != TPResult::Ambiguous)
259 if (Tok.
isNot(tok::semi) && (!AllowForRangeDecl || Tok.
isNot(tok::colon)))
260 return TPResult::False;
262 return TPResult::Ambiguous;
292 Parser::TPResult Parser::TryParseInitDeclaratorList() {
295 TPResult TPR = TryParseDeclarator(
false);
296 if (TPR != TPResult::Ambiguous)
300 if (Tok.
isOneOf(tok::kw_asm, tok::kw___attribute))
301 return TPResult::True;
304 if (Tok.
is(tok::l_paren)) {
308 return TPResult::Error;
309 }
else if (Tok.
is(tok::l_brace)) {
312 return TPResult::True;
313 }
else if (Tok.
is(tok::equal) || isTokIdentifier_in()) {
330 return TPResult::True;
337 return TPResult::Ambiguous;
343 bool CanBeCondition =
true;
348 bool CanBeForRangeDecl)
349 : P(P), CanBeInitStatement(CanBeInitStatement),
350 CanBeForRangeDecl(CanBeForRangeDecl) {}
353 return CanBeExpression + CanBeCondition + CanBeInitStatement +
354 CanBeForRangeDecl < 2;
358 CanBeExpression =
false;
365 RevertingTentativeParsingAction PA(P);
366 if (CanBeForRangeDecl) {
370 unsigned QuestionColonDepth = 0;
371 P.
SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
373 if (P.Tok.
is(tok::question))
374 ++QuestionColonDepth;
375 else if (P.Tok.
is(tok::colon)) {
376 if (QuestionColonDepth)
377 --QuestionColonDepth;
379 CanBeCondition = CanBeInitStatement =
false;
383 CanBeForRangeDecl =
false;
392 if (P.Tok.
isNot(tok::r_paren))
393 CanBeCondition = CanBeForRangeDecl =
false;
394 if (P.Tok.
isNot(tok::semi))
395 CanBeInitStatement =
false;
400 CanBeCondition =
false;
405 CanBeForRangeDecl =
false;
413 assert(resolved() &&
"can't continue after tentative parsing bails out");
415 case TPResult::False:
416 CanBeCondition = CanBeInitStatement = CanBeForRangeDecl =
false;
418 case TPResult::Ambiguous:
420 case TPResult::Error:
421 CanBeExpression = CanBeCondition = CanBeInitStatement =
422 CanBeForRangeDecl =
false;
428 ConditionOrInitStatement
result()
const {
429 assert(CanBeExpression + CanBeCondition + CanBeInitStatement +
430 CanBeForRangeDecl < 2 &&
431 "result called but not yet resolved");
433 return ConditionOrInitStatement::Expression;
435 return ConditionOrInitStatement::ConditionDecl;
436 if (CanBeInitStatement)
437 return ConditionOrInitStatement::InitStmtDecl;
438 if (CanBeForRangeDecl)
439 return ConditionOrInitStatement::ForRangeDecl;
440 return ConditionOrInitStatement::Error;
461 Parser::ConditionOrInitStatement
462 Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement,
463 bool CanBeForRangeDecl) {
467 if (State.
update(isCXXDeclarationSpecifier()))
471 RevertingTentativeParsingAction PA(*
this);
474 if (State.
update(TryConsumeDeclarationSpecifier()))
476 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
480 if (State.
update(TryParseDeclarator(
false)))
486 if (Tok.
isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
494 return ConditionOrInitStatement::ForRangeDecl;
507 if (Tok.
is(tok::l_paren)) {
518 return ConditionOrInitStatement::ConditionDecl;
520 return ConditionOrInitStatement::InitStmtDecl;
522 return ConditionOrInitStatement::Expression;
542 bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context,
bool &isAmbiguous) {
553 TPResult TPR = isCXXDeclarationSpecifier();
554 if (TPR != TPResult::Ambiguous)
555 return TPR != TPResult::False;
564 RevertingTentativeParsingAction PA(*
this);
567 TryConsumeDeclarationSpecifier();
568 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
571 TPR = TryParseDeclarator(
true,
false);
574 if (TPR == TPResult::Error)
575 TPR = TPResult::True;
577 if (TPR == TPResult::Ambiguous) {
580 if (Context == TypeIdInParens && Tok.
is(tok::r_paren)) {
581 TPR = TPResult::True;
588 }
else if (Context == TypeIdAsTemplateArgument &&
589 (Tok.
isOneOf(tok::greater, tok::comma) ||
591 (Tok.
isOneOf(tok::greatergreater,
592 tok::greatergreatergreater) ||
593 (Tok.
is(tok::ellipsis) &&
595 tok::greatergreatergreater,
597 TPR = TPResult::True;
601 TPR = TPResult::False;
604 assert(TPR == TPResult::True || TPR == TPResult::False);
605 return TPR == TPResult::True;
641 Parser::CXX11AttributeKind
642 Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
643 bool OuterMightBeMessageSend) {
644 if (Tok.
is(tok::kw_alignas))
645 return CAK_AttributeSpecifier;
648 return CAK_NotAttributeSpecifier;
652 return CAK_AttributeSpecifier;
655 if (GetLookAheadToken(2).is(tok::kw_using))
656 return CAK_AttributeSpecifier;
658 RevertingTentativeParsingAction PA(*
this);
666 bool IsAttribute =
SkipUntil(tok::r_square);
667 IsAttribute &= Tok.
is(tok::r_square);
669 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
685 RevertingTentativeParsingAction LambdaTPA(*
this);
687 LambdaIntroducerTentativeParse Tentative;
688 if (ParseLambdaIntroducer(Intro, &Tentative)) {
692 return CAK_NotAttributeSpecifier;
696 case LambdaIntroducerTentativeParse::MessageSend:
699 return CAK_NotAttributeSpecifier;
701 case LambdaIntroducerTentativeParse::Success:
702 case LambdaIntroducerTentativeParse::Incomplete:
704 if (Tok.
is(tok::r_square))
706 return CAK_AttributeSpecifier;
708 if (OuterMightBeMessageSend)
710 return CAK_NotAttributeSpecifier;
713 return CAK_InvalidAttributeSpecifier;
715 case LambdaIntroducerTentativeParse::Invalid:
726 bool IsAttribute =
true;
727 while (Tok.
isNot(tok::r_square)) {
728 if (Tok.
is(tok::comma)) {
730 return CAK_AttributeSpecifier;
739 if (!TryParseCXX11AttributeIdentifier(Loc)) {
743 if (Tok.
is(tok::coloncolon)) {
745 if (!TryParseCXX11AttributeIdentifier(Loc)) {
752 if (Tok.
is(tok::l_paren)) {
768 if (Tok.
is(tok::r_square)) {
770 IsAttribute = Tok.
is(tok::r_square);
778 return CAK_AttributeSpecifier;
781 return CAK_NotAttributeSpecifier;
784 Parser::TPResult Parser::TryParsePtrOperatorSeq() {
787 return TPResult::Error;
789 if (Tok.
isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
790 (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
793 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
794 tok::kw__Nonnull, tok::kw__Nullable,
795 tok::kw__Null_unspecified))
798 return TPResult::True;
821 Parser::TPResult Parser::TryParseOperatorId() {
822 assert(Tok.
is(tok::kw_operator));
826 switch (Tok.getKind()) {
827 case tok::kw_new:
case tok::kw_delete:
829 if (Tok.
is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
833 return TPResult::True;
835 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \ 837 #define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly) 838 #include "clang/Basic/OperatorKinds.def" 840 return TPResult::True;
846 return TPResult::True;
854 return TPResult::True;
864 bool FoundUDSuffix =
false;
866 FoundUDSuffix |= Tok.hasUDSuffix();
867 ConsumeStringToken();
868 }
while (isTokenStringLiteral());
870 if (!FoundUDSuffix) {
871 if (Tok.
is(tok::identifier))
874 return TPResult::Error;
876 return TPResult::True;
880 bool AnyDeclSpecifiers =
false;
882 TPResult TPR = isCXXDeclarationSpecifier();
883 if (TPR == TPResult::Error)
885 if (TPR == TPResult::False) {
886 if (!AnyDeclSpecifiers)
887 return TPResult::Error;
890 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
891 return TPResult::Error;
892 AnyDeclSpecifiers =
true;
894 return TryParsePtrOperatorSeq();
950 Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
951 bool mayHaveIdentifier,
952 bool mayHaveDirectInit) {
956 if (TryParsePtrOperatorSeq() == TPResult::Error)
957 return TPResult::Error;
961 if (Tok.
is(tok::ellipsis))
964 if ((Tok.
isOneOf(tok::identifier, tok::kw_operator) ||
965 (Tok.
is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
969 if (Tok.
is(tok::annot_cxxscope))
970 ConsumeAnnotationToken();
971 else if (Tok.
is(tok::identifier))
972 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
973 if (Tok.
is(tok::kw_operator)) {
974 if (TryParseOperatorId() == TPResult::Error)
975 return TPResult::Error;
978 }
else if (Tok.
is(tok::l_paren)) {
981 (Tok.
is(tok::r_paren) ||
984 isDeclarationSpecifier())) {
987 TPResult TPR = TryParseFunctionDeclarator();
988 if (TPR != TPResult::Ambiguous)
994 if (Tok.
isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
995 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
996 tok::kw___regcall, tok::kw___vectorcall))
997 return TPResult::True;
998 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
999 if (TPR != TPResult::Ambiguous)
1001 if (Tok.
isNot(tok::r_paren))
1002 return TPResult::False;
1005 }
else if (!mayBeAbstract) {
1006 return TPResult::False;
1009 if (mayHaveDirectInit)
1010 return TPResult::Ambiguous;
1013 TPResult TPR(TPResult::Ambiguous);
1015 if (Tok.
is(tok::l_paren)) {
1020 if (!mayBeAbstract && !isCXXFunctionDeclarator())
1026 TPR = TryParseFunctionDeclarator();
1027 }
else if (Tok.
is(tok::l_square)) {
1030 TPR = TryParseBracketDeclarator();
1031 }
else if (Tok.
is(tok::kw_requires)) {
1034 TPR = TPResult::True;
1039 if (TPR != TPResult::Ambiguous)
1043 return TPResult::Ambiguous;
1050 case tok::numeric_constant:
1051 case tok::char_constant:
1052 case tok::wide_char_constant:
1053 case tok::utf8_char_constant:
1054 case tok::utf16_char_constant:
1055 case tok::utf32_char_constant:
1056 case tok::string_literal:
1057 case tok::wide_string_literal:
1058 case tok::utf8_string_literal:
1059 case tok::utf16_string_literal:
1060 case tok::utf32_string_literal:
1069 case tok::minusminus:
1072 case tok::kw_sizeof:
1073 case tok::kw___func__:
1074 case tok::kw_const_cast:
1075 case tok::kw_delete:
1076 case tok::kw_dynamic_cast:
1079 case tok::kw_operator:
1080 case tok::kw_reinterpret_cast:
1081 case tok::kw_static_cast:
1085 case tok::kw_typeid:
1086 case tok::kw_alignof:
1087 case tok::kw_noexcept:
1088 case tok::kw_nullptr:
1089 case tok::kw__Alignof:
1090 case tok::kw___null:
1091 case tok::kw___alignof:
1092 case tok::kw___builtin_choose_expr:
1093 case tok::kw___builtin_offsetof:
1094 case tok::kw___builtin_va_arg:
1095 case tok::kw___imag:
1096 case tok::kw___real:
1097 case tok::kw___FUNCTION__:
1098 case tok::kw___FUNCDNAME__:
1099 case tok::kw___FUNCSIG__:
1100 case tok::kw_L__FUNCTION__:
1101 case tok::kw_L__FUNCSIG__:
1102 case tok::kw___PRETTY_FUNCTION__:
1103 case tok::kw___uuidof:
1104 #define TYPE_TRAIT(N,Spelling,K) \ 1105 case tok::kw_##Spelling: 1106 #include "clang/Basic/TokenKinds.def" 1107 return TPResult::True;
1112 case tok::kw_double:
1113 case tok::kw__Float16:
1114 case tok::kw___float128:
1120 case tok::kw___int64:
1121 case tok::kw___int128:
1122 case tok::kw_restrict:
1124 case tok::kw_signed:
1125 case tok::kw_struct:
1127 case tok::kw_unsigned:
1129 case tok::kw_volatile:
1131 case tok::kw__Complex:
1133 case tok::kw_typename:
1134 case tok::kw_wchar_t:
1135 case tok::kw_char8_t:
1136 case tok::kw_char16_t:
1137 case tok::kw_char32_t:
1138 case tok::kw__Decimal32:
1139 case tok::kw__Decimal64:
1140 case tok::kw__Decimal128:
1141 case tok::kw___interface:
1142 case tok::kw___thread:
1143 case tok::kw_thread_local:
1144 case tok::kw__Thread_local:
1145 case tok::kw_typeof:
1146 case tok::kw___underlying_type:
1147 case tok::kw___cdecl:
1148 case tok::kw___stdcall:
1149 case tok::kw___fastcall:
1150 case tok::kw___thiscall:
1151 case tok::kw___regcall:
1152 case tok::kw___vectorcall:
1153 case tok::kw___unaligned:
1154 case tok::kw___vector:
1155 case tok::kw___pixel:
1156 case tok::kw___bool:
1157 case tok::kw__Atomic:
1158 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 1159 #include "clang/Basic/OpenCLImageTypes.def" 1160 case tok::kw___unknown_anytype:
1161 return TPResult::False;
1167 return TPResult::Ambiguous;
1171 return std::find(TentativelyDeclaredIdentifiers.begin(),
1172 TentativelyDeclaredIdentifiers.end(), II)
1173 != TentativelyDeclaredIdentifiers.end();
1179 TentativeParseCCC(
const Token &Next) {
1180 WantRemainingKeywords =
false;
1181 WantTypeSpecifiers = Next.
isOneOf(tok::l_paren, tok::r_paren, tok::greater,
1182 tok::l_brace, tok::identifier);
1185 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1189 llvm::all_of(Candidate,
1196 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
1197 return std::make_unique<TentativeParseCCC>(*this);
1314 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1315 bool *InvalidAsDeclSpec) {
1321 GetLookAheadToken(Lookahead + 1).isOneOf(tok::kw_auto, tok::kw_decltype,
1328 switch (Tok.getKind()) {
1329 case tok::identifier: {
1332 if (TryAltiVecVectorToken())
1333 return TPResult::True;
1338 return TPResult::True;
1340 if (Next.
isNot(tok::coloncolon) && Next.
isNot(tok::less)) {
1345 TentativeParseCCC CCC(Next);
1346 switch (TryAnnotateName(&CCC)) {
1348 return TPResult::Error;
1349 case ANK_TentativeDecl:
1350 return TPResult::False;
1351 case ANK_TemplateName:
1358 return TPResult::Error;
1359 if (Tok.
isNot(tok::identifier))
1365 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1366 case ANK_Unresolved:
1367 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1371 assert(Tok.
isNot(tok::identifier) &&
1372 "TryAnnotateName succeeded without producing an annotation");
1379 return TPResult::Error;
1383 if (Tok.
is(tok::identifier))
1384 return TPResult::False;
1388 return isCXXDeclarationSpecifier(BracedCastResult, InvalidAsDeclSpec);
1391 case tok::kw_typename:
1395 return TPResult::Error;
1396 return isCXXDeclarationSpecifier(BracedCastResult, InvalidAsDeclSpec);
1398 case tok::coloncolon: {
1402 return TPResult::False;
1405 case tok::kw___super:
1406 case tok::kw_decltype:
1410 return TPResult::Error;
1411 return isCXXDeclarationSpecifier(BracedCastResult, InvalidAsDeclSpec);
1420 case tok::kw_friend:
1421 case tok::kw_typedef:
1422 case tok::kw_constexpr:
1423 case tok::kw_consteval:
1424 case tok::kw_constinit:
1426 case tok::kw_register:
1427 case tok::kw_static:
1428 case tok::kw_extern:
1429 case tok::kw_mutable:
1431 case tok::kw___thread:
1432 case tok::kw_thread_local:
1433 case tok::kw__Thread_local:
1435 case tok::kw_inline:
1436 case tok::kw_virtual:
1437 case tok::kw_explicit:
1440 case tok::kw___module_private__:
1443 case tok::kw___unknown_anytype:
1456 case tok::kw_struct:
1458 case tok::kw___interface:
1463 case tok::kw_volatile:
1464 return TPResult::True;
1467 case tok::kw_private:
1469 return TPResult::False;
1471 case tok::kw___private:
1472 case tok::kw___local:
1473 case tok::kw___global:
1474 case tok::kw___constant:
1475 case tok::kw___generic:
1477 case tok::kw___read_only:
1478 case tok::kw___write_only:
1479 case tok::kw___read_write:
1484 case tok::kw_restrict:
1485 case tok::kw__Complex:
1486 case tok::kw___attribute:
1487 case tok::kw___auto_type:
1488 return TPResult::True;
1491 case tok::kw___declspec:
1492 case tok::kw___cdecl:
1493 case tok::kw___stdcall:
1494 case tok::kw___fastcall:
1495 case tok::kw___thiscall:
1496 case tok::kw___regcall:
1497 case tok::kw___vectorcall:
1499 case tok::kw___sptr:
1500 case tok::kw___uptr:
1501 case tok::kw___ptr64:
1502 case tok::kw___ptr32:
1503 case tok::kw___forceinline:
1504 case tok::kw___unaligned:
1505 case tok::kw__Nonnull:
1506 case tok::kw__Nullable:
1507 case tok::kw__Null_unspecified:
1508 case tok::kw___kindof:
1509 return TPResult::True;
1512 case tok::kw___pascal:
1513 return TPResult::True;
1516 case tok::kw___vector:
1517 return TPResult::True;
1519 case tok::annot_template_id: {
1528 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1529 return TPResult::Ambiguous;
1531 if (IsPlaceholderSpecifier(TemplateId, 0))
1532 return TPResult::True;
1534 return TPResult::False;
1536 AnnotateTemplateIdTokenAsType(SS);
1537 assert(Tok.
is(tok::annot_typename));
1541 case tok::annot_cxxscope:
1544 return TPResult::Error;
1545 if (!Tok.
is(tok::annot_typename)) {
1546 if (Tok.
is(tok::annot_cxxscope) &&
1550 if (IsPlaceholderSpecifier(TemplateId, 1))
1551 return TPResult::True;
1555 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1557 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1558 Tok.getAnnotationRange(),
1561 RevertingTentativeParsingAction PA(*
this);
1562 ConsumeAnnotationToken();
1564 bool isIdentifier = Tok.
is(tok::identifier);
1565 TPResult TPR = TPResult::False;
1567 TPR = isCXXDeclarationSpecifier(BracedCastResult,
1571 TPR == TPResult::True || TPR == TPResult::Error)
1572 return TPResult::Error;
1574 if (InvalidAsDeclSpec) {
1577 *InvalidAsDeclSpec =
true;
1578 return TPResult::Ambiguous;
1584 if (((Tok.
is(tok::amp) || Tok.
is(tok::star)) &&
1588 return TPResult::True;
1594 switch (TryAnnotateName()) {
1596 return TPResult::Error;
1597 case ANK_TentativeDecl:
1598 return TPResult::False;
1599 case ANK_TemplateName:
1604 return TPResult::Error;
1605 if (Tok.
isNot(tok::identifier))
1612 return (
getLangOpts().CPlusPlus17 || GreaterThanIsOperator)
1615 case ANK_Unresolved:
1616 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1622 assert(Tok.
isNot(tok::annot_cxxscope) ||
1624 return isCXXDeclarationSpecifier(BracedCastResult, InvalidAsDeclSpec);
1627 return TPResult::False;
1650 case tok::annot_typename:
1655 RevertingTentativeParsingAction PA(*
this);
1658 TPResult TPR = TryParseProtocolQualifiers();
1659 bool isFollowedByParen = Tok.
is(tok::l_paren);
1660 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1662 if (TPR == TPResult::Error)
1663 return TPResult::Error;
1665 if (isFollowedByParen)
1666 return TPResult::Ambiguous;
1669 return BracedCastResult;
1671 return TPResult::True;
1676 case tok::kw_wchar_t:
1677 case tok::kw_char8_t:
1678 case tok::kw_char16_t:
1679 case tok::kw_char32_t:
1684 case tok::kw___int64:
1685 case tok::kw___int128:
1686 case tok::kw_signed:
1687 case tok::kw_unsigned:
1690 case tok::kw_double:
1691 case tok::kw__Float16:
1692 case tok::kw___float128:
1694 case tok::annot_decltype:
1695 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 1696 #include "clang/Basic/OpenCLImageTypes.def" 1698 return TPResult::Ambiguous;
1707 return BracedCastResult;
1709 if (isStartOfObjCClassMessageMissingOpenBracket())
1710 return TPResult::False;
1712 return TPResult::True;
1715 case tok::kw_typeof: {
1717 return TPResult::True;
1719 RevertingTentativeParsingAction PA(*
this);
1721 TPResult TPR = TryParseTypeofSpecifier();
1722 bool isFollowedByParen = Tok.
is(tok::l_paren);
1723 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1725 if (TPR == TPResult::Error)
1726 return TPResult::Error;
1728 if (isFollowedByParen)
1729 return TPResult::Ambiguous;
1732 return BracedCastResult;
1734 return TPResult::True;
1738 case tok::kw___underlying_type:
1739 return TPResult::True;
1742 case tok::kw__Atomic:
1743 return TPResult::True;
1746 return TPResult::False;
1750 bool Parser::isCXXDeclarationSpecifierAType() {
1751 switch (Tok.getKind()) {
1753 case tok::annot_decltype:
1754 case tok::annot_template_id:
1755 case tok::annot_typename:
1756 case tok::kw_typeof:
1757 case tok::kw___underlying_type:
1762 case tok::kw_struct:
1764 case tok::kw___interface:
1770 case tok::kw_wchar_t:
1771 case tok::kw_char8_t:
1772 case tok::kw_char16_t:
1773 case tok::kw_char32_t:
1778 case tok::kw___int64:
1779 case tok::kw___int128:
1780 case tok::kw_signed:
1781 case tok::kw_unsigned:
1784 case tok::kw_double:
1785 case tok::kw__Float16:
1786 case tok::kw___float128:
1788 case tok::kw___unknown_anytype:
1789 case tok::kw___auto_type:
1790 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 1791 #include "clang/Basic/OpenCLImageTypes.def" 1797 case tok::kw__Atomic:
1810 Parser::TPResult Parser::TryParseTypeofSpecifier() {
1811 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1814 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1818 return TPResult::Error;
1820 return TPResult::Ambiguous;
1825 Parser::TPResult Parser::TryParseProtocolQualifiers() {
1826 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1829 if (Tok.
isNot(tok::identifier))
1830 return TPResult::Error;
1833 if (Tok.
is(tok::comma)) {
1838 if (Tok.
is(tok::greater)) {
1840 return TPResult::Ambiguous;
1844 return TPResult::Error;
1857 bool Parser::isCXXFunctionDeclarator(
bool *IsAmbiguous) {
1868 RevertingTentativeParsingAction PA(*
this);
1871 bool InvalidAsDeclaration =
false;
1872 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
1873 if (TPR == TPResult::Ambiguous) {
1874 if (Tok.
isNot(tok::r_paren))
1875 TPR = TPResult::False;
1878 if (Next.
isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1879 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1880 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1881 isCXX11VirtSpecifier(Next))
1885 TPR = TPResult::True;
1886 else if (InvalidAsDeclaration)
1888 TPR = TPResult::False;
1892 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1893 *IsAmbiguous =
true;
1896 return TPR != TPResult::False;
1917 Parser::TryParseParameterDeclarationClause(
bool *InvalidAsDeclaration,
1918 bool VersusTemplateArgument) {
1920 if (Tok.
is(tok::r_paren))
1921 return TPResult::Ambiguous;
1932 if (Tok.
is(tok::ellipsis)) {
1934 if (Tok.
is(tok::r_paren))
1935 return TPResult::True;
1937 return TPResult::False;
1941 if (isCXX11AttributeSpecifier(
false,
1943 return TPResult::True;
1946 MaybeParseMicrosoftAttributes(attrs);
1951 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
1952 InvalidAsDeclaration);
1955 if (TPR != TPResult::Ambiguous &&
1956 !(VersusTemplateArgument && TPR == TPResult::True))
1959 bool SeenType =
false;
1961 SeenType |= isCXXDeclarationSpecifierAType();
1962 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1963 return TPResult::Error;
1966 if (SeenType && Tok.
is(tok::identifier))
1967 return TPResult::True;
1969 TPR = isCXXDeclarationSpecifier(TPResult::False,
1970 InvalidAsDeclaration);
1971 if (TPR == TPResult::Error)
1975 if (TPR == TPResult::True && !VersusTemplateArgument)
1977 }
while (TPR != TPResult::False);
1981 TPR = TryParseDeclarator(
true);
1982 if (TPR != TPResult::Ambiguous)
1986 if (Tok.
is(tok::kw___attribute))
1987 return TPResult::True;
1999 if (VersusTemplateArgument)
2000 return Tok.
isOneOf(tok::equal, tok::r_paren) ? TPResult::True
2003 if (Tok.
is(tok::equal)) {
2008 return TPResult::Error;
2011 if (Tok.
is(tok::ellipsis)) {
2013 if (Tok.
is(tok::r_paren))
2014 return TPResult::True;
2016 return TPResult::False;
2023 return TPResult::Ambiguous;
2038 Parser::TPResult Parser::TryParseFunctionDeclarator() {
2041 TPResult TPR = TryParseParameterDeclarationClause();
2042 if (TPR == TPResult::Ambiguous && Tok.
isNot(tok::r_paren))
2043 TPR = TPResult::False;
2045 if (TPR == TPResult::False || TPR == TPResult::Error)
2050 return TPResult::Error;
2053 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
2058 if (Tok.
isOneOf(tok::amp, tok::ampamp))
2062 if (Tok.
is(tok::kw_throw)) {
2064 if (Tok.
isNot(tok::l_paren))
2065 return TPResult::Error;
2070 return TPResult::Error;
2072 if (Tok.
is(tok::kw_noexcept)) {
2075 if (Tok.
is(tok::l_paren)) {
2079 return TPResult::Error;
2083 return TPResult::Ambiguous;
2088 Parser::TPResult Parser::TryParseBracketDeclarator() {
2093 if (Tok.
is(tok::l_brace))
2094 return TPResult::False;
2097 return TPResult::Error;
2101 if (Tok.
isNot(tok::r_square))
2102 return TPResult::False;
2105 return TPResult::Ambiguous;
2112 Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
2113 if (!TokensToSkip) {
2114 if (Tok.
isNot(tok::less))
2115 return TPResult::False;
2117 return TPResult::True;
2120 RevertingTentativeParsingAction PA(*
this);
2122 while (TokensToSkip) {
2128 return TPResult::False;
2133 bool InvalidAsTemplateArgumentList =
false;
2134 if (isCXXDeclarationSpecifier(TPResult::False,
2135 &InvalidAsTemplateArgumentList) ==
2137 return TPResult::True;
2138 if (InvalidAsTemplateArgumentList)
2139 return TPResult::False;
2153 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2155 return TPResult::Ambiguous;
2156 return TPResult::False;
2161 Parser::TPResult Parser::isExplicitBool() {
2162 assert(Tok.
is(tok::l_paren) &&
"expected to be looking at a '(' token");
2164 RevertingTentativeParsingAction PA(*
this);
2172 while (Tok.
is(tok::l_paren))
2176 return TPResult::Error;
2181 if (Tok.
is(tok::annot_cxxscope)) {
2182 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2183 Tok.getAnnotationRange(),
2185 ConsumeAnnotationToken();
2190 if (Tok.
is(tok::kw_operator))
2191 return TPResult::Ambiguous;
2194 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::annot_template_id))
2195 return TPResult::True;
2196 if (!Actions.isCurrentClassName(Tok.
is(tok::identifier)
2197 ? *Tok.getIdentifierInfo()
2198 : *takeTemplateIdAnnotation(Tok)->Name,
2200 return TPResult::True;
2206 !isConstructorDeclarator(SS.
isEmpty(),
2208 return TPResult::True;
2211 return TPResult::Ambiguous;
Simple class containing the result of Sema::CorrectTypo.
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)) {...
bool isEmpty() const
No scope specifier.
ConditionOrInitStatement result() const
TemplateNameKind Kind
The kind of template that Template refers to.
Parser - This implements a parser for the C family of languages.
tok::TokenKind getKind() 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 ...
Information about a template-id annotation token.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
bool TryConsumeToken(tok::TokenKind Expected)
One of these records is kept for each identifier that is lexed.
Lookup for the name failed, but we're assuming it was a template name anyway.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
Token - This structure provides full information about a lexed token.
ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement, bool CanBeForRangeDecl)
Represents a C++ nested-name-specifier or a global scope specifier.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type...
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
The name refers to a concept.
const LangOptions & getLangOpts() const
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
Stop skipping at semicolon.
Encodes a location in the source.
bool TryAnnotateTypeOrScopeToken()
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
bool update(TPResult IsDecl)
bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext=false)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Scope * getCurScope() const
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
The name refers to a template whose specialization produces a type.
bool markNotForRangeDecl()
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Represents a complete lambda introducer.
This represents a decl that may have a name.
ParsedAttributes - A collection of parsed attributes.
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
Stop skipping at specified token, but don't skip the token itself.