18 using namespace clang;
50 bool Parser::isCXXDeclarationStatement() {
55 case tok::kw_namespace:
60 case tok::kw_static_assert:
61 case tok::kw__Static_assert:
65 return isCXXSimpleDeclaration(
false);
89 bool Parser::isCXXSimpleDeclaration(
bool AllowForRangeDecl) {
114 bool InvalidAsDeclaration =
false;
115 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
116 &InvalidAsDeclaration);
117 if (TPR != TPResult::Ambiguous)
118 return TPR != TPResult::False;
126 if (InvalidAsDeclaration)
137 RevertingTentativeParsingAction PA(*
this);
138 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
142 if (TPR == TPResult::Error)
146 if (TPR == TPResult::Ambiguous)
147 TPR = TPResult::True;
149 assert(TPR == TPResult::True || TPR == TPResult::False);
150 return TPR == TPResult::True;
155 Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
157 case tok::kw__Atomic:
164 case tok::kw___attribute:
165 case tok::kw___underlying_type: {
167 if (Tok.
isNot(tok::l_paren))
168 return TPResult::Error;
171 return TPResult::Error;
178 case tok::kw___interface:
190 while (Tok.
isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
192 if (Tok.
is(tok::l_square)) {
195 return TPResult::Error;
198 if (Tok.
isNot(tok::l_paren))
199 return TPResult::Error;
202 return TPResult::Error;
206 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
207 tok::annot_template_id) &&
209 return TPResult::Error;
210 if (Tok.
is(tok::annot_cxxscope))
211 ConsumeAnnotationToken();
212 if (Tok.
is(tok::identifier))
214 else if (Tok.
is(tok::annot_template_id))
215 ConsumeAnnotationToken();
217 return TPResult::Error;
220 case tok::annot_cxxscope:
221 ConsumeAnnotationToken();
227 return TryParseProtocolQualifiers();
231 return TPResult::Ambiguous;
242 Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
243 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
244 return TPResult::Error;
249 if (Tok.
isNot(tok::l_paren)) {
250 TPResult TPR = isCXXDeclarationSpecifier();
251 if (TPR == TPResult::Ambiguous)
252 return TPResult::True;
253 if (TPR == TPResult::True || TPR == TPResult::Error)
255 assert(TPR == TPResult::False);
258 TPResult TPR = TryParseInitDeclaratorList();
259 if (TPR != TPResult::Ambiguous)
262 if (Tok.
isNot(tok::semi) && (!AllowForRangeDecl || Tok.
isNot(tok::colon)))
263 return TPResult::False;
265 return TPResult::Ambiguous;
295 Parser::TPResult Parser::TryParseInitDeclaratorList() {
298 TPResult TPR = TryParseDeclarator(
false);
299 if (TPR != TPResult::Ambiguous)
303 if (Tok.
isOneOf(tok::kw_asm, tok::kw___attribute))
304 return TPResult::True;
307 if (Tok.
is(tok::l_paren)) {
311 return TPResult::Error;
312 }
else if (Tok.
is(tok::l_brace)) {
315 return TPResult::True;
316 }
else if (Tok.
is(tok::equal) || isTokIdentifier_in()) {
333 return TPResult::True;
340 return TPResult::Ambiguous;
346 bool CanBeCondition =
true;
351 bool CanBeForRangeDecl)
352 : P(P), CanBeInitStatement(CanBeInitStatement),
353 CanBeForRangeDecl(CanBeForRangeDecl) {}
356 return CanBeExpression + CanBeCondition + CanBeInitStatement +
357 CanBeForRangeDecl < 2;
361 CanBeExpression =
false;
368 RevertingTentativeParsingAction PA(P);
369 if (CanBeForRangeDecl) {
373 unsigned QuestionColonDepth = 0;
374 P.
SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
376 if (P.Tok.
is(tok::question))
377 ++QuestionColonDepth;
378 else if (P.Tok.
is(tok::colon)) {
379 if (QuestionColonDepth)
380 --QuestionColonDepth;
382 CanBeCondition = CanBeInitStatement =
false;
386 CanBeForRangeDecl =
false;
395 if (P.Tok.
isNot(tok::r_paren))
396 CanBeCondition = CanBeForRangeDecl =
false;
397 if (P.Tok.
isNot(tok::semi))
398 CanBeInitStatement =
false;
403 CanBeCondition =
false;
408 CanBeForRangeDecl =
false;
416 assert(resolved() &&
"can't continue after tentative parsing bails out");
418 case TPResult::False:
419 CanBeCondition = CanBeInitStatement = CanBeForRangeDecl =
false;
421 case TPResult::Ambiguous:
423 case TPResult::Error:
424 CanBeExpression = CanBeCondition = CanBeInitStatement =
425 CanBeForRangeDecl =
false;
431 ConditionOrInitStatement
result()
const {
432 assert(CanBeExpression + CanBeCondition + CanBeInitStatement +
433 CanBeForRangeDecl < 2 &&
434 "result called but not yet resolved");
436 return ConditionOrInitStatement::Expression;
438 return ConditionOrInitStatement::ConditionDecl;
439 if (CanBeInitStatement)
440 return ConditionOrInitStatement::InitStmtDecl;
441 if (CanBeForRangeDecl)
442 return ConditionOrInitStatement::ForRangeDecl;
443 return ConditionOrInitStatement::Error;
464 Parser::ConditionOrInitStatement
465 Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement,
466 bool CanBeForRangeDecl) {
470 if (State.
update(isCXXDeclarationSpecifier()))
474 RevertingTentativeParsingAction PA(*
this);
477 if (State.
update(TryConsumeDeclarationSpecifier()))
479 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
483 if (State.
update(TryParseDeclarator(
false)))
489 if (Tok.
isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
497 return ConditionOrInitStatement::ForRangeDecl;
510 if (Tok.
is(tok::l_paren)) {
521 return ConditionOrInitStatement::ConditionDecl;
523 return ConditionOrInitStatement::InitStmtDecl;
525 return ConditionOrInitStatement::Expression;
545 bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context,
bool &isAmbiguous) {
556 TPResult TPR = isCXXDeclarationSpecifier();
557 if (TPR != TPResult::Ambiguous)
558 return TPR != TPResult::False;
567 RevertingTentativeParsingAction PA(*
this);
570 TryConsumeDeclarationSpecifier();
571 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
574 TPR = TryParseDeclarator(
true,
false);
577 if (TPR == TPResult::Error)
578 TPR = TPResult::True;
580 if (TPR == TPResult::Ambiguous) {
583 if (Context == TypeIdInParens && Tok.
is(tok::r_paren)) {
584 TPR = TPResult::True;
591 }
else if (Context == TypeIdAsTemplateArgument &&
592 (Tok.
isOneOf(tok::greater, tok::comma) ||
594 (Tok.
is(tok::greatergreater) ||
595 (Tok.
is(tok::ellipsis) &&
598 TPR = TPResult::True;
602 TPR = TPResult::False;
605 assert(TPR == TPResult::True || TPR == TPResult::False);
606 return TPR == TPResult::True;
642 Parser::CXX11AttributeKind
643 Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
644 bool OuterMightBeMessageSend) {
645 if (Tok.
is(tok::kw_alignas))
646 return CAK_AttributeSpecifier;
649 return CAK_NotAttributeSpecifier;
653 return CAK_AttributeSpecifier;
655 RevertingTentativeParsingAction PA(*
this);
664 bool IsAttribute =
SkipUntil(tok::r_square);
665 IsAttribute &= Tok.
is(tok::r_square);
667 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
683 if (!TryParseLambdaIntroducer(Intro)) {
685 bool IsAttribute = Tok.
is(tok::r_square);
689 return CAK_AttributeSpecifier;
691 if (OuterMightBeMessageSend)
693 return CAK_NotAttributeSpecifier;
696 return CAK_InvalidAttributeSpecifier;
703 bool IsAttribute =
true;
704 while (Tok.
isNot(tok::r_square)) {
705 if (Tok.
is(tok::comma)) {
707 return CAK_AttributeSpecifier;
716 if (!TryParseCXX11AttributeIdentifier(Loc)) {
720 if (Tok.
is(tok::coloncolon)) {
722 if (!TryParseCXX11AttributeIdentifier(Loc)) {
729 if (Tok.
is(tok::l_paren)) {
745 if (Tok.
is(tok::r_square)) {
747 IsAttribute = Tok.
is(tok::r_square);
755 return CAK_AttributeSpecifier;
758 return CAK_NotAttributeSpecifier;
761 Parser::TPResult Parser::TryParsePtrOperatorSeq() {
763 if (Tok.
isOneOf(tok::coloncolon, tok::identifier))
765 return TPResult::Error;
767 if (Tok.
isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
768 (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
771 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
772 tok::kw__Nonnull, tok::kw__Nullable,
773 tok::kw__Null_unspecified))
776 return TPResult::True;
799 Parser::TPResult Parser::TryParseOperatorId() {
800 assert(Tok.
is(tok::kw_operator));
804 switch (Tok.getKind()) {
805 case tok::kw_new:
case tok::kw_delete:
807 if (Tok.
is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
811 return TPResult::True;
813 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \ 815 #define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly) 816 #include "clang/Basic/OperatorKinds.def" 818 return TPResult::True;
824 return TPResult::True;
832 return TPResult::True;
842 bool FoundUDSuffix =
false;
844 FoundUDSuffix |= Tok.hasUDSuffix();
845 ConsumeStringToken();
846 }
while (isTokenStringLiteral());
848 if (!FoundUDSuffix) {
849 if (Tok.
is(tok::identifier))
852 return TPResult::Error;
854 return TPResult::True;
858 bool AnyDeclSpecifiers =
false;
860 TPResult TPR = isCXXDeclarationSpecifier();
861 if (TPR == TPResult::Error)
863 if (TPR == TPResult::False) {
864 if (!AnyDeclSpecifiers)
865 return TPResult::Error;
868 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
869 return TPResult::Error;
870 AnyDeclSpecifiers =
true;
872 return TryParsePtrOperatorSeq();
928 Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
929 bool mayHaveIdentifier,
930 bool mayHaveDirectInit) {
934 if (TryParsePtrOperatorSeq() == TPResult::Error)
935 return TPResult::Error;
939 if (Tok.
is(tok::ellipsis))
942 if ((Tok.
isOneOf(tok::identifier, tok::kw_operator) ||
943 (Tok.
is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
947 if (Tok.
is(tok::annot_cxxscope))
948 ConsumeAnnotationToken();
949 else if (Tok.
is(tok::identifier))
950 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
951 if (Tok.
is(tok::kw_operator)) {
952 if (TryParseOperatorId() == TPResult::Error)
953 return TPResult::Error;
956 }
else if (Tok.
is(tok::l_paren)) {
959 (Tok.
is(tok::r_paren) ||
962 isDeclarationSpecifier())) {
965 TPResult TPR = TryParseFunctionDeclarator();
966 if (TPR != TPResult::Ambiguous)
972 if (Tok.
isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
973 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
974 tok::kw___regcall, tok::kw___vectorcall))
975 return TPResult::True;
976 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
977 if (TPR != TPResult::Ambiguous)
979 if (Tok.
isNot(tok::r_paren))
980 return TPResult::False;
983 }
else if (!mayBeAbstract) {
984 return TPResult::False;
987 if (mayHaveDirectInit)
988 return TPResult::Ambiguous;
991 TPResult TPR(TPResult::Ambiguous);
993 if (Tok.
is(tok::l_paren)) {
998 if (!mayBeAbstract && !isCXXFunctionDeclarator())
1004 TPR = TryParseFunctionDeclarator();
1005 }
else if (Tok.
is(tok::l_square)) {
1008 TPR = TryParseBracketDeclarator();
1013 if (TPR != TPResult::Ambiguous)
1017 return TPResult::Ambiguous;
1024 case tok::numeric_constant:
1025 case tok::char_constant:
1026 case tok::wide_char_constant:
1027 case tok::utf8_char_constant:
1028 case tok::utf16_char_constant:
1029 case tok::utf32_char_constant:
1030 case tok::string_literal:
1031 case tok::wide_string_literal:
1032 case tok::utf8_string_literal:
1033 case tok::utf16_string_literal:
1034 case tok::utf32_string_literal:
1043 case tok::minusminus:
1046 case tok::kw_sizeof:
1047 case tok::kw___func__:
1048 case tok::kw_const_cast:
1049 case tok::kw_delete:
1050 case tok::kw_dynamic_cast:
1053 case tok::kw_operator:
1054 case tok::kw_reinterpret_cast:
1055 case tok::kw_static_cast:
1059 case tok::kw_typeid:
1060 case tok::kw_alignof:
1061 case tok::kw_noexcept:
1062 case tok::kw_nullptr:
1063 case tok::kw__Alignof:
1064 case tok::kw___null:
1065 case tok::kw___alignof:
1066 case tok::kw___builtin_choose_expr:
1067 case tok::kw___builtin_offsetof:
1068 case tok::kw___builtin_va_arg:
1069 case tok::kw___imag:
1070 case tok::kw___real:
1071 case tok::kw___FUNCTION__:
1072 case tok::kw___FUNCDNAME__:
1073 case tok::kw___FUNCSIG__:
1074 case tok::kw_L__FUNCTION__:
1075 case tok::kw_L__FUNCSIG__:
1076 case tok::kw___PRETTY_FUNCTION__:
1077 case tok::kw___uuidof:
1078 #define TYPE_TRAIT(N,Spelling,K) \ 1079 case tok::kw_##Spelling: 1080 #include "clang/Basic/TokenKinds.def" 1081 return TPResult::True;
1086 case tok::kw_double:
1087 case tok::kw__Float16:
1088 case tok::kw___float128:
1094 case tok::kw___int64:
1095 case tok::kw___int128:
1096 case tok::kw_restrict:
1098 case tok::kw_signed:
1099 case tok::kw_struct:
1101 case tok::kw_unsigned:
1103 case tok::kw_volatile:
1105 case tok::kw__Complex:
1107 case tok::kw_typename:
1108 case tok::kw_wchar_t:
1109 case tok::kw_char8_t:
1110 case tok::kw_char16_t:
1111 case tok::kw_char32_t:
1112 case tok::kw__Decimal32:
1113 case tok::kw__Decimal64:
1114 case tok::kw__Decimal128:
1115 case tok::kw___interface:
1116 case tok::kw___thread:
1117 case tok::kw_thread_local:
1118 case tok::kw__Thread_local:
1119 case tok::kw_typeof:
1120 case tok::kw___underlying_type:
1121 case tok::kw___cdecl:
1122 case tok::kw___stdcall:
1123 case tok::kw___fastcall:
1124 case tok::kw___thiscall:
1125 case tok::kw___regcall:
1126 case tok::kw___vectorcall:
1127 case tok::kw___unaligned:
1128 case tok::kw___vector:
1129 case tok::kw___pixel:
1130 case tok::kw___bool:
1131 case tok::kw__Atomic:
1132 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 1133 #include "clang/Basic/OpenCLImageTypes.def" 1134 case tok::kw___unknown_anytype:
1135 return TPResult::False;
1141 return TPResult::Ambiguous;
1145 return std::find(TentativelyDeclaredIdentifiers.begin(),
1146 TentativelyDeclaredIdentifiers.end(), II)
1147 != TentativelyDeclaredIdentifiers.end();
1153 TentativeParseCCC(
const Token &Next) {
1154 WantRemainingKeywords =
false;
1155 WantTypeSpecifiers = Next.
isOneOf(tok::l_paren, tok::r_paren, tok::greater,
1156 tok::l_brace, tok::identifier);
1159 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1163 llvm::all_of(Candidate,
1278 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1279 bool *HasMissingTypename) {
1280 switch (Tok.getKind()) {
1281 case tok::identifier: {
1284 if (TryAltiVecVectorToken())
1285 return TPResult::True;
1290 return TPResult::True;
1292 if (Next.
isNot(tok::coloncolon) && Next.
isNot(tok::less)) {
1297 switch (TryAnnotateName(
false ,
1298 llvm::make_unique<TentativeParseCCC>(Next))) {
1300 return TPResult::Error;
1301 case ANK_TentativeDecl:
1302 return TPResult::False;
1303 case ANK_TemplateName:
1310 return TPResult::Error;
1311 if (Tok.
isNot(tok::identifier))
1317 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1318 case ANK_Unresolved:
1319 return HasMissingTypename ? TPResult::Ambiguous : TPResult::False;
1323 assert(Tok.
isNot(tok::identifier) &&
1324 "TryAnnotateName succeeded without producing an annotation");
1331 return TPResult::Error;
1335 if (Tok.
is(tok::identifier))
1336 return TPResult::False;
1340 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1343 case tok::kw_typename:
1347 return TPResult::Error;
1348 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1350 case tok::coloncolon: {
1354 return TPResult::False;
1357 case tok::kw___super:
1358 case tok::kw_decltype:
1362 return TPResult::Error;
1363 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1372 case tok::kw_friend:
1373 case tok::kw_typedef:
1374 case tok::kw_constexpr:
1376 case tok::kw_register:
1377 case tok::kw_static:
1378 case tok::kw_extern:
1379 case tok::kw_mutable:
1381 case tok::kw___thread:
1382 case tok::kw_thread_local:
1383 case tok::kw__Thread_local:
1385 case tok::kw_inline:
1386 case tok::kw_virtual:
1387 case tok::kw_explicit:
1390 case tok::kw___module_private__:
1393 case tok::kw___unknown_anytype:
1406 case tok::kw_struct:
1408 case tok::kw___interface:
1413 case tok::kw_volatile:
1414 case tok::kw___private:
1415 case tok::kw___local:
1416 case tok::kw___global:
1417 case tok::kw___constant:
1418 case tok::kw___generic:
1421 case tok::kw_restrict:
1422 case tok::kw__Complex:
1423 case tok::kw___attribute:
1424 case tok::kw___auto_type:
1425 return TPResult::True;
1428 case tok::kw___declspec:
1429 case tok::kw___cdecl:
1430 case tok::kw___stdcall:
1431 case tok::kw___fastcall:
1432 case tok::kw___thiscall:
1433 case tok::kw___regcall:
1434 case tok::kw___vectorcall:
1436 case tok::kw___sptr:
1437 case tok::kw___uptr:
1438 case tok::kw___ptr64:
1439 case tok::kw___ptr32:
1440 case tok::kw___forceinline:
1441 case tok::kw___unaligned:
1442 case tok::kw__Nonnull:
1443 case tok::kw__Nullable:
1444 case tok::kw__Null_unspecified:
1445 case tok::kw___kindof:
1446 return TPResult::True;
1449 case tok::kw___pascal:
1450 return TPResult::True;
1453 case tok::kw___vector:
1454 return TPResult::True;
1456 case tok::annot_template_id: {
1459 return TPResult::False;
1461 AnnotateTemplateIdTokenAsType();
1462 assert(Tok.
is(tok::annot_typename));
1466 case tok::annot_cxxscope:
1469 return TPResult::Error;
1470 if (!Tok.
is(tok::annot_typename)) {
1473 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1475 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1476 Tok.getAnnotationRange(),
1479 RevertingTentativeParsingAction PA(*
this);
1480 ConsumeAnnotationToken();
1482 bool isIdentifier = Tok.
is(tok::identifier);
1483 TPResult TPR = TPResult::False;
1485 TPR = isCXXDeclarationSpecifier(BracedCastResult,
1486 HasMissingTypename);
1489 TPR == TPResult::True || TPR == TPResult::Error)
1490 return TPResult::Error;
1492 if (HasMissingTypename) {
1495 *HasMissingTypename =
true;
1496 return TPResult::Ambiguous;
1501 switch (TryAnnotateName(
false )) {
1503 return TPResult::Error;
1504 case ANK_TentativeDecl:
1505 return TPResult::False;
1506 case ANK_TemplateName:
1511 return TPResult::Error;
1512 if (Tok.
isNot(tok::identifier))
1519 return (
getLangOpts().CPlusPlus17 || GreaterThanIsOperator)
1522 case ANK_Unresolved:
1523 return HasMissingTypename ? TPResult::Ambiguous
1530 assert(Tok.
isNot(tok::annot_cxxscope) ||
1532 return isCXXDeclarationSpecifier(BracedCastResult,
1533 HasMissingTypename);
1536 return TPResult::False;
1559 case tok::annot_typename:
1564 RevertingTentativeParsingAction PA(*
this);
1567 TPResult TPR = TryParseProtocolQualifiers();
1568 bool isFollowedByParen = Tok.
is(tok::l_paren);
1569 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1571 if (TPR == TPResult::Error)
1572 return TPResult::Error;
1574 if (isFollowedByParen)
1575 return TPResult::Ambiguous;
1578 return BracedCastResult;
1580 return TPResult::True;
1585 case tok::kw_wchar_t:
1586 case tok::kw_char8_t:
1587 case tok::kw_char16_t:
1588 case tok::kw_char32_t:
1593 case tok::kw___int64:
1594 case tok::kw___int128:
1595 case tok::kw_signed:
1596 case tok::kw_unsigned:
1599 case tok::kw_double:
1600 case tok::kw__Float16:
1601 case tok::kw___float128:
1603 case tok::annot_decltype:
1605 return TPResult::Ambiguous;
1614 return BracedCastResult;
1616 if (isStartOfObjCClassMessageMissingOpenBracket())
1617 return TPResult::False;
1619 return TPResult::True;
1622 case tok::kw_typeof: {
1624 return TPResult::True;
1626 RevertingTentativeParsingAction PA(*
this);
1628 TPResult TPR = TryParseTypeofSpecifier();
1629 bool isFollowedByParen = Tok.
is(tok::l_paren);
1630 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1632 if (TPR == TPResult::Error)
1633 return TPResult::Error;
1635 if (isFollowedByParen)
1636 return TPResult::Ambiguous;
1639 return BracedCastResult;
1641 return TPResult::True;
1645 case tok::kw___underlying_type:
1646 return TPResult::True;
1649 case tok::kw__Atomic:
1650 return TPResult::True;
1653 return TPResult::False;
1657 bool Parser::isCXXDeclarationSpecifierAType() {
1658 switch (Tok.getKind()) {
1660 case tok::annot_decltype:
1661 case tok::annot_template_id:
1662 case tok::annot_typename:
1663 case tok::kw_typeof:
1664 case tok::kw___underlying_type:
1669 case tok::kw_struct:
1671 case tok::kw___interface:
1677 case tok::kw_wchar_t:
1678 case tok::kw_char8_t:
1679 case tok::kw_char16_t:
1680 case tok::kw_char32_t:
1685 case tok::kw___int64:
1686 case tok::kw___int128:
1687 case tok::kw_signed:
1688 case tok::kw_unsigned:
1691 case tok::kw_double:
1692 case tok::kw__Float16:
1693 case tok::kw___float128:
1695 case tok::kw___unknown_anytype:
1696 case tok::kw___auto_type:
1702 case tok::kw__Atomic:
1715 Parser::TPResult Parser::TryParseTypeofSpecifier() {
1716 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1719 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1723 return TPResult::Error;
1725 return TPResult::Ambiguous;
1730 Parser::TPResult Parser::TryParseProtocolQualifiers() {
1731 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1734 if (Tok.
isNot(tok::identifier))
1735 return TPResult::Error;
1738 if (Tok.
is(tok::comma)) {
1743 if (Tok.
is(tok::greater)) {
1745 return TPResult::Ambiguous;
1749 return TPResult::Error;
1762 bool Parser::isCXXFunctionDeclarator(
bool *IsAmbiguous) {
1773 RevertingTentativeParsingAction PA(*
this);
1776 bool InvalidAsDeclaration =
false;
1777 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
1778 if (TPR == TPResult::Ambiguous) {
1779 if (Tok.
isNot(tok::r_paren))
1780 TPR = TPResult::False;
1783 if (Next.
isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1784 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1785 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1786 isCXX11VirtSpecifier(Next))
1790 TPR = TPResult::True;
1791 else if (InvalidAsDeclaration)
1793 TPR = TPResult::False;
1797 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1798 *IsAmbiguous =
true;
1801 return TPR != TPResult::False;
1822 Parser::TryParseParameterDeclarationClause(
bool *InvalidAsDeclaration,
1823 bool VersusTemplateArgument) {
1825 if (Tok.
is(tok::r_paren))
1826 return TPResult::Ambiguous;
1837 if (Tok.
is(tok::ellipsis)) {
1839 if (Tok.
is(tok::r_paren))
1840 return TPResult::True;
1842 return TPResult::False;
1846 if (isCXX11AttributeSpecifier(
false,
1848 return TPResult::True;
1851 MaybeParseMicrosoftAttributes(attrs);
1856 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
1857 InvalidAsDeclaration);
1859 if (VersusTemplateArgument && TPR == TPResult::True) {
1862 bool SeenType =
false;
1864 SeenType |= isCXXDeclarationSpecifierAType();
1865 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1866 return TPResult::Error;
1869 if (SeenType && Tok.
is(tok::identifier))
1870 return TPResult::True;
1872 TPR = isCXXDeclarationSpecifier(TPResult::False,
1873 InvalidAsDeclaration);
1874 if (TPR == TPResult::Error)
1876 }
while (TPR != TPResult::False);
1877 }
else if (TPR == TPResult::Ambiguous) {
1879 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1880 return TPResult::Error;
1886 TPR = TryParseDeclarator(
true);
1887 if (TPR != TPResult::Ambiguous)
1891 if (Tok.
is(tok::kw___attribute))
1892 return TPResult::True;
1904 if (VersusTemplateArgument)
1905 return Tok.
isOneOf(tok::equal, tok::r_paren) ? TPResult::True
1908 if (Tok.
is(tok::equal)) {
1913 return TPResult::Error;
1916 if (Tok.
is(tok::ellipsis)) {
1918 if (Tok.
is(tok::r_paren))
1919 return TPResult::True;
1921 return TPResult::False;
1928 return TPResult::Ambiguous;
1943 Parser::TPResult Parser::TryParseFunctionDeclarator() {
1947 TPResult TPR = TryParseParameterDeclarationClause();
1948 if (TPR == TPResult::Ambiguous && Tok.
isNot(tok::r_paren))
1949 TPR = TPResult::False;
1951 if (TPR == TPResult::False || TPR == TPResult::Error)
1956 return TPResult::Error;
1959 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1964 if (Tok.
isOneOf(tok::amp, tok::ampamp))
1968 if (Tok.
is(tok::kw_throw)) {
1970 if (Tok.
isNot(tok::l_paren))
1971 return TPResult::Error;
1976 return TPResult::Error;
1978 if (Tok.
is(tok::kw_noexcept)) {
1981 if (Tok.
is(tok::l_paren)) {
1985 return TPResult::Error;
1989 return TPResult::Ambiguous;
1994 Parser::TPResult Parser::TryParseBracketDeclarator() {
1997 return TPResult::Error;
1999 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 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.
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.