19bool Parser::isCXXDeclarationStatement(
20 bool DisambiguatingWithExpression ) {
23 switch (Tok.getKind()) {
27 case tok::kw_namespace:
32 case tok::kw_static_assert:
33 case tok::kw__Static_assert:
36 case tok::identifier: {
37 if (DisambiguatingWithExpression) {
42 RevertingTentativeParsingAction TPA(*
this,
true);
43 SuppressAccessChecks AccessSuppressor(*
this,
true);
46 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
50 switch (Tok.getKind()) {
51 case tok::identifier: {
52 IdentifierInfo *II = Tok.getIdentifierInfo();
53 bool isDeductionGuide = Actions.isDeductionGuideName(
54 getCurScope(), *II, Tok.getLocation(), SS,
nullptr);
55 if (Actions.isCurrentClassName(*II,
getCurScope(), &SS) ||
57 if (isConstructorDeclarator(
75 case tok::kw_operator:
86 RevertingTentativeParsingAction TPA(*
this);
88 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
97 if (DisambiguatingWithExpression) {
98 TentativeParsingAction TPA(*
this,
true);
102 SuppressAccessChecks AccessExporter(*
this,
true);
103 if (isCXXSimpleDeclaration(
false)) {
111 return isCXXSimpleDeclaration(
false);
115bool Parser::isCXXSimpleDeclaration(
bool AllowForRangeDecl) {
140 bool InvalidAsDeclaration =
false;
141 TPResult TPR = isCXXDeclarationSpecifier(
143 if (TPR != TPResult::Ambiguous)
144 return TPR != TPResult::False;
152 if (InvalidAsDeclaration)
163 RevertingTentativeParsingAction PA(*
this);
164 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
168 if (TPR == TPResult::Error)
172 if (TPR == TPResult::Ambiguous)
173 TPR = TPResult::True;
175 assert(TPR == TPResult::True || TPR == TPResult::False);
176 return TPR == TPResult::True;
179Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
180 switch (Tok.getKind()) {
181 case tok::kw__Atomic:
188 case tok::kw_typeof_unqual:
189 case tok::kw___attribute:
190#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
191#include "clang/Basic/BuiltinTraits.inc"
194 if (Tok.isNot(tok::l_paren))
195 return TPResult::Error;
198 return TPResult::Error;
205 case tok::kw___interface:
217 if (!TrySkipAttributes())
218 return TPResult::Error;
221 return TPResult::Error;
222 if (Tok.is(tok::annot_cxxscope))
223 ConsumeAnnotationToken();
224 if (Tok.is(tok::identifier))
226 else if (Tok.is(tok::annot_template_id))
227 ConsumeAnnotationToken();
229 return TPResult::Error;
232 case tok::annot_cxxscope:
233 ConsumeAnnotationToken();
239 return TryParseProtocolQualifiers();
243 return TPResult::Ambiguous;
246Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
247 bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);
248 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
249 return TPResult::Error;
254 if (Tok.isNot(tok::l_paren)) {
256 if (TPR == TPResult::Ambiguous)
257 return TPResult::True;
258 if (TPR == TPResult::True || TPR == TPResult::Error)
260 assert(TPR == TPResult::False);
263 TPResult TPR = TryParseInitDeclaratorList(
264 DeclSpecifierIsAuto);
265 if (TPR != TPResult::Ambiguous)
268 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
269 return TPResult::False;
271 return TPResult::Ambiguous;
275Parser::TryParseInitDeclaratorList(
bool MayHaveTrailingReturnType) {
278 TPResult TPR = TryParseDeclarator(
282 MayHaveTrailingReturnType);
283 if (TPR != TPResult::Ambiguous)
287 if (Tok.isOneOf(tok::kw_asm, tok::kw___attribute))
288 return TPResult::True;
291 if (Tok.is(tok::l_paren)) {
295 return TPResult::Error;
296 }
else if (Tok.is(tok::l_brace)) {
299 return TPResult::True;
300 }
else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
317 return TPResult::True;
324 return TPResult::Ambiguous;
352 RevertingTentativeParsingAction PA(
P);
356 unsigned QuestionColonDepth = 0;
358 P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
360 if (
P.Tok.is(tok::question))
361 ++QuestionColonDepth;
362 else if (
P.Tok.is(tok::colon)) {
363 if (QuestionColonDepth)
364 --QuestionColonDepth;
379 if (
P.Tok.isNot(tok::r_paren))
381 if (
P.Tok.isNot(tok::semi))
400 assert(
resolved() &&
"can't continue after tentative parsing bails out");
402 case TPResult::False:
405 case TPResult::Ambiguous:
407 case TPResult::Error:
415 ConditionOrInitStatement
result()
const {
418 "result called but not yet resolved");
420 return ConditionOrInitStatement::Expression;
422 return ConditionOrInitStatement::ConditionDecl;
424 return ConditionOrInitStatement::InitStmtDecl;
426 return ConditionOrInitStatement::ForRangeDecl;
427 return ConditionOrInitStatement::Error;
431bool Parser::isEnumBase(
bool AllowSemi) {
432 assert(
Tok.is(tok::colon) &&
"should be looking at the ':'");
434 RevertingTentativeParsingAction PA(*
this);
439 bool InvalidAsDeclSpec =
false;
446 if (R == TPResult::Ambiguous) {
449 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
454 if (
Tok.is(tok::l_brace) || (AllowSemi &&
Tok.is(tok::semi)))
462 return R != TPResult::False;
465Parser::ConditionOrInitStatement
466Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement,
467 bool CanBeForRangeDecl) {
471 if (CanBeInitStatement && Tok.is(tok::kw_using))
472 return ConditionOrInitStatement::InitStmtDecl;
474 return State.result();
477 RevertingTentativeParsingAction PA(*
this);
480 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
481 if (State.update(TryConsumeDeclarationSpecifier()))
482 return State.result();
483 assert(Tok.is(tok::l_paren) &&
"Expected '('");
487 if (State.update(TryParseDeclarator(
491 MayHaveTrailingReturnType)))
492 return State.result();
497 if (Tok.isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
499 State.markNotExpression();
500 return State.result();
504 if (State.CanBeForRangeDecl && Tok.is(tok::colon))
505 return ConditionOrInitStatement::ForRangeDecl;
509 if (State.markNotCondition())
510 return State.result();
513 if (State.markNotForRangeDecl())
514 return State.result();
518 if (Tok.is(tok::l_paren)) {
528 if (State.CanBeCondition && Tok.is(tok::r_paren))
529 return ConditionOrInitStatement::ConditionDecl;
530 else if (State.CanBeInitStatement && Tok.is(tok::semi))
531 return ConditionOrInitStatement::InitStmtDecl;
533 return ConditionOrInitStatement::Expression;
548 if (TPR != TPResult::Ambiguous)
549 return TPR != TPResult::False;
558 RevertingTentativeParsingAction PA(*
this);
559 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
562 TryConsumeDeclarationSpecifier();
563 assert(Tok.is(tok::l_paren) &&
"Expected '('");
566 TPR = TryParseDeclarator(
true ,
false ,
568 MayHaveTrailingReturnType);
571 if (TPR == TPResult::Error)
572 TPR = TPResult::True;
574 if (TPR == TPResult::Ambiguous) {
578 Tok.is(tok::r_paren)) {
579 TPR = TPResult::True;
584 }
else if (Context ==
586 Tok.is(tok::comma)) {
587 TPR = TPResult::True;
594 (Tok.isOneOf(tok::greater, tok::comma) ||
596 (Tok.isOneOf(tok::greatergreater,
597 tok::greatergreatergreater) ||
598 (Tok.is(tok::ellipsis) &&
600 tok::greatergreatergreater,
602 TPR = TPResult::True;
606 TPR = TPResult::True;
609 TPR = TPResult::True;
612 TPR = TPResult::False;
615 assert(TPR == TPResult::True || TPR == TPResult::False);
616 return TPR == TPResult::True;
620Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
621 bool OuterMightBeMessageSend) {
626 if (Tok.isRegularKeywordAttribute())
640 RevertingTentativeParsingAction PA(*
this);
648 bool IsAttribute =
SkipUntil(tok::r_square);
649 IsAttribute &= Tok.is(tok::r_square);
668 RevertingTentativeParsingAction LambdaTPA(*
this);
669 LambdaIntroducer Intro;
670 LambdaIntroducerTentativeParse Tentative;
671 if (ParseLambdaIntroducer(Intro, &Tentative)) {
679 case LambdaIntroducerTentativeParse::MessageSend:
684 case LambdaIntroducerTentativeParse::Success:
685 case LambdaIntroducerTentativeParse::Incomplete:
687 if (Tok.is(tok::r_square))
691 if (OuterMightBeMessageSend)
698 case LambdaIntroducerTentativeParse::Invalid:
709 bool IsAttribute =
true;
710 while (Tok.isNot(tok::r_square)) {
711 if (Tok.is(tok::comma)) {
722 if (!TryParseCXX11AttributeIdentifier(Loc)) {
726 if (Tok.is(tok::coloncolon)) {
728 if (!TryParseCXX11AttributeIdentifier(Loc)) {
735 if (Tok.is(tok::l_paren)) {
751 if (Tok.is(tok::r_square)) {
753 IsAttribute = Tok.is(tok::r_square);
767bool Parser::TrySkipAttributes() {
768 while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
770 Tok.isRegularKeywordAttribute()) {
771 if (Tok.is(tok::l_square)) {
778 if (!
SkipUntil(tok::r_square) || Tok.isNot(tok::r_square))
783 }
else if (Tok.isRegularKeywordAttribute() &&
788 if (Tok.isNot(tok::l_paren))
799bool Parser::hasLambdaLikeContinuation() {
800 RevertingTentativeParsingAction TPA(*
this);
808 if (!TrySkipAttributes())
811 if (Tok.isOneOf(tok::l_paren, tok::l_brace, tok::less, tok::arrow,
812 tok::kw_requires, tok::kw_noexcept))
820 if (!isLambdaSpecifier())
827Parser::TPResult Parser::TryParsePtrOperatorSeq() {
830 return TPResult::Error;
832 if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
833 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
838 if (!TrySkipAttributes())
839 return TPResult::Error;
841 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
842 tok::kw__Nonnull, tok::kw__Nullable,
843 tok::kw__Nullable_result, tok::kw__Null_unspecified,
847 return TPResult::True;
852Parser::TPResult Parser::TryParseOperatorId() {
853 assert(Tok.is(tok::kw_operator));
857 switch (Tok.getKind()) {
858 case tok::kw_new:
case tok::kw_delete:
860 if (Tok.is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
864 return TPResult::True;
866#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
868#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
869#include "clang/Basic/OperatorKinds.def"
871 return TPResult::True;
877 return TPResult::True;
885 return TPResult::True;
889 case tok::lesslessless:
894 return TPResult::True;
902 bool FoundUDSuffix =
false;
904 FoundUDSuffix |= Tok.hasUDSuffix();
905 ConsumeStringToken();
906 }
while (isTokenStringLiteral());
908 if (!FoundUDSuffix) {
909 if (Tok.is(tok::identifier))
912 return TPResult::Error;
914 return TPResult::True;
918 bool AnyDeclSpecifiers =
false;
921 if (TPR == TPResult::Error)
923 if (TPR == TPResult::False) {
924 if (!AnyDeclSpecifiers)
925 return TPResult::Error;
928 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
929 return TPResult::Error;
930 AnyDeclSpecifiers =
true;
932 return TryParsePtrOperatorSeq();
935Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
936 bool mayHaveIdentifier,
937 bool mayHaveDirectInit,
938 bool mayHaveTrailingReturnType) {
942 if (TryParsePtrOperatorSeq() == TPResult::Error)
943 return TPResult::Error;
947 if (Tok.is(tok::ellipsis))
950 if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||
951 (Tok.is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
955 if (Tok.is(tok::annot_cxxscope)) {
957 Actions.RestoreNestedNameSpecifierAnnotation(
958 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
960 return TPResult::Error;
961 ConsumeAnnotationToken();
962 }
else if (Tok.is(tok::identifier)) {
963 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
965 if (Tok.is(tok::kw_operator)) {
966 if (TryParseOperatorId() == TPResult::Error)
967 return TPResult::Error;
970 }
else if (Tok.is(tok::l_paren)) {
973 (Tok.is(tok::r_paren) ||
975 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren)) ||
976 isDeclarationSpecifier(
980 TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
981 if (TPR != TPResult::Ambiguous)
987 if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
988 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
989 tok::kw___regcall, tok::kw___vectorcall))
990 return TPResult::True;
991 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
992 if (TPR != TPResult::Ambiguous)
994 if (Tok.isNot(tok::r_paren))
995 return TPResult::False;
998 }
else if (!mayBeAbstract) {
999 return TPResult::False;
1002 if (mayHaveDirectInit)
1003 return TPResult::Ambiguous;
1006 TPResult TPR(TPResult::Ambiguous);
1008 if (Tok.is(tok::l_paren)) {
1013 if (!mayBeAbstract && !isCXXFunctionDeclarator())
1019 TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
1020 }
else if (Tok.is(tok::l_square)) {
1023 TPR = TryParseBracketDeclarator();
1024 }
else if (Tok.is(tok::kw_requires)) {
1027 TPR = TPResult::True;
1032 if (TPR != TPResult::Ambiguous)
1036 return TPResult::Ambiguous;
1040 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
1046 TentativeParseCCC(
const Token &
Next) {
1047 WantRemainingKeywords =
false;
1048 WantTypeSpecifiers =
1049 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
1050 tok::identifier, tok::comma);
1053 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1057 llvm::all_of(Candidate,
1058 [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
1064 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
1065 return std::make_unique<TentativeParseCCC>(*
this);
1072 Parser::TPResult BracedCastResult,
1073 bool *InvalidAsDeclSpec) {
1074 auto IsPlaceholderSpecifier = [&](TemplateIdAnnotation *TemplateId,
1080 .
isOneOf(tok::kw_auto, tok::kw_decltype,
1090 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
1103 switch (Tok.getKind()) {
1104 case tok::identifier: {
1109 return TPResult::Error;
1110 if (Tok.is(tok::identifier))
1111 return TPResult::False;
1113 BracedCastResult, InvalidAsDeclSpec);
1118 if (TryAltiVecVectorToken())
1119 return TPResult::True;
1124 return TPResult::True;
1129 if (
Next.is(tok::l_paren) &&
1130 Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier() &&
1131 isRevertibleTypeTrait(Tok.getIdentifierInfo())) {
1132 return TPResult::False;
1135 if (
Next.isNoneOf(tok::coloncolon, tok::less, tok::colon)) {
1140 TentativeParseCCC CCC(
Next);
1141 switch (TryAnnotateName(&CCC)) {
1143 return TPResult::Error;
1145 return TPResult::False;
1153 return TPResult::Error;
1154 if (Tok.isNot(tok::identifier))
1160 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1162 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1166 assert(Tok.isNot(tok::identifier) &&
1167 "TryAnnotateName succeeded without producing an annotation");
1174 return TPResult::Error;
1178 if (Tok.is(tok::identifier))
1179 return TPResult::False;
1183 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1187 case tok::kw_typename:
1191 return TPResult::Error;
1193 BracedCastResult, InvalidAsDeclSpec);
1195 case tok::kw_auto: {
1197 return TPResult::False;
1199 return TPResult::Ambiguous;
1200 return TPResult::True;
1203 case tok::coloncolon: {
1205 if (
Next.isOneOf(tok::kw_new,
1207 return TPResult::False;
1210 case tok::kw___super:
1211 case tok::kw_decltype:
1215 return TPResult::Error;
1216 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1226 case tok::kw_friend:
1227 case tok::kw_typedef:
1228 case tok::kw_constexpr:
1229 case tok::kw_consteval:
1230 case tok::kw_constinit:
1232 case tok::kw_register:
1233 case tok::kw_static:
1234 case tok::kw_extern:
1235 case tok::kw_mutable:
1236 case tok::kw___thread:
1237 case tok::kw_thread_local:
1238 case tok::kw__Thread_local:
1240 case tok::kw_inline:
1241 case tok::kw_virtual:
1242 case tok::kw_explicit:
1243 case tok::kw__Noreturn:
1246 case tok::kw___module_private__:
1249 case tok::kw___unknown_anytype:
1262 case tok::kw_struct:
1264 case tok::kw___interface:
1269 case tok::kw_volatile:
1270 return TPResult::True;
1273 case tok::kw_private:
1275 return TPResult::False;
1277 case tok::kw___private:
1278 case tok::kw___local:
1279 case tok::kw___global:
1280 case tok::kw___constant:
1281 case tok::kw___generic:
1283 case tok::kw___read_only:
1284 case tok::kw___write_only:
1285 case tok::kw___read_write:
1290 case tok::kw_groupshared:
1295 case tok::kw_row_major:
1296 case tok::kw_column_major:
1299 case tok::kw_restrict:
1300 case tok::kw__Complex:
1301 case tok::kw__Imaginary:
1302 case tok::kw___attribute:
1303 case tok::kw___auto_type:
1304 return TPResult::True;
1307 case tok::kw___ob_wrap:
1308 case tok::kw___ob_trap:
1309 return TPResult::True;
1312 case tok::kw___declspec:
1313 case tok::kw___cdecl:
1314 case tok::kw___stdcall:
1315 case tok::kw___fastcall:
1316 case tok::kw___thiscall:
1317 case tok::kw___regcall:
1318 case tok::kw___vectorcall:
1320 case tok::kw___sptr:
1321 case tok::kw___uptr:
1322 case tok::kw___ptr64:
1323 case tok::kw___ptr32:
1324 case tok::kw___forceinline:
1325 case tok::kw___unaligned:
1326 case tok::kw__Nonnull:
1327 case tok::kw__Nullable:
1328 case tok::kw__Nullable_result:
1329 case tok::kw__Null_unspecified:
1330 case tok::kw___kindof:
1331 return TPResult::True;
1334 case tok::kw___funcref:
1335 return TPResult::True;
1338 case tok::kw___pascal:
1339 return TPResult::True;
1342 case tok::kw___vector:
1343 return TPResult::True;
1345 case tok::kw_this: {
1349 RevertingTentativeParsingAction PA(*
this);
1351 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1354 return TPResult::False;
1356 case tok::annot_template_id: {
1357 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1362 InvalidAsDeclSpec) {
1367 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1368 return TPResult::Ambiguous;
1371 return TPResult::Error;
1372 if (IsPlaceholderSpecifier(TemplateId, 0))
1373 return TPResult::True;
1375 return TPResult::False;
1377 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1378 assert(Tok.is(tok::annot_typename));
1382 case tok::annot_cxxscope:
1385 return TPResult::Error;
1386 if (!Tok.is(tok::annot_typename)) {
1387 if (Tok.is(tok::annot_cxxscope) &&
1389 TemplateIdAnnotation *TemplateId =
1392 if (InvalidAsDeclSpec) {
1393 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1394 return TPResult::Ambiguous;
1396 return TPResult::Error;
1398 if (IsPlaceholderSpecifier(TemplateId, 1))
1399 return TPResult::True;
1403 if (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1405 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1406 Tok.getAnnotationRange(),
1409 RevertingTentativeParsingAction PA(*
this);
1410 ConsumeAnnotationToken();
1412 bool isIdentifier = Tok.is(tok::identifier);
1413 TPResult TPR = TPResult::False;
1415 TPR = isCXXDeclarationSpecifier(
1416 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1419 TPR == TPResult::True || TPR == TPResult::Error)
1420 return TPResult::Error;
1422 if (InvalidAsDeclSpec) {
1425 *InvalidAsDeclSpec =
true;
1426 return TPResult::Ambiguous;
1432 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1435 (Tok.is(tok::ampamp) &&
NextToken().
is(tok::greater)))
1436 return TPResult::True;
1442 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1444 return TPResult::Error;
1446 return TPResult::False;
1452 return TPResult::Error;
1456 if (Tok.isNot(tok::annot_cxxscope) && Tok.isNot(tok::identifier))
1467 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1473 assert(Tok.isNot(tok::annot_cxxscope) ||
1475 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1476 BracedCastResult, InvalidAsDeclSpec);
1479 return TPResult::False;
1502 case tok::annot_typename:
1507 RevertingTentativeParsingAction PA(*
this);
1510 TPResult TPR = TryParseProtocolQualifiers();
1511 bool isFollowedByParen = Tok.is(tok::l_paren);
1512 bool isFollowedByBrace = Tok.is(tok::l_brace);
1514 if (TPR == TPResult::Error)
1515 return TPResult::Error;
1517 if (isFollowedByParen)
1518 return TPResult::Ambiguous;
1521 return BracedCastResult;
1523 return TPResult::True;
1529 case tok::kw_wchar_t:
1530 case tok::kw_char8_t:
1531 case tok::kw_char16_t:
1532 case tok::kw_char32_t:
1537 case tok::kw___int64:
1538 case tok::kw___int128:
1539 case tok::kw_signed:
1540 case tok::kw_unsigned:
1543 case tok::kw_double:
1544 case tok::kw___bf16:
1545 case tok::kw__Float16:
1546 case tok::kw___float128:
1547 case tok::kw___ibm128:
1549 case tok::annot_decltype:
1550 case tok::kw__Accum:
1551 case tok::kw__Fract:
1553 case tok::annot_pack_indexing_type:
1554#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1555#include "clang/Basic/OpenCLImageTypes.def"
1556#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1557#include "clang/Basic/HLSLIntangibleTypes.def"
1559 return TPResult::Ambiguous;
1568 return BracedCastResult;
1570 if (isStartOfObjCClassMessageMissingOpenBracket())
1571 return TPResult::False;
1573 return TPResult::True;
1576 case tok::kw_typeof:
1577 case tok::kw_typeof_unqual: {
1579 return TPResult::True;
1581 RevertingTentativeParsingAction PA(*
this);
1583 TPResult TPR = TryParseTypeofSpecifier();
1584 bool isFollowedByParen = Tok.is(tok::l_paren);
1585 bool isFollowedByBrace = Tok.is(tok::l_brace);
1587 if (TPR == TPResult::Error)
1588 return TPResult::Error;
1590 if (isFollowedByParen)
1591 return TPResult::Ambiguous;
1594 return BracedCastResult;
1596 return TPResult::True;
1599#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1600#include "clang/Basic/BuiltinTraits.inc"
1601 return TPResult::True;
1604 case tok::kw__Alignas:
1605 return TPResult::True;
1607 case tok::kw__Atomic:
1608 return TPResult::True;
1610 case tok::kw__BitInt:
1611 case tok::kw__ExtInt: {
1613 return TPResult::Error;
1614 RevertingTentativeParsingAction PA(*
this);
1619 return TPResult::Error;
1621 if (Tok.is(tok::l_paren))
1622 return TPResult::Ambiguous;
1625 return BracedCastResult;
1627 return TPResult::True;
1630 return TPResult::False;
1634bool Parser::isCXXDeclarationSpecifierAType() {
1635 switch (Tok.getKind()) {
1637 case tok::annot_decltype:
1638 case tok::annot_pack_indexing_type:
1639 case tok::annot_template_id:
1640 case tok::annot_typename:
1641 case tok::kw_typeof:
1642 case tok::kw_typeof_unqual:
1643#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1644#include "clang/Basic/BuiltinTraits.inc"
1649 case tok::kw_struct:
1651 case tok::kw___interface:
1657 case tok::kw_wchar_t:
1658 case tok::kw_char8_t:
1659 case tok::kw_char16_t:
1660 case tok::kw_char32_t:
1664 case tok::kw__ExtInt:
1665 case tok::kw__BitInt:
1667 case tok::kw___int64:
1668 case tok::kw___int128:
1669 case tok::kw_signed:
1670 case tok::kw_unsigned:
1673 case tok::kw_double:
1674 case tok::kw___bf16:
1675 case tok::kw__Float16:
1676 case tok::kw___float128:
1677 case tok::kw___ibm128:
1679 case tok::kw___unknown_anytype:
1680 case tok::kw___auto_type:
1681 case tok::kw__Accum:
1682 case tok::kw__Fract:
1684#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1685#include "clang/Basic/OpenCLImageTypes.def"
1686#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1687#include "clang/Basic/HLSLIntangibleTypes.def"
1693 case tok::kw__Atomic:
1702Parser::TPResult Parser::TryParseTypeofSpecifier() {
1703 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
1704 "Expected 'typeof' or 'typeof_unqual'!");
1707 assert(Tok.is(tok::l_paren) &&
"Expected '('");
1711 return TPResult::Error;
1713 return TPResult::Ambiguous;
1716Parser::TPResult Parser::TryParseProtocolQualifiers() {
1717 assert(Tok.is(tok::less) &&
"Expected '<' for qualifier list");
1720 if (Tok.isNot(tok::identifier))
1721 return TPResult::Error;
1724 if (Tok.is(tok::comma)) {
1729 if (Tok.is(tok::greater)) {
1731 return TPResult::Ambiguous;
1735 return TPResult::Error;
1738bool Parser::isCXXFunctionDeclarator(
1750 RevertingTentativeParsingAction PA(*
this);
1753 bool InvalidAsDeclaration =
false;
1754 TPResult TPR = TryParseParameterDeclarationClause(
1755 &InvalidAsDeclaration,
false,
1756 AllowImplicitTypename);
1757 if (TPR == TPResult::Ambiguous) {
1758 if (Tok.isNot(tok::r_paren))
1759 TPR = TPResult::False;
1762 if (
Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1763 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1764 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1765 isCXX11VirtSpecifier(
Next))
1769 TPR = TPResult::True;
1770 else if (InvalidAsDeclaration)
1772 TPR = TPResult::False;
1776 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1777 *IsAmbiguous =
true;
1780 return TPR != TPResult::False;
1783Parser::TPResult Parser::TryParseParameterDeclarationClause(
1784 bool *InvalidAsDeclaration,
bool VersusTemplateArgument,
1787 if (Tok.is(tok::r_paren))
1788 return TPResult::Ambiguous;
1799 if (Tok.is(tok::ellipsis)) {
1801 if (Tok.is(tok::r_paren))
1802 return TPResult::True;
1804 return TPResult::False;
1808 if (isCXX11AttributeSpecifier(
false,
1811 return TPResult::True;
1814 Tok.is(tok::l_square) && hasLambdaLikeContinuation())
1815 return TPResult::False;
1817 ParsedAttributes attrs(AttrFactory);
1818 MaybeParseMicrosoftAttributes(attrs);
1823 TPResult TPR = isCXXDeclarationSpecifier(
1824 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
1827 if (TPR != TPResult::Ambiguous &&
1828 !(VersusTemplateArgument && TPR == TPResult::True))
1831 bool SeenType =
false;
1832 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
1834 SeenType |= isCXXDeclarationSpecifierAType();
1835 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1836 return TPResult::Error;
1839 if (SeenType && Tok.is(tok::identifier))
1840 return TPResult::True;
1842 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
1843 InvalidAsDeclaration);
1844 if (TPR == TPResult::Error)
1848 if (TPR == TPResult::True && !VersusTemplateArgument)
1850 }
while (TPR != TPResult::False);
1854 TPR = TryParseDeclarator(
1858 DeclarationSpecifierIsAuto);
1859 if (TPR != TPResult::Ambiguous)
1863 if (Tok.is(tok::kw___attribute))
1864 return TPResult::True;
1875 if (VersusTemplateArgument)
1876 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;
1878 if (Tok.is(tok::equal)) {
1882 return TPResult::Error;
1885 if (Tok.is(tok::ellipsis)) {
1887 if (Tok.is(tok::r_paren))
1888 return TPResult::True;
1890 return TPResult::False;
1897 return TPResult::Ambiguous;
1901Parser::TryParseFunctionDeclarator(
bool MayHaveTrailingReturnType) {
1904 TPResult TPR = TryParseParameterDeclarationClause();
1905 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
1906 TPR = TPResult::False;
1908 if (TPR == TPResult::False || TPR == TPResult::Error)
1913 return TPResult::Error;
1916 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1921 if (Tok.isOneOf(tok::amp, tok::ampamp))
1925 if (Tok.is(tok::kw_throw)) {
1927 if (Tok.isNot(tok::l_paren))
1928 return TPResult::Error;
1933 return TPResult::Error;
1935 if (Tok.is(tok::kw_noexcept)) {
1938 if (Tok.is(tok::l_paren)) {
1942 return TPResult::Error;
1947 if (!TrySkipAttributes())
1948 return TPResult::Ambiguous;
1951 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
1952 if (TPR == TPResult::True)
1955 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
1956 return TPResult::False;
1959 return TPResult::True;
1962 return TPResult::Ambiguous;
1965bool Parser::NameAfterArrowIsNonType() {
1966 assert(Tok.is(tok::identifier));
1968 if (
Next.is(tok::coloncolon))
1970 IdentifierInfo *Name = Tok.getIdentifierInfo();
1971 SourceLocation NameLoc = Tok.getLocation();
1973 TentativeParseCCC CCC(
Next);
1974 Sema::NameClassification Classification =
1976 switch (Classification.
getKind()) {
1988Parser::TPResult Parser::TryParseBracketDeclarator() {
1993 if (Tok.is(tok::l_brace))
1994 return TPResult::False;
1997 return TPResult::Error;
2001 if (Tok.isNot(tok::r_square))
2002 return TPResult::False;
2005 return TPResult::Ambiguous;
2008Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
2009 if (!TokensToSkip) {
2010 if (Tok.isNot(tok::less))
2011 return TPResult::False;
2013 return TPResult::True;
2016 RevertingTentativeParsingAction PA(*
this);
2018 while (TokensToSkip) {
2024 return TPResult::False;
2029 bool InvalidAsTemplateArgumentList =
false;
2031 &InvalidAsTemplateArgumentList) ==
2033 return TPResult::True;
2034 if (InvalidAsTemplateArgumentList)
2035 return TPResult::False;
2049 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2051 return TPResult::Ambiguous;
2052 return TPResult::False;
2055Parser::TPResult Parser::isExplicitBool() {
2056 assert(Tok.is(tok::l_paren) &&
"expected to be looking at a '(' token");
2058 RevertingTentativeParsingAction PA(*
this);
2066 while (Tok.is(tok::l_paren))
2070 return TPResult::Error;
2075 if (Tok.is(tok::annot_cxxscope)) {
2076 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2077 Tok.getAnnotationRange(),
2079 ConsumeAnnotationToken();
2084 if (Tok.is(tok::kw_operator))
2085 return TPResult::Ambiguous;
2088 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
2089 return TPResult::True;
2090 if (!Actions.isCurrentClassName(Tok.is(tok::identifier)
2091 ? *Tok.getIdentifierInfo()
2092 : *takeTemplateIdAnnotation(Tok)->Name,
2094 return TPResult::True;
2100 !isConstructorDeclarator(SS.
isEmpty(),
2102 return TPResult::True;
2105 return TPResult::Ambiguous;
static constexpr bool isOneOf()
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
NestedNameSpecifier getScopeRep() const
Retrieve the representation of the nested-name-specifier.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
bool isEmpty() const
No scope specifier.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
One of these records is kept for each identifier that is lexed.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, bool IsAddressOfOperand=false)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies)
bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext=false)
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() 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 ...
const LangOptions & getLangOpts() const
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
NameClassificationKind getKind() const
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 isOneOf(Ts... Ks) const
Top level wrappers for InstallAPI frontend operations.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
CXX11AttributeKind
The kind of attribute specifier we have found.
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ Unresolved
The identifier can't be resolved.
@ Success
Annotation was successful.
@ Error
Annotation has failed and emitted an error.
@ TentativeDecl
The identifier is a tentatively-declared name.
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
TentativeCXXTypeIdContext
Specifies the context in which type-id/expression disambiguation will occur.
@ AsGenericSelectionArgument
@ FunctionTemplate
The name was classified as a function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ VarTemplate
The name was classified as a variable template name.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
bool markNotForRangeDecl()
ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement, bool CanBeForRangeDecl)
bool update(TPResult IsDecl)
ConditionOrInitStatement result() const
bool hasInvalidName() const
TemplateNameKind Kind
The kind of template that Template refers to.
unsigned NumArgs
NumArgs - The number of template arguments.