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) {
880 if (TryParsePtrOperatorSeq() == TPResult::Error)
881 return TPResult::Error;
885 if (Tok.
is(tok::ellipsis))
888 if ((Tok.
isOneOf(tok::identifier, tok::kw_operator) ||
889 (Tok.
is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
893 if (Tok.
is(tok::annot_cxxscope))
894 ConsumeAnnotationToken();
895 else if (Tok.
is(tok::identifier))
896 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
897 if (Tok.
is(tok::kw_operator)) {
898 if (TryParseOperatorId() == TPResult::Error)
899 return TPResult::Error;
902 }
else if (Tok.
is(tok::l_paren)) {
905 (Tok.
is(tok::r_paren) ||
908 isDeclarationSpecifier())) {
911 TPResult TPR = TryParseFunctionDeclarator();
912 if (TPR != TPResult::Ambiguous)
918 if (Tok.
isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
919 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
920 tok::kw___regcall, tok::kw___vectorcall))
921 return TPResult::True;
922 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
923 if (TPR != TPResult::Ambiguous)
925 if (Tok.
isNot(tok::r_paren))
926 return TPResult::False;
929 }
else if (!mayBeAbstract) {
930 return TPResult::False;
934 TPResult TPR(TPResult::Ambiguous);
936 if (Tok.
is(tok::l_paren)) {
941 if (!mayBeAbstract && !isCXXFunctionDeclarator())
947 TPR = TryParseFunctionDeclarator();
948 }
else if (Tok.
is(tok::l_square)) {
951 TPR = TryParseBracketDeclarator();
956 if (TPR != TPResult::Ambiguous)
960 return TPResult::Ambiguous;
967 case tok::numeric_constant:
968 case tok::char_constant:
969 case tok::wide_char_constant:
970 case tok::utf8_char_constant:
971 case tok::utf16_char_constant:
972 case tok::utf32_char_constant:
973 case tok::string_literal:
974 case tok::wide_string_literal:
975 case tok::utf8_string_literal:
976 case tok::utf16_string_literal:
977 case tok::utf32_string_literal:
986 case tok::minusminus:
990 case tok::kw___func__:
991 case tok::kw_const_cast:
993 case tok::kw_dynamic_cast:
996 case tok::kw_operator:
997 case tok::kw_reinterpret_cast:
998 case tok::kw_static_cast:
1002 case tok::kw_typeid:
1003 case tok::kw_alignof:
1004 case tok::kw_noexcept:
1005 case tok::kw_nullptr:
1006 case tok::kw__Alignof:
1007 case tok::kw___null:
1008 case tok::kw___alignof:
1009 case tok::kw___builtin_choose_expr:
1010 case tok::kw___builtin_offsetof:
1011 case tok::kw___builtin_va_arg:
1012 case tok::kw___imag:
1013 case tok::kw___real:
1014 case tok::kw___FUNCTION__:
1015 case tok::kw___FUNCDNAME__:
1016 case tok::kw___FUNCSIG__:
1017 case tok::kw_L__FUNCTION__:
1018 case tok::kw___PRETTY_FUNCTION__:
1019 case tok::kw___uuidof:
1020 #define TYPE_TRAIT(N,Spelling,K) \ 1021 case tok::kw_##Spelling: 1022 #include "clang/Basic/TokenKinds.def" 1023 return TPResult::True;
1028 case tok::kw_double:
1029 case tok::kw__Float16:
1030 case tok::kw___float128:
1036 case tok::kw___int64:
1037 case tok::kw___int128:
1038 case tok::kw_restrict:
1040 case tok::kw_signed:
1041 case tok::kw_struct:
1043 case tok::kw_unsigned:
1045 case tok::kw_volatile:
1047 case tok::kw__Complex:
1049 case tok::kw_typename:
1050 case tok::kw_wchar_t:
1051 case tok::kw_char16_t:
1052 case tok::kw_char32_t:
1053 case tok::kw__Decimal32:
1054 case tok::kw__Decimal64:
1055 case tok::kw__Decimal128:
1056 case tok::kw___interface:
1057 case tok::kw___thread:
1058 case tok::kw_thread_local:
1059 case tok::kw__Thread_local:
1060 case tok::kw_typeof:
1061 case tok::kw___underlying_type:
1062 case tok::kw___cdecl:
1063 case tok::kw___stdcall:
1064 case tok::kw___fastcall:
1065 case tok::kw___thiscall:
1066 case tok::kw___regcall:
1067 case tok::kw___vectorcall:
1068 case tok::kw___unaligned:
1069 case tok::kw___vector:
1070 case tok::kw___pixel:
1071 case tok::kw___bool:
1072 case tok::kw__Atomic:
1073 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: 1074 #include "clang/Basic/OpenCLImageTypes.def" 1075 case tok::kw___unknown_anytype:
1076 return TPResult::False;
1082 return TPResult::Ambiguous;
1086 return std::find(TentativelyDeclaredIdentifiers.begin(),
1087 TentativelyDeclaredIdentifiers.end(), II)
1088 != TentativelyDeclaredIdentifiers.end();
1094 TentativeParseCCC(
const Token &Next) {
1095 WantRemainingKeywords =
false;
1096 WantTypeSpecifiers = Next.
isOneOf(tok::l_paren, tok::r_paren, tok::greater,
1097 tok::l_brace, tok::identifier);
1100 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1104 std::all_of(Candidate.
begin(), Candidate.
end(),
1105 [](
NamedDecl *ND) {
return ND->isCXXInstanceMember(); }))
1219 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1220 bool *HasMissingTypename) {
1221 switch (Tok.getKind()) {
1222 case tok::identifier: {
1225 if (TryAltiVecVectorToken())
1226 return TPResult::True;
1231 return TPResult::True;
1233 if (Next.
isNot(tok::coloncolon) && Next.
isNot(tok::less)) {
1238 switch (TryAnnotateName(
false ,
1239 llvm::make_unique<TentativeParseCCC>(Next))) {
1241 return TPResult::Error;
1242 case ANK_TentativeDecl:
1243 return TPResult::False;
1244 case ANK_TemplateName:
1247 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1248 case ANK_Unresolved:
1249 return HasMissingTypename ? TPResult::Ambiguous : TPResult::False;
1253 assert(Tok.
isNot(tok::identifier) &&
1254 "TryAnnotateName succeeded without producing an annotation");
1261 return TPResult::Error;
1265 if (Tok.
is(tok::identifier))
1266 return TPResult::False;
1270 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1273 case tok::kw_typename:
1277 return TPResult::Error;
1278 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1280 case tok::coloncolon: {
1284 return TPResult::False;
1287 case tok::kw___super:
1288 case tok::kw_decltype:
1292 return TPResult::Error;
1293 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1302 case tok::kw_friend:
1303 case tok::kw_typedef:
1304 case tok::kw_constexpr:
1306 case tok::kw_register:
1307 case tok::kw_static:
1308 case tok::kw_extern:
1309 case tok::kw_mutable:
1311 case tok::kw___thread:
1312 case tok::kw_thread_local:
1313 case tok::kw__Thread_local:
1315 case tok::kw_inline:
1316 case tok::kw_virtual:
1317 case tok::kw_explicit:
1320 case tok::kw___module_private__:
1323 case tok::kw___unknown_anytype:
1336 case tok::kw_struct:
1338 case tok::kw___interface:
1343 case tok::kw_volatile:
1346 case tok::kw_restrict:
1347 case tok::kw__Complex:
1348 case tok::kw___attribute:
1349 case tok::kw___auto_type:
1350 return TPResult::True;
1353 case tok::kw___declspec:
1354 case tok::kw___cdecl:
1355 case tok::kw___stdcall:
1356 case tok::kw___fastcall:
1357 case tok::kw___thiscall:
1358 case tok::kw___regcall:
1359 case tok::kw___vectorcall:
1361 case tok::kw___sptr:
1362 case tok::kw___uptr:
1363 case tok::kw___ptr64:
1364 case tok::kw___ptr32:
1365 case tok::kw___forceinline:
1366 case tok::kw___unaligned:
1367 case tok::kw__Nonnull:
1368 case tok::kw__Nullable:
1369 case tok::kw__Null_unspecified:
1370 case tok::kw___kindof:
1371 return TPResult::True;
1374 case tok::kw___pascal:
1375 return TPResult::True;
1378 case tok::kw___vector:
1379 return TPResult::True;
1381 case tok::annot_template_id: {
1384 return TPResult::False;
1386 AnnotateTemplateIdTokenAsType();
1387 assert(Tok.
is(tok::annot_typename));
1391 case tok::annot_cxxscope:
1394 return TPResult::Error;
1395 if (!Tok.
is(tok::annot_typename)) {
1398 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1400 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1401 Tok.getAnnotationRange(),
1404 RevertingTentativeParsingAction PA(*
this);
1405 ConsumeAnnotationToken();
1407 bool isIdentifier = Tok.
is(tok::identifier);
1408 TPResult TPR = TPResult::False;
1410 TPR = isCXXDeclarationSpecifier(BracedCastResult,
1411 HasMissingTypename);
1414 TPR == TPResult::True || TPR == TPResult::Error)
1415 return TPResult::Error;
1417 if (HasMissingTypename) {
1420 *HasMissingTypename =
true;
1421 return TPResult::Ambiguous;
1428 switch (TryAnnotateName(
false )) {
1430 return TPResult::Error;
1431 case ANK_TentativeDecl:
1432 return TPResult::False;
1433 case ANK_TemplateName:
1436 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1437 case ANK_Unresolved:
1438 return HasMissingTypename ? TPResult::Ambiguous
1442 assert(Tok.
isNot(tok::annot_cxxscope) ||
1444 return isCXXDeclarationSpecifier(BracedCastResult,
1445 HasMissingTypename);
1449 return TPResult::False;
1472 case tok::annot_typename:
1477 RevertingTentativeParsingAction PA(*
this);
1480 TPResult TPR = TryParseProtocolQualifiers();
1481 bool isFollowedByParen = Tok.
is(tok::l_paren);
1482 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1484 if (TPR == TPResult::Error)
1485 return TPResult::Error;
1487 if (isFollowedByParen)
1488 return TPResult::Ambiguous;
1491 return BracedCastResult;
1493 return TPResult::True;
1498 case tok::kw_wchar_t:
1499 case tok::kw_char16_t:
1500 case tok::kw_char32_t:
1505 case tok::kw___int64:
1506 case tok::kw___int128:
1507 case tok::kw_signed:
1508 case tok::kw_unsigned:
1511 case tok::kw_double:
1512 case tok::kw__Float16:
1513 case tok::kw___float128:
1515 case tok::annot_decltype:
1517 return TPResult::Ambiguous;
1526 return BracedCastResult;
1528 if (isStartOfObjCClassMessageMissingOpenBracket())
1529 return TPResult::False;
1531 return TPResult::True;
1534 case tok::kw_typeof: {
1536 return TPResult::True;
1538 RevertingTentativeParsingAction PA(*
this);
1540 TPResult TPR = TryParseTypeofSpecifier();
1541 bool isFollowedByParen = Tok.
is(tok::l_paren);
1542 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1544 if (TPR == TPResult::Error)
1545 return TPResult::Error;
1547 if (isFollowedByParen)
1548 return TPResult::Ambiguous;
1551 return BracedCastResult;
1553 return TPResult::True;
1557 case tok::kw___underlying_type:
1558 return TPResult::True;
1561 case tok::kw__Atomic:
1562 return TPResult::True;
1565 return TPResult::False;
1569 bool Parser::isCXXDeclarationSpecifierAType() {
1570 switch (Tok.getKind()) {
1572 case tok::annot_decltype:
1573 case tok::annot_template_id:
1574 case tok::annot_typename:
1575 case tok::kw_typeof:
1576 case tok::kw___underlying_type:
1581 case tok::kw_struct:
1583 case tok::kw___interface:
1589 case tok::kw_wchar_t:
1590 case tok::kw_char16_t:
1591 case tok::kw_char32_t:
1596 case tok::kw___int64:
1597 case tok::kw___int128:
1598 case tok::kw_signed:
1599 case tok::kw_unsigned:
1602 case tok::kw_double:
1603 case tok::kw__Float16:
1604 case tok::kw___float128:
1606 case tok::kw___unknown_anytype:
1607 case tok::kw___auto_type:
1613 case tok::kw__Atomic:
1626 Parser::TPResult Parser::TryParseTypeofSpecifier() {
1627 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1630 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1634 return TPResult::Error;
1636 return TPResult::Ambiguous;
1641 Parser::TPResult Parser::TryParseProtocolQualifiers() {
1642 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1645 if (Tok.
isNot(tok::identifier))
1646 return TPResult::Error;
1649 if (Tok.
is(tok::comma)) {
1654 if (Tok.
is(tok::greater)) {
1656 return TPResult::Ambiguous;
1660 return TPResult::Error;
1673 bool Parser::isCXXFunctionDeclarator(
bool *IsAmbiguous) {
1684 RevertingTentativeParsingAction PA(*
this);
1687 bool InvalidAsDeclaration =
false;
1688 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
1689 if (TPR == TPResult::Ambiguous) {
1690 if (Tok.
isNot(tok::r_paren))
1691 TPR = TPResult::False;
1694 if (Next.
isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1695 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1696 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1697 isCXX11VirtSpecifier(Next))
1701 TPR = TPResult::True;
1702 else if (InvalidAsDeclaration)
1704 TPR = TPResult::False;
1708 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1709 *IsAmbiguous =
true;
1712 return TPR != TPResult::False;
1733 Parser::TryParseParameterDeclarationClause(
bool *InvalidAsDeclaration,
1734 bool VersusTemplateArgument) {
1736 if (Tok.
is(tok::r_paren))
1737 return TPResult::Ambiguous;
1748 if (Tok.
is(tok::ellipsis)) {
1750 if (Tok.
is(tok::r_paren))
1751 return TPResult::True;
1753 return TPResult::False;
1757 if (isCXX11AttributeSpecifier(
false,
1759 return TPResult::True;
1762 MaybeParseMicrosoftAttributes(attrs);
1767 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
1768 InvalidAsDeclaration);
1770 if (VersusTemplateArgument && TPR == TPResult::True) {
1773 bool SeenType =
false;
1775 SeenType |= isCXXDeclarationSpecifierAType();
1776 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1777 return TPResult::Error;
1780 if (SeenType && Tok.
is(tok::identifier))
1781 return TPResult::True;
1783 TPR = isCXXDeclarationSpecifier(TPResult::False,
1784 InvalidAsDeclaration);
1785 if (TPR == TPResult::Error)
1787 }
while (TPR != TPResult::False);
1788 }
else if (TPR == TPResult::Ambiguous) {
1790 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1791 return TPResult::Error;
1797 TPR = TryParseDeclarator(
true);
1798 if (TPR != TPResult::Ambiguous)
1802 if (Tok.
is(tok::kw___attribute))
1803 return TPResult::True;
1815 if (VersusTemplateArgument)
1816 return Tok.
isOneOf(tok::equal, tok::r_paren) ? TPResult::True
1819 if (Tok.
is(tok::equal)) {
1824 return TPResult::Error;
1827 if (Tok.
is(tok::ellipsis)) {
1829 if (Tok.
is(tok::r_paren))
1830 return TPResult::True;
1832 return TPResult::False;
1839 return TPResult::Ambiguous;
1854 Parser::TPResult Parser::TryParseFunctionDeclarator() {
1858 TPResult TPR = TryParseParameterDeclarationClause();
1859 if (TPR == TPResult::Ambiguous && Tok.
isNot(tok::r_paren))
1860 TPR = TPResult::False;
1862 if (TPR == TPResult::False || TPR == TPResult::Error)
1867 return TPResult::Error;
1870 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict))
1874 if (Tok.
isOneOf(tok::amp, tok::ampamp))
1878 if (Tok.
is(tok::kw_throw)) {
1880 if (Tok.
isNot(tok::l_paren))
1881 return TPResult::Error;
1886 return TPResult::Error;
1888 if (Tok.
is(tok::kw_noexcept)) {
1891 if (Tok.
is(tok::l_paren)) {
1895 return TPResult::Error;
1899 return TPResult::Ambiguous;
1904 Parser::TPResult Parser::TryParseBracketDeclarator() {
1907 return TPResult::Error;
1909 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.
NamedDecl - This represents a decl with a name.
ParsedAttributes - A collection of parsed attributes.
Stop skipping at specified token, but don't skip the token itself.