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;
205 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
206 tok::annot_template_id) &&
208 return TPResult::Error;
209 if (Tok.
is(tok::annot_cxxscope))
210 ConsumeAnnotationToken();
211 if (Tok.
is(tok::identifier))
213 else if (Tok.
is(tok::annot_template_id))
214 ConsumeAnnotationToken();
216 return TPResult::Error;
219 case tok::annot_cxxscope:
220 ConsumeAnnotationToken();
226 return TryParseProtocolQualifiers();
230 return TPResult::Ambiguous;
241 Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
242 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
243 return TPResult::Error;
248 if (Tok.
isNot(tok::l_paren)) {
249 TPResult TPR = isCXXDeclarationSpecifier();
250 if (TPR == TPResult::Ambiguous)
251 return TPResult::True;
252 if (TPR == TPResult::True || TPR == TPResult::Error)
254 assert(TPR == TPResult::False);
257 TPResult TPR = TryParseInitDeclaratorList();
258 if (TPR != TPResult::Ambiguous)
261 if (Tok.
isNot(tok::semi) && (!AllowForRangeDecl || Tok.
isNot(tok::colon)))
262 return TPResult::False;
264 return TPResult::Ambiguous;
294 Parser::TPResult Parser::TryParseInitDeclaratorList() {
297 TPResult TPR = TryParseDeclarator(
false);
298 if (TPR != TPResult::Ambiguous)
302 if (Tok.
isOneOf(tok::kw_asm, tok::kw___attribute))
303 return TPResult::True;
306 if (Tok.
is(tok::l_paren)) {
310 return TPResult::Error;
311 }
else if (Tok.
is(tok::l_brace)) {
314 return TPResult::True;
315 }
else if (Tok.
is(tok::equal) || isTokIdentifier_in()) {
332 return TPResult::True;
339 return TPResult::Ambiguous;
345 bool CanBeCondition =
true;
350 bool CanBeForRangeDecl)
351 : P(P), CanBeInitStatement(CanBeInitStatement),
352 CanBeForRangeDecl(CanBeForRangeDecl) {}
355 return CanBeExpression + CanBeCondition + CanBeInitStatement +
356 CanBeForRangeDecl < 2;
360 CanBeExpression =
false;
367 RevertingTentativeParsingAction PA(P);
368 if (CanBeForRangeDecl) {
372 unsigned QuestionColonDepth = 0;
373 P.
SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
375 if (P.Tok.
is(tok::question))
376 ++QuestionColonDepth;
377 else if (P.Tok.
is(tok::colon)) {
378 if (QuestionColonDepth)
379 --QuestionColonDepth;
381 CanBeCondition = CanBeInitStatement =
false;
385 CanBeForRangeDecl =
false;
394 if (P.Tok.
isNot(tok::r_paren))
395 CanBeCondition = CanBeForRangeDecl =
false;
396 if (P.Tok.
isNot(tok::semi))
397 CanBeInitStatement =
false;
402 CanBeCondition =
false;
407 CanBeForRangeDecl =
false;
415 assert(resolved() &&
"can't continue after tentative parsing bails out");
417 case TPResult::False:
418 CanBeCondition = CanBeInitStatement = CanBeForRangeDecl =
false;
420 case TPResult::Ambiguous:
422 case TPResult::Error:
423 CanBeExpression = CanBeCondition = CanBeInitStatement =
424 CanBeForRangeDecl =
false;
430 ConditionOrInitStatement
result()
const {
431 assert(CanBeExpression + CanBeCondition + CanBeInitStatement +
432 CanBeForRangeDecl < 2 &&
433 "result called but not yet resolved");
435 return ConditionOrInitStatement::Expression;
437 return ConditionOrInitStatement::ConditionDecl;
438 if (CanBeInitStatement)
439 return ConditionOrInitStatement::InitStmtDecl;
440 if (CanBeForRangeDecl)
441 return ConditionOrInitStatement::ForRangeDecl;
442 return ConditionOrInitStatement::Error;
463 Parser::ConditionOrInitStatement
464 Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement,
465 bool CanBeForRangeDecl) {
469 if (State.
update(isCXXDeclarationSpecifier()))
473 RevertingTentativeParsingAction PA(*
this);
476 if (State.
update(TryConsumeDeclarationSpecifier()))
478 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
482 if (State.
update(TryParseDeclarator(
false)))
488 if (Tok.
isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
496 return ConditionOrInitStatement::ForRangeDecl;
509 if (Tok.
is(tok::l_paren)) {
520 return ConditionOrInitStatement::ConditionDecl;
522 return ConditionOrInitStatement::InitStmtDecl;
524 return ConditionOrInitStatement::Expression;
544 bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context,
bool &isAmbiguous) {
555 TPResult TPR = isCXXDeclarationSpecifier();
556 if (TPR != TPResult::Ambiguous)
557 return TPR != TPResult::False;
566 RevertingTentativeParsingAction PA(*
this);
569 TryConsumeDeclarationSpecifier();
570 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
573 TPR = TryParseDeclarator(
true,
false);
576 if (TPR == TPResult::Error)
577 TPR = TPResult::True;
579 if (TPR == TPResult::Ambiguous) {
582 if (Context == TypeIdInParens && Tok.
is(tok::r_paren)) {
583 TPR = TPResult::True;
590 }
else if (Context == TypeIdAsTemplateArgument &&
591 (Tok.
isOneOf(tok::greater, tok::comma) ||
593 (Tok.
isOneOf(tok::greatergreater,
594 tok::greatergreatergreater) ||
595 (Tok.
is(tok::ellipsis) &&
597 tok::greatergreatergreater,
599 TPR = TPResult::True;
603 TPR = TPResult::False;
606 assert(TPR == TPResult::True || TPR == TPResult::False);
607 return TPR == TPResult::True;
643 Parser::CXX11AttributeKind
644 Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
645 bool OuterMightBeMessageSend) {
646 if (Tok.
is(tok::kw_alignas))
647 return CAK_AttributeSpecifier;
650 return CAK_NotAttributeSpecifier;
654 return CAK_AttributeSpecifier;
657 if (GetLookAheadToken(2).is(tok::kw_using))
658 return CAK_AttributeSpecifier;
660 RevertingTentativeParsingAction PA(*
this);
668 bool IsAttribute =
SkipUntil(tok::r_square);
669 IsAttribute &= Tok.
is(tok::r_square);
671 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
687 RevertingTentativeParsingAction LambdaTPA(*
this);
689 LambdaIntroducerTentativeParse Tentative;
690 if (ParseLambdaIntroducer(Intro, &Tentative)) {
694 return CAK_NotAttributeSpecifier;
698 case LambdaIntroducerTentativeParse::MessageSend:
701 return CAK_NotAttributeSpecifier;
703 case LambdaIntroducerTentativeParse::Success:
704 case LambdaIntroducerTentativeParse::Incomplete:
706 if (Tok.
is(tok::r_square))
708 return CAK_AttributeSpecifier;
710 if (OuterMightBeMessageSend)
712 return CAK_NotAttributeSpecifier;
715 return CAK_InvalidAttributeSpecifier;
717 case LambdaIntroducerTentativeParse::Invalid:
728 bool IsAttribute =
true;
729 while (Tok.
isNot(tok::r_square)) {
730 if (Tok.
is(tok::comma)) {
732 return CAK_AttributeSpecifier;
741 if (!TryParseCXX11AttributeIdentifier(Loc)) {
745 if (Tok.
is(tok::coloncolon)) {
747 if (!TryParseCXX11AttributeIdentifier(Loc)) {
754 if (Tok.
is(tok::l_paren)) {
770 if (Tok.
is(tok::r_square)) {
772 IsAttribute = Tok.
is(tok::r_square);
780 return CAK_AttributeSpecifier;
783 return CAK_NotAttributeSpecifier;
786 Parser::TPResult Parser::TryParsePtrOperatorSeq() {
788 if (Tok.
isOneOf(tok::coloncolon, tok::identifier))
790 return TPResult::Error;
792 if (Tok.
isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
793 (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
796 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
797 tok::kw__Nonnull, tok::kw__Nullable,
798 tok::kw__Null_unspecified))
801 return TPResult::True;
824 Parser::TPResult Parser::TryParseOperatorId() {
825 assert(Tok.
is(tok::kw_operator));
829 switch (Tok.getKind()) {
830 case tok::kw_new:
case tok::kw_delete:
832 if (Tok.
is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
836 return TPResult::True;
838 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \ 840 #define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly) 841 #include "clang/Basic/OperatorKinds.def" 843 return TPResult::True;
849 return TPResult::True;
857 return TPResult::True;
867 bool FoundUDSuffix =
false;
869 FoundUDSuffix |= Tok.hasUDSuffix();
870 ConsumeStringToken();
871 }
while (isTokenStringLiteral());
873 if (!FoundUDSuffix) {
874 if (Tok.
is(tok::identifier))
877 return TPResult::Error;
879 return TPResult::True;
883 bool AnyDeclSpecifiers =
false;
885 TPResult TPR = isCXXDeclarationSpecifier();
886 if (TPR == TPResult::Error)
888 if (TPR == TPResult::False) {
889 if (!AnyDeclSpecifiers)
890 return TPResult::Error;
893 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
894 return TPResult::Error;
895 AnyDeclSpecifiers =
true;
897 return TryParsePtrOperatorSeq();
953 Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
954 bool mayHaveIdentifier,
955 bool mayHaveDirectInit) {
959 if (TryParsePtrOperatorSeq() == TPResult::Error)
960 return TPResult::Error;
964 if (Tok.
is(tok::ellipsis))
967 if ((Tok.
isOneOf(tok::identifier, tok::kw_operator) ||
968 (Tok.
is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
972 if (Tok.
is(tok::annot_cxxscope))
973 ConsumeAnnotationToken();
974 else if (Tok.
is(tok::identifier))
975 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
976 if (Tok.
is(tok::kw_operator)) {
977 if (TryParseOperatorId() == TPResult::Error)
978 return TPResult::Error;
981 }
else if (Tok.
is(tok::l_paren)) {
984 (Tok.
is(tok::r_paren) ||
987 isDeclarationSpecifier())) {
990 TPResult TPR = TryParseFunctionDeclarator();
991 if (TPR != TPResult::Ambiguous)
997 if (Tok.
isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
998 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
999 tok::kw___regcall, tok::kw___vectorcall))
1000 return TPResult::True;
1001 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
1002 if (TPR != TPResult::Ambiguous)
1004 if (Tok.
isNot(tok::r_paren))
1005 return TPResult::False;
1008 }
else if (!mayBeAbstract) {
1009 return TPResult::False;
1012 if (mayHaveDirectInit)
1013 return TPResult::Ambiguous;
1016 TPResult TPR(TPResult::Ambiguous);
1018 if (Tok.
is(tok::l_paren)) {
1023 if (!mayBeAbstract && !isCXXFunctionDeclarator())
1029 TPR = TryParseFunctionDeclarator();
1030 }
else if (Tok.
is(tok::l_square)) {
1033 TPR = TryParseBracketDeclarator();
1038 if (TPR != TPResult::Ambiguous)
1042 return TPResult::Ambiguous;
1049 case tok::numeric_constant:
1050 case tok::char_constant:
1051 case tok::wide_char_constant:
1052 case tok::utf8_char_constant:
1053 case tok::utf16_char_constant:
1054 case tok::utf32_char_constant:
1055 case tok::string_literal:
1056 case tok::wide_string_literal:
1057 case tok::utf8_string_literal:
1058 case tok::utf16_string_literal:
1059 case tok::utf32_string_literal:
1068 case tok::minusminus:
1071 case tok::kw_sizeof:
1072 case tok::kw___func__:
1073 case tok::kw_const_cast:
1074 case tok::kw_delete:
1075 case tok::kw_dynamic_cast:
1078 case tok::kw_operator:
1079 case tok::kw_reinterpret_cast:
1080 case tok::kw_static_cast:
1084 case tok::kw_typeid:
1085 case tok::kw_alignof:
1086 case tok::kw_noexcept:
1087 case tok::kw_nullptr:
1088 case tok::kw__Alignof:
1089 case tok::kw___null:
1090 case tok::kw___alignof:
1091 case tok::kw___builtin_choose_expr:
1092 case tok::kw___builtin_offsetof:
1093 case tok::kw___builtin_va_arg:
1094 case tok::kw___imag:
1095 case tok::kw___real:
1096 case tok::kw___FUNCTION__:
1097 case tok::kw___FUNCDNAME__:
1098 case tok::kw___FUNCSIG__:
1099 case tok::kw_L__FUNCTION__:
1100 case tok::kw_L__FUNCSIG__:
1101 case tok::kw___PRETTY_FUNCTION__:
1102 case tok::kw___uuidof:
1103 #define TYPE_TRAIT(N,Spelling,K) \ 1104 case tok::kw_##Spelling: 1105 #include "clang/Basic/TokenKinds.def" 1106 return TPResult::True;
1111 case tok::kw_double:
1112 case tok::kw__Float16:
1113 case tok::kw___float128:
1119 case tok::kw___int64:
1120 case tok::kw___int128:
1121 case tok::kw_restrict:
1123 case tok::kw_signed:
1124 case tok::kw_struct:
1126 case tok::kw_unsigned:
1128 case tok::kw_volatile:
1130 case tok::kw__Complex:
1132 case tok::kw_typename:
1133 case tok::kw_wchar_t:
1134 case tok::kw_char8_t:
1135 case tok::kw_char16_t:
1136 case tok::kw_char32_t:
1137 case tok::kw__Decimal32:
1138 case tok::kw__Decimal64:
1139 case tok::kw__Decimal128:
1140 case tok::kw___interface:
1141 case tok::kw___thread:
1142 case tok::kw_thread_local:
1143 case tok::kw__Thread_local:
1144 case tok::kw_typeof:
1145 case tok::kw___underlying_type:
1146 case tok::kw___cdecl:
1147 case tok::kw___stdcall:
1148 case tok::kw___fastcall:
1149 case tok::kw___thiscall:
1150 case tok::kw___regcall:
1151 case tok::kw___vectorcall:
1152 case tok::kw___unaligned:
1153 case tok::kw___vector:
1154 case tok::kw___pixel:
1155 case tok::kw___bool:
1156 case tok::kw__Atomic:
1157 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 1158 #include "clang/Basic/OpenCLImageTypes.def" 1159 case tok::kw___unknown_anytype:
1160 return TPResult::False;
1166 return TPResult::Ambiguous;
1170 return std::find(TentativelyDeclaredIdentifiers.begin(),
1171 TentativelyDeclaredIdentifiers.end(), II)
1172 != TentativelyDeclaredIdentifiers.end();
1178 TentativeParseCCC(
const Token &Next) {
1179 WantRemainingKeywords =
false;
1180 WantTypeSpecifiers = Next.
isOneOf(tok::l_paren, tok::r_paren, tok::greater,
1181 tok::l_brace, tok::identifier);
1184 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1188 llvm::all_of(Candidate,
1195 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
1196 return llvm::make_unique<TentativeParseCCC>(*this);
1313 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1314 bool *InvalidAsDeclSpec) {
1315 switch (Tok.getKind()) {
1316 case tok::identifier: {
1319 if (TryAltiVecVectorToken())
1320 return TPResult::True;
1325 return TPResult::True;
1327 if (Next.
isNot(tok::coloncolon) && Next.
isNot(tok::less)) {
1332 TentativeParseCCC CCC(Next);
1333 switch (TryAnnotateName(
false , &CCC)) {
1335 return TPResult::Error;
1336 case ANK_TentativeDecl:
1337 return TPResult::False;
1338 case ANK_TemplateName:
1345 return TPResult::Error;
1346 if (Tok.
isNot(tok::identifier))
1352 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1353 case ANK_Unresolved:
1354 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1358 assert(Tok.
isNot(tok::identifier) &&
1359 "TryAnnotateName succeeded without producing an annotation");
1366 return TPResult::Error;
1370 if (Tok.
is(tok::identifier))
1371 return TPResult::False;
1375 return isCXXDeclarationSpecifier(BracedCastResult, InvalidAsDeclSpec);
1378 case tok::kw_typename:
1382 return TPResult::Error;
1383 return isCXXDeclarationSpecifier(BracedCastResult, InvalidAsDeclSpec);
1385 case tok::coloncolon: {
1389 return TPResult::False;
1392 case tok::kw___super:
1393 case tok::kw_decltype:
1397 return TPResult::Error;
1398 return isCXXDeclarationSpecifier(BracedCastResult, InvalidAsDeclSpec);
1407 case tok::kw_friend:
1408 case tok::kw_typedef:
1409 case tok::kw_constexpr:
1410 case tok::kw_consteval:
1412 case tok::kw_register:
1413 case tok::kw_static:
1414 case tok::kw_extern:
1415 case tok::kw_mutable:
1417 case tok::kw___thread:
1418 case tok::kw_thread_local:
1419 case tok::kw__Thread_local:
1421 case tok::kw_inline:
1422 case tok::kw_virtual:
1423 case tok::kw_explicit:
1426 case tok::kw___module_private__:
1429 case tok::kw___unknown_anytype:
1442 case tok::kw_struct:
1444 case tok::kw___interface:
1449 case tok::kw_volatile:
1450 return TPResult::True;
1453 case tok::kw_private:
1455 return TPResult::False;
1457 case tok::kw___private:
1458 case tok::kw___local:
1459 case tok::kw___global:
1460 case tok::kw___constant:
1461 case tok::kw___generic:
1463 case tok::kw___read_only:
1464 case tok::kw___write_only:
1465 case tok::kw___read_write:
1470 case tok::kw_restrict:
1471 case tok::kw__Complex:
1472 case tok::kw___attribute:
1473 case tok::kw___auto_type:
1474 return TPResult::True;
1477 case tok::kw___declspec:
1478 case tok::kw___cdecl:
1479 case tok::kw___stdcall:
1480 case tok::kw___fastcall:
1481 case tok::kw___thiscall:
1482 case tok::kw___regcall:
1483 case tok::kw___vectorcall:
1485 case tok::kw___sptr:
1486 case tok::kw___uptr:
1487 case tok::kw___ptr64:
1488 case tok::kw___ptr32:
1489 case tok::kw___forceinline:
1490 case tok::kw___unaligned:
1491 case tok::kw__Nonnull:
1492 case tok::kw__Nullable:
1493 case tok::kw__Null_unspecified:
1494 case tok::kw___kindof:
1495 return TPResult::True;
1498 case tok::kw___pascal:
1499 return TPResult::True;
1502 case tok::kw___vector:
1503 return TPResult::True;
1505 case tok::annot_template_id: {
1514 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1515 return TPResult::Ambiguous;
1518 return TPResult::False;
1520 AnnotateTemplateIdTokenAsType();
1521 assert(Tok.
is(tok::annot_typename));
1525 case tok::annot_cxxscope:
1528 return TPResult::Error;
1529 if (!Tok.
is(tok::annot_typename)) {
1532 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1534 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1535 Tok.getAnnotationRange(),
1538 RevertingTentativeParsingAction PA(*
this);
1539 ConsumeAnnotationToken();
1541 bool isIdentifier = Tok.
is(tok::identifier);
1542 TPResult TPR = TPResult::False;
1544 TPR = isCXXDeclarationSpecifier(BracedCastResult,
1548 TPR == TPResult::True || TPR == TPResult::Error)
1549 return TPResult::Error;
1551 if (InvalidAsDeclSpec) {
1554 *InvalidAsDeclSpec =
true;
1555 return TPResult::Ambiguous;
1561 if (((Tok.
is(tok::amp) || Tok.
is(tok::star)) &&
1565 return TPResult::True;
1571 switch (TryAnnotateName(
false )) {
1573 return TPResult::Error;
1574 case ANK_TentativeDecl:
1575 return TPResult::False;
1576 case ANK_TemplateName:
1581 return TPResult::Error;
1582 if (Tok.
isNot(tok::identifier))
1589 return (
getLangOpts().CPlusPlus17 || GreaterThanIsOperator)
1592 case ANK_Unresolved:
1593 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1599 assert(Tok.
isNot(tok::annot_cxxscope) ||
1601 return isCXXDeclarationSpecifier(BracedCastResult, InvalidAsDeclSpec);
1604 return TPResult::False;
1627 case tok::annot_typename:
1632 RevertingTentativeParsingAction PA(*
this);
1635 TPResult TPR = TryParseProtocolQualifiers();
1636 bool isFollowedByParen = Tok.
is(tok::l_paren);
1637 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1639 if (TPR == TPResult::Error)
1640 return TPResult::Error;
1642 if (isFollowedByParen)
1643 return TPResult::Ambiguous;
1646 return BracedCastResult;
1648 return TPResult::True;
1653 case tok::kw_wchar_t:
1654 case tok::kw_char8_t:
1655 case tok::kw_char16_t:
1656 case tok::kw_char32_t:
1661 case tok::kw___int64:
1662 case tok::kw___int128:
1663 case tok::kw_signed:
1664 case tok::kw_unsigned:
1667 case tok::kw_double:
1668 case tok::kw__Float16:
1669 case tok::kw___float128:
1671 case tok::annot_decltype:
1672 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 1673 #include "clang/Basic/OpenCLImageTypes.def" 1675 return TPResult::Ambiguous;
1684 return BracedCastResult;
1686 if (isStartOfObjCClassMessageMissingOpenBracket())
1687 return TPResult::False;
1689 return TPResult::True;
1692 case tok::kw_typeof: {
1694 return TPResult::True;
1696 RevertingTentativeParsingAction PA(*
this);
1698 TPResult TPR = TryParseTypeofSpecifier();
1699 bool isFollowedByParen = Tok.
is(tok::l_paren);
1700 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1702 if (TPR == TPResult::Error)
1703 return TPResult::Error;
1705 if (isFollowedByParen)
1706 return TPResult::Ambiguous;
1709 return BracedCastResult;
1711 return TPResult::True;
1715 case tok::kw___underlying_type:
1716 return TPResult::True;
1719 case tok::kw__Atomic:
1720 return TPResult::True;
1723 return TPResult::False;
1727 bool Parser::isCXXDeclarationSpecifierAType() {
1728 switch (Tok.getKind()) {
1730 case tok::annot_decltype:
1731 case tok::annot_template_id:
1732 case tok::annot_typename:
1733 case tok::kw_typeof:
1734 case tok::kw___underlying_type:
1739 case tok::kw_struct:
1741 case tok::kw___interface:
1747 case tok::kw_wchar_t:
1748 case tok::kw_char8_t:
1749 case tok::kw_char16_t:
1750 case tok::kw_char32_t:
1755 case tok::kw___int64:
1756 case tok::kw___int128:
1757 case tok::kw_signed:
1758 case tok::kw_unsigned:
1761 case tok::kw_double:
1762 case tok::kw__Float16:
1763 case tok::kw___float128:
1765 case tok::kw___unknown_anytype:
1766 case tok::kw___auto_type:
1767 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 1768 #include "clang/Basic/OpenCLImageTypes.def" 1774 case tok::kw__Atomic:
1787 Parser::TPResult Parser::TryParseTypeofSpecifier() {
1788 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1791 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1795 return TPResult::Error;
1797 return TPResult::Ambiguous;
1802 Parser::TPResult Parser::TryParseProtocolQualifiers() {
1803 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1806 if (Tok.
isNot(tok::identifier))
1807 return TPResult::Error;
1810 if (Tok.
is(tok::comma)) {
1815 if (Tok.
is(tok::greater)) {
1817 return TPResult::Ambiguous;
1821 return TPResult::Error;
1834 bool Parser::isCXXFunctionDeclarator(
bool *IsAmbiguous) {
1845 RevertingTentativeParsingAction PA(*
this);
1848 bool InvalidAsDeclaration =
false;
1849 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
1850 if (TPR == TPResult::Ambiguous) {
1851 if (Tok.
isNot(tok::r_paren))
1852 TPR = TPResult::False;
1855 if (Next.
isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1856 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1857 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1858 isCXX11VirtSpecifier(Next))
1862 TPR = TPResult::True;
1863 else if (InvalidAsDeclaration)
1865 TPR = TPResult::False;
1869 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1870 *IsAmbiguous =
true;
1873 return TPR != TPResult::False;
1894 Parser::TryParseParameterDeclarationClause(
bool *InvalidAsDeclaration,
1895 bool VersusTemplateArgument) {
1897 if (Tok.
is(tok::r_paren))
1898 return TPResult::Ambiguous;
1909 if (Tok.
is(tok::ellipsis)) {
1911 if (Tok.
is(tok::r_paren))
1912 return TPResult::True;
1914 return TPResult::False;
1918 if (isCXX11AttributeSpecifier(
false,
1920 return TPResult::True;
1923 MaybeParseMicrosoftAttributes(attrs);
1928 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
1929 InvalidAsDeclaration);
1932 if (TPR != TPResult::Ambiguous &&
1933 !(VersusTemplateArgument && TPR == TPResult::True))
1936 bool SeenType =
false;
1938 SeenType |= isCXXDeclarationSpecifierAType();
1939 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1940 return TPResult::Error;
1943 if (SeenType && Tok.
is(tok::identifier))
1944 return TPResult::True;
1946 TPR = isCXXDeclarationSpecifier(TPResult::False,
1947 InvalidAsDeclaration);
1948 if (TPR == TPResult::Error)
1952 if (TPR == TPResult::True && !VersusTemplateArgument)
1954 }
while (TPR != TPResult::False);
1958 TPR = TryParseDeclarator(
true);
1959 if (TPR != TPResult::Ambiguous)
1963 if (Tok.
is(tok::kw___attribute))
1964 return TPResult::True;
1976 if (VersusTemplateArgument)
1977 return Tok.
isOneOf(tok::equal, tok::r_paren) ? TPResult::True
1980 if (Tok.
is(tok::equal)) {
1985 return TPResult::Error;
1988 if (Tok.
is(tok::ellipsis)) {
1990 if (Tok.
is(tok::r_paren))
1991 return TPResult::True;
1993 return TPResult::False;
2000 return TPResult::Ambiguous;
2015 Parser::TPResult Parser::TryParseFunctionDeclarator() {
2019 TPResult TPR = TryParseParameterDeclarationClause();
2020 if (TPR == TPResult::Ambiguous && Tok.
isNot(tok::r_paren))
2021 TPR = TPResult::False;
2023 if (TPR == TPResult::False || TPR == TPResult::Error)
2028 return TPResult::Error;
2031 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
2036 if (Tok.
isOneOf(tok::amp, tok::ampamp))
2040 if (Tok.
is(tok::kw_throw)) {
2042 if (Tok.
isNot(tok::l_paren))
2043 return TPResult::Error;
2048 return TPResult::Error;
2050 if (Tok.
is(tok::kw_noexcept)) {
2053 if (Tok.
is(tok::l_paren)) {
2057 return TPResult::Error;
2061 return TPResult::Ambiguous;
2066 Parser::TPResult Parser::TryParseBracketDeclarator() {
2069 return TPResult::Error;
2071 return TPResult::Ambiguous;
2078 Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
2079 if (!TokensToSkip) {
2080 if (Tok.
isNot(tok::less))
2081 return TPResult::False;
2083 return TPResult::True;
2086 RevertingTentativeParsingAction PA(*
this);
2088 while (TokensToSkip) {
2094 return TPResult::False;
2099 bool InvalidAsTemplateArgumentList =
false;
2100 if (isCXXDeclarationSpecifier(TPResult::False,
2101 &InvalidAsTemplateArgumentList) ==
2103 return TPResult::True;
2104 if (InvalidAsTemplateArgumentList)
2105 return TPResult::False;
2119 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2121 return TPResult::Ambiguous;
2122 return TPResult::False;
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 TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
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...
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)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
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.