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;
350 : P(P), CanBeInitStatement(CanBeInitStatement) {}
353 CanBeExpression =
false;
355 if (CanBeCondition && CanBeInitStatement) {
360 RevertingTentativeParsingAction PA(P);
362 if (P.Tok.
isNot(tok::r_paren))
363 CanBeCondition =
false;
364 if (P.Tok.
isNot(tok::semi))
365 CanBeInitStatement =
false;
370 CanBeCondition =
false;
379 case TPResult::False:
380 CanBeCondition = CanBeInitStatement =
false;
382 case TPResult::Ambiguous:
384 case TPResult::Error:
385 CanBeExpression = CanBeCondition = CanBeInitStatement =
false;
388 llvm_unreachable(
"unknown tentative parse result");
391 ConditionOrInitStatement
result()
const {
392 assert(CanBeExpression + CanBeCondition + CanBeInitStatement < 2 &&
393 "result called but not yet resolved");
395 return ConditionOrInitStatement::Expression;
397 return ConditionOrInitStatement::ConditionDecl;
398 if (CanBeInitStatement)
399 return ConditionOrInitStatement::InitStmtDecl;
400 return ConditionOrInitStatement::Error;
421 Parser::ConditionOrInitStatement
422 Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement) {
425 if (State.
update(isCXXDeclarationSpecifier()))
429 RevertingTentativeParsingAction PA(*
this);
432 if (State.
update(TryConsumeDeclarationSpecifier()))
434 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
438 if (State.
update(TryParseDeclarator(
false)))
444 if (Tok.
isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
457 if (Tok.
is(tok::l_paren)) {
468 return ConditionOrInitStatement::ConditionDecl;
470 return ConditionOrInitStatement::InitStmtDecl;
472 return ConditionOrInitStatement::Expression;
492 bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context,
bool &isAmbiguous) {
503 TPResult TPR = isCXXDeclarationSpecifier();
504 if (TPR != TPResult::Ambiguous)
505 return TPR != TPResult::False;
514 RevertingTentativeParsingAction PA(*
this);
517 TryConsumeDeclarationSpecifier();
518 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
521 TPR = TryParseDeclarator(
true,
false);
524 if (TPR == TPResult::Error)
525 TPR = TPResult::True;
527 if (TPR == TPResult::Ambiguous) {
530 if (Context == TypeIdInParens && Tok.
is(tok::r_paren)) {
531 TPR = TPResult::True;
538 }
else if (Context == TypeIdAsTemplateArgument &&
539 (Tok.
isOneOf(tok::greater, tok::comma) ||
541 (Tok.
is(tok::greatergreater) ||
542 (Tok.
is(tok::ellipsis) &&
545 TPR = TPResult::True;
549 TPR = TPResult::False;
552 assert(TPR == TPResult::True || TPR == TPResult::False);
553 return TPR == TPResult::True;
589 Parser::CXX11AttributeKind
590 Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
591 bool OuterMightBeMessageSend) {
592 if (Tok.
is(tok::kw_alignas))
593 return CAK_AttributeSpecifier;
596 return CAK_NotAttributeSpecifier;
600 return CAK_AttributeSpecifier;
602 RevertingTentativeParsingAction PA(*
this);
611 bool IsAttribute =
SkipUntil(tok::r_square);
612 IsAttribute &= Tok.
is(tok::r_square);
614 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
630 if (!TryParseLambdaIntroducer(Intro)) {
632 bool IsAttribute = Tok.
is(tok::r_square);
636 return CAK_AttributeSpecifier;
638 if (OuterMightBeMessageSend)
640 return CAK_NotAttributeSpecifier;
643 return CAK_InvalidAttributeSpecifier;
650 bool IsAttribute =
true;
651 while (Tok.
isNot(tok::r_square)) {
652 if (Tok.
is(tok::comma)) {
654 return CAK_AttributeSpecifier;
663 if (!TryParseCXX11AttributeIdentifier(Loc)) {
667 if (Tok.
is(tok::coloncolon)) {
669 if (!TryParseCXX11AttributeIdentifier(Loc)) {
676 if (Tok.
is(tok::l_paren)) {
692 if (Tok.
is(tok::r_square)) {
694 IsAttribute = Tok.
is(tok::r_square);
702 return CAK_AttributeSpecifier;
705 return CAK_NotAttributeSpecifier;
708 Parser::TPResult Parser::TryParsePtrOperatorSeq() {
710 if (Tok.
isOneOf(tok::coloncolon, tok::identifier))
712 return TPResult::Error;
714 if (Tok.
isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
715 (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
718 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
719 tok::kw__Nonnull, tok::kw__Nullable,
720 tok::kw__Null_unspecified))
723 return TPResult::True;
746 Parser::TPResult Parser::TryParseOperatorId() {
747 assert(Tok.
is(tok::kw_operator));
751 switch (Tok.getKind()) {
752 case tok::kw_new:
case tok::kw_delete:
754 if (Tok.
is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
758 return TPResult::True;
760 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \ 762 #define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly) 763 #include "clang/Basic/OperatorKinds.def" 765 return TPResult::True;
771 return TPResult::True;
779 return TPResult::True;
789 bool FoundUDSuffix =
false;
791 FoundUDSuffix |= Tok.hasUDSuffix();
792 ConsumeStringToken();
793 }
while (isTokenStringLiteral());
795 if (!FoundUDSuffix) {
796 if (Tok.
is(tok::identifier))
799 return TPResult::Error;
801 return TPResult::True;
805 bool AnyDeclSpecifiers =
false;
807 TPResult TPR = isCXXDeclarationSpecifier();
808 if (TPR == TPResult::Error)
810 if (TPR == TPResult::False) {
811 if (!AnyDeclSpecifiers)
812 return TPResult::Error;
815 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
816 return TPResult::Error;
817 AnyDeclSpecifiers =
true;
819 return TryParsePtrOperatorSeq();
875 Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
876 bool mayHaveIdentifier,
877 bool mayHaveDirectInit) {
881 if (TryParsePtrOperatorSeq() == TPResult::Error)
882 return TPResult::Error;
886 if (Tok.
is(tok::ellipsis))
889 if ((Tok.
isOneOf(tok::identifier, tok::kw_operator) ||
890 (Tok.
is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
894 if (Tok.
is(tok::annot_cxxscope))
895 ConsumeAnnotationToken();
896 else if (Tok.
is(tok::identifier))
897 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
898 if (Tok.
is(tok::kw_operator)) {
899 if (TryParseOperatorId() == TPResult::Error)
900 return TPResult::Error;
903 }
else if (Tok.
is(tok::l_paren)) {
906 (Tok.
is(tok::r_paren) ||
909 isDeclarationSpecifier())) {
912 TPResult TPR = TryParseFunctionDeclarator();
913 if (TPR != TPResult::Ambiguous)
919 if (Tok.
isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
920 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
921 tok::kw___regcall, tok::kw___vectorcall))
922 return TPResult::True;
923 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
924 if (TPR != TPResult::Ambiguous)
926 if (Tok.
isNot(tok::r_paren))
927 return TPResult::False;
930 }
else if (!mayBeAbstract) {
931 return TPResult::False;
934 if (mayHaveDirectInit)
935 return TPResult::Ambiguous;
938 TPResult TPR(TPResult::Ambiguous);
940 if (Tok.
is(tok::l_paren)) {
945 if (!mayBeAbstract && !isCXXFunctionDeclarator())
951 TPR = TryParseFunctionDeclarator();
952 }
else if (Tok.
is(tok::l_square)) {
955 TPR = TryParseBracketDeclarator();
960 if (TPR != TPResult::Ambiguous)
964 return TPResult::Ambiguous;
971 case tok::numeric_constant:
972 case tok::char_constant:
973 case tok::wide_char_constant:
974 case tok::utf8_char_constant:
975 case tok::utf16_char_constant:
976 case tok::utf32_char_constant:
977 case tok::string_literal:
978 case tok::wide_string_literal:
979 case tok::utf8_string_literal:
980 case tok::utf16_string_literal:
981 case tok::utf32_string_literal:
990 case tok::minusminus:
994 case tok::kw___func__:
995 case tok::kw_const_cast:
997 case tok::kw_dynamic_cast:
1000 case tok::kw_operator:
1001 case tok::kw_reinterpret_cast:
1002 case tok::kw_static_cast:
1006 case tok::kw_typeid:
1007 case tok::kw_alignof:
1008 case tok::kw_noexcept:
1009 case tok::kw_nullptr:
1010 case tok::kw__Alignof:
1011 case tok::kw___null:
1012 case tok::kw___alignof:
1013 case tok::kw___builtin_choose_expr:
1014 case tok::kw___builtin_offsetof:
1015 case tok::kw___builtin_va_arg:
1016 case tok::kw___imag:
1017 case tok::kw___real:
1018 case tok::kw___FUNCTION__:
1019 case tok::kw___FUNCDNAME__:
1020 case tok::kw___FUNCSIG__:
1021 case tok::kw_L__FUNCTION__:
1022 case tok::kw_L__FUNCSIG__:
1023 case tok::kw___PRETTY_FUNCTION__:
1024 case tok::kw___uuidof:
1025 #define TYPE_TRAIT(N,Spelling,K) \ 1026 case tok::kw_##Spelling: 1027 #include "clang/Basic/TokenKinds.def" 1028 return TPResult::True;
1033 case tok::kw_double:
1034 case tok::kw__Float16:
1035 case tok::kw___float128:
1041 case tok::kw___int64:
1042 case tok::kw___int128:
1043 case tok::kw_restrict:
1045 case tok::kw_signed:
1046 case tok::kw_struct:
1048 case tok::kw_unsigned:
1050 case tok::kw_volatile:
1052 case tok::kw__Complex:
1054 case tok::kw_typename:
1055 case tok::kw_wchar_t:
1056 case tok::kw_char8_t:
1057 case tok::kw_char16_t:
1058 case tok::kw_char32_t:
1059 case tok::kw__Decimal32:
1060 case tok::kw__Decimal64:
1061 case tok::kw__Decimal128:
1062 case tok::kw___interface:
1063 case tok::kw___thread:
1064 case tok::kw_thread_local:
1065 case tok::kw__Thread_local:
1066 case tok::kw_typeof:
1067 case tok::kw___underlying_type:
1068 case tok::kw___cdecl:
1069 case tok::kw___stdcall:
1070 case tok::kw___fastcall:
1071 case tok::kw___thiscall:
1072 case tok::kw___regcall:
1073 case tok::kw___vectorcall:
1074 case tok::kw___unaligned:
1075 case tok::kw___vector:
1076 case tok::kw___pixel:
1077 case tok::kw___bool:
1078 case tok::kw__Atomic:
1079 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 1080 #include "clang/Basic/OpenCLImageTypes.def" 1081 case tok::kw___unknown_anytype:
1082 return TPResult::False;
1088 return TPResult::Ambiguous;
1092 return std::find(TentativelyDeclaredIdentifiers.begin(),
1093 TentativelyDeclaredIdentifiers.end(), II)
1094 != TentativelyDeclaredIdentifiers.end();
1100 TentativeParseCCC(
const Token &Next) {
1101 WantRemainingKeywords =
false;
1102 WantTypeSpecifiers = Next.
isOneOf(tok::l_paren, tok::r_paren, tok::greater,
1103 tok::l_brace, tok::identifier);
1106 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1110 std::all_of(Candidate.
begin(), Candidate.
end(),
1111 [](
NamedDecl *ND) {
return ND->isCXXInstanceMember(); }))
1225 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1226 bool *HasMissingTypename) {
1227 switch (Tok.getKind()) {
1228 case tok::identifier: {
1231 if (TryAltiVecVectorToken())
1232 return TPResult::True;
1237 return TPResult::True;
1239 if (Next.
isNot(tok::coloncolon) && Next.
isNot(tok::less)) {
1244 switch (TryAnnotateName(
false ,
1245 llvm::make_unique<TentativeParseCCC>(Next))) {
1247 return TPResult::Error;
1248 case ANK_TentativeDecl:
1249 return TPResult::False;
1250 case ANK_TemplateName:
1257 return TPResult::Error;
1258 if (Tok.
isNot(tok::identifier))
1264 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1265 case ANK_Unresolved:
1266 return HasMissingTypename ? TPResult::Ambiguous : TPResult::False;
1270 assert(Tok.
isNot(tok::identifier) &&
1271 "TryAnnotateName succeeded without producing an annotation");
1278 return TPResult::Error;
1282 if (Tok.
is(tok::identifier))
1283 return TPResult::False;
1287 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1290 case tok::kw_typename:
1294 return TPResult::Error;
1295 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1297 case tok::coloncolon: {
1301 return TPResult::False;
1304 case tok::kw___super:
1305 case tok::kw_decltype:
1309 return TPResult::Error;
1310 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1319 case tok::kw_friend:
1320 case tok::kw_typedef:
1321 case tok::kw_constexpr:
1323 case tok::kw_register:
1324 case tok::kw_static:
1325 case tok::kw_extern:
1326 case tok::kw_mutable:
1328 case tok::kw___thread:
1329 case tok::kw_thread_local:
1330 case tok::kw__Thread_local:
1332 case tok::kw_inline:
1333 case tok::kw_virtual:
1334 case tok::kw_explicit:
1337 case tok::kw___module_private__:
1340 case tok::kw___unknown_anytype:
1353 case tok::kw_struct:
1355 case tok::kw___interface:
1360 case tok::kw_volatile:
1361 case tok::kw___private:
1362 case tok::kw___local:
1363 case tok::kw___global:
1364 case tok::kw___constant:
1365 case tok::kw___generic:
1368 case tok::kw_restrict:
1369 case tok::kw__Complex:
1370 case tok::kw___attribute:
1371 case tok::kw___auto_type:
1372 return TPResult::True;
1375 case tok::kw___declspec:
1376 case tok::kw___cdecl:
1377 case tok::kw___stdcall:
1378 case tok::kw___fastcall:
1379 case tok::kw___thiscall:
1380 case tok::kw___regcall:
1381 case tok::kw___vectorcall:
1383 case tok::kw___sptr:
1384 case tok::kw___uptr:
1385 case tok::kw___ptr64:
1386 case tok::kw___ptr32:
1387 case tok::kw___forceinline:
1388 case tok::kw___unaligned:
1389 case tok::kw__Nonnull:
1390 case tok::kw__Nullable:
1391 case tok::kw__Null_unspecified:
1392 case tok::kw___kindof:
1393 return TPResult::True;
1396 case tok::kw___pascal:
1397 return TPResult::True;
1400 case tok::kw___vector:
1401 return TPResult::True;
1403 case tok::annot_template_id: {
1406 return TPResult::False;
1408 AnnotateTemplateIdTokenAsType();
1409 assert(Tok.
is(tok::annot_typename));
1413 case tok::annot_cxxscope:
1416 return TPResult::Error;
1417 if (!Tok.
is(tok::annot_typename)) {
1420 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1422 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1423 Tok.getAnnotationRange(),
1426 RevertingTentativeParsingAction PA(*
this);
1427 ConsumeAnnotationToken();
1429 bool isIdentifier = Tok.
is(tok::identifier);
1430 TPResult TPR = TPResult::False;
1432 TPR = isCXXDeclarationSpecifier(BracedCastResult,
1433 HasMissingTypename);
1436 TPR == TPResult::True || TPR == TPResult::Error)
1437 return TPResult::Error;
1439 if (HasMissingTypename) {
1442 *HasMissingTypename =
true;
1443 return TPResult::Ambiguous;
1448 switch (TryAnnotateName(
false )) {
1450 return TPResult::Error;
1451 case ANK_TentativeDecl:
1452 return TPResult::False;
1453 case ANK_TemplateName:
1458 return TPResult::Error;
1459 if (Tok.
isNot(tok::identifier))
1466 return (
getLangOpts().CPlusPlus17 || GreaterThanIsOperator)
1469 case ANK_Unresolved:
1470 return HasMissingTypename ? TPResult::Ambiguous
1477 assert(Tok.
isNot(tok::annot_cxxscope) ||
1479 return isCXXDeclarationSpecifier(BracedCastResult,
1480 HasMissingTypename);
1483 return TPResult::False;
1506 case tok::annot_typename:
1511 RevertingTentativeParsingAction PA(*
this);
1514 TPResult TPR = TryParseProtocolQualifiers();
1515 bool isFollowedByParen = Tok.
is(tok::l_paren);
1516 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1518 if (TPR == TPResult::Error)
1519 return TPResult::Error;
1521 if (isFollowedByParen)
1522 return TPResult::Ambiguous;
1525 return BracedCastResult;
1527 return TPResult::True;
1532 case tok::kw_wchar_t:
1533 case tok::kw_char8_t:
1534 case tok::kw_char16_t:
1535 case tok::kw_char32_t:
1540 case tok::kw___int64:
1541 case tok::kw___int128:
1542 case tok::kw_signed:
1543 case tok::kw_unsigned:
1546 case tok::kw_double:
1547 case tok::kw__Float16:
1548 case tok::kw___float128:
1550 case tok::annot_decltype:
1552 return TPResult::Ambiguous;
1561 return BracedCastResult;
1563 if (isStartOfObjCClassMessageMissingOpenBracket())
1564 return TPResult::False;
1566 return TPResult::True;
1569 case tok::kw_typeof: {
1571 return TPResult::True;
1573 RevertingTentativeParsingAction PA(*
this);
1575 TPResult TPR = TryParseTypeofSpecifier();
1576 bool isFollowedByParen = Tok.
is(tok::l_paren);
1577 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1579 if (TPR == TPResult::Error)
1580 return TPResult::Error;
1582 if (isFollowedByParen)
1583 return TPResult::Ambiguous;
1586 return BracedCastResult;
1588 return TPResult::True;
1592 case tok::kw___underlying_type:
1593 return TPResult::True;
1596 case tok::kw__Atomic:
1597 return TPResult::True;
1600 return TPResult::False;
1604 bool Parser::isCXXDeclarationSpecifierAType() {
1605 switch (Tok.getKind()) {
1607 case tok::annot_decltype:
1608 case tok::annot_template_id:
1609 case tok::annot_typename:
1610 case tok::kw_typeof:
1611 case tok::kw___underlying_type:
1616 case tok::kw_struct:
1618 case tok::kw___interface:
1624 case tok::kw_wchar_t:
1625 case tok::kw_char8_t:
1626 case tok::kw_char16_t:
1627 case tok::kw_char32_t:
1632 case tok::kw___int64:
1633 case tok::kw___int128:
1634 case tok::kw_signed:
1635 case tok::kw_unsigned:
1638 case tok::kw_double:
1639 case tok::kw__Float16:
1640 case tok::kw___float128:
1642 case tok::kw___unknown_anytype:
1643 case tok::kw___auto_type:
1649 case tok::kw__Atomic:
1662 Parser::TPResult Parser::TryParseTypeofSpecifier() {
1663 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1666 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1670 return TPResult::Error;
1672 return TPResult::Ambiguous;
1677 Parser::TPResult Parser::TryParseProtocolQualifiers() {
1678 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1681 if (Tok.
isNot(tok::identifier))
1682 return TPResult::Error;
1685 if (Tok.
is(tok::comma)) {
1690 if (Tok.
is(tok::greater)) {
1692 return TPResult::Ambiguous;
1696 return TPResult::Error;
1709 bool Parser::isCXXFunctionDeclarator(
bool *IsAmbiguous) {
1720 RevertingTentativeParsingAction PA(*
this);
1723 bool InvalidAsDeclaration =
false;
1724 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
1725 if (TPR == TPResult::Ambiguous) {
1726 if (Tok.
isNot(tok::r_paren))
1727 TPR = TPResult::False;
1730 if (Next.
isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1731 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1732 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1733 isCXX11VirtSpecifier(Next))
1737 TPR = TPResult::True;
1738 else if (InvalidAsDeclaration)
1740 TPR = TPResult::False;
1744 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1745 *IsAmbiguous =
true;
1748 return TPR != TPResult::False;
1769 Parser::TryParseParameterDeclarationClause(
bool *InvalidAsDeclaration,
1770 bool VersusTemplateArgument) {
1772 if (Tok.
is(tok::r_paren))
1773 return TPResult::Ambiguous;
1784 if (Tok.
is(tok::ellipsis)) {
1786 if (Tok.
is(tok::r_paren))
1787 return TPResult::True;
1789 return TPResult::False;
1793 if (isCXX11AttributeSpecifier(
false,
1795 return TPResult::True;
1798 MaybeParseMicrosoftAttributes(attrs);
1803 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
1804 InvalidAsDeclaration);
1806 if (VersusTemplateArgument && TPR == TPResult::True) {
1809 bool SeenType =
false;
1811 SeenType |= isCXXDeclarationSpecifierAType();
1812 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1813 return TPResult::Error;
1816 if (SeenType && Tok.
is(tok::identifier))
1817 return TPResult::True;
1819 TPR = isCXXDeclarationSpecifier(TPResult::False,
1820 InvalidAsDeclaration);
1821 if (TPR == TPResult::Error)
1823 }
while (TPR != TPResult::False);
1824 }
else if (TPR == TPResult::Ambiguous) {
1826 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1827 return TPResult::Error;
1833 TPR = TryParseDeclarator(
true);
1834 if (TPR != TPResult::Ambiguous)
1838 if (Tok.
is(tok::kw___attribute))
1839 return TPResult::True;
1851 if (VersusTemplateArgument)
1852 return Tok.
isOneOf(tok::equal, tok::r_paren) ? TPResult::True
1855 if (Tok.
is(tok::equal)) {
1860 return TPResult::Error;
1863 if (Tok.
is(tok::ellipsis)) {
1865 if (Tok.
is(tok::r_paren))
1866 return TPResult::True;
1868 return TPResult::False;
1875 return TPResult::Ambiguous;
1890 Parser::TPResult Parser::TryParseFunctionDeclarator() {
1894 TPResult TPR = TryParseParameterDeclarationClause();
1895 if (TPR == TPResult::Ambiguous && Tok.
isNot(tok::r_paren))
1896 TPR = TPResult::False;
1898 if (TPR == TPResult::False || TPR == TPResult::Error)
1903 return TPResult::Error;
1906 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1911 if (Tok.
isOneOf(tok::amp, tok::ampamp))
1915 if (Tok.
is(tok::kw_throw)) {
1917 if (Tok.
isNot(tok::l_paren))
1918 return TPResult::Error;
1923 return TPResult::Error;
1925 if (Tok.
is(tok::kw_noexcept)) {
1928 if (Tok.
is(tok::l_paren)) {
1932 return TPResult::Error;
1936 return TPResult::Ambiguous;
1941 Parser::TPResult Parser::TryParseBracketDeclarator() {
1944 return TPResult::Error;
1946 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.
ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement)
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.
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.
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.
Stop skipping at specified token, but don't skip the token itself.