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) {
38 RevertingTentativeParsingAction TPA(*
this);
41 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
45 switch (Tok.getKind()) {
46 case tok::identifier: {
47 IdentifierInfo *II = Tok.getIdentifierInfo();
48 bool isDeductionGuide = Actions.isDeductionGuideName(
49 getCurScope(), *II, Tok.getLocation(), SS,
nullptr);
50 if (Actions.isCurrentClassName(*II,
getCurScope(), &SS) ||
52 if (isConstructorDeclarator(
70 case tok::kw_operator:
83 if (DisambiguatingWithExpression) {
84 TentativeParsingAction TPA(*
this,
true);
88 SuppressAccessChecks AccessExporter(*
this,
true);
89 if (isCXXSimpleDeclaration(
false)) {
97 return isCXXSimpleDeclaration(
false);
101bool Parser::isCXXSimpleDeclaration(
bool AllowForRangeDecl) {
126 bool InvalidAsDeclaration =
false;
127 TPResult TPR = isCXXDeclarationSpecifier(
129 if (TPR != TPResult::Ambiguous)
130 return TPR != TPResult::False;
138 if (InvalidAsDeclaration)
149 RevertingTentativeParsingAction PA(*
this);
150 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
154 if (TPR == TPResult::Error)
158 if (TPR == TPResult::Ambiguous)
159 TPR = TPResult::True;
161 assert(TPR == TPResult::True || TPR == TPResult::False);
162 return TPR == TPResult::True;
165Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
166 switch (Tok.getKind()) {
167 case tok::kw__Atomic:
174 case tok::kw___attribute:
175#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
176#include "clang/Basic/TransformTypeTraits.def"
179 if (Tok.isNot(tok::l_paren))
180 return TPResult::Error;
183 return TPResult::Error;
190 case tok::kw___interface:
202 if (!TrySkipAttributes())
203 return TPResult::Error;
206 return TPResult::Error;
207 if (Tok.is(tok::annot_cxxscope))
208 ConsumeAnnotationToken();
209 if (Tok.is(tok::identifier))
211 else if (Tok.is(tok::annot_template_id))
212 ConsumeAnnotationToken();
214 return TPResult::Error;
217 case tok::annot_cxxscope:
218 ConsumeAnnotationToken();
224 return TryParseProtocolQualifiers();
228 return TPResult::Ambiguous;
231Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
232 bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);
233 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
234 return TPResult::Error;
239 if (Tok.isNot(tok::l_paren)) {
241 if (TPR == TPResult::Ambiguous)
242 return TPResult::True;
243 if (TPR == TPResult::True || TPR == TPResult::Error)
245 assert(TPR == TPResult::False);
248 TPResult TPR = TryParseInitDeclaratorList(
249 DeclSpecifierIsAuto);
250 if (TPR != TPResult::Ambiguous)
253 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
254 return TPResult::False;
256 return TPResult::Ambiguous;
260Parser::TryParseInitDeclaratorList(
bool MayHaveTrailingReturnType) {
263 TPResult TPR = TryParseDeclarator(
267 MayHaveTrailingReturnType);
268 if (TPR != TPResult::Ambiguous)
272 if (Tok.isOneOf(tok::kw_asm, tok::kw___attribute))
273 return TPResult::True;
276 if (Tok.is(tok::l_paren)) {
280 return TPResult::Error;
281 }
else if (Tok.is(tok::l_brace)) {
284 return TPResult::True;
285 }
else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
302 return TPResult::True;
309 return TPResult::Ambiguous;
337 RevertingTentativeParsingAction PA(
P);
341 unsigned QuestionColonDepth = 0;
343 P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
345 if (
P.Tok.is(tok::question))
346 ++QuestionColonDepth;
347 else if (
P.Tok.is(tok::colon)) {
348 if (QuestionColonDepth)
349 --QuestionColonDepth;
364 if (
P.Tok.isNot(tok::r_paren))
366 if (
P.Tok.isNot(tok::semi))
385 assert(
resolved() &&
"can't continue after tentative parsing bails out");
387 case TPResult::False:
390 case TPResult::Ambiguous:
392 case TPResult::Error:
400 ConditionOrInitStatement
result()
const {
403 "result called but not yet resolved");
405 return ConditionOrInitStatement::Expression;
407 return ConditionOrInitStatement::ConditionDecl;
409 return ConditionOrInitStatement::InitStmtDecl;
411 return ConditionOrInitStatement::ForRangeDecl;
412 return ConditionOrInitStatement::Error;
416bool Parser::isEnumBase(
bool AllowSemi) {
417 assert(
Tok.is(tok::colon) &&
"should be looking at the ':'");
419 RevertingTentativeParsingAction PA(*
this);
424 bool InvalidAsDeclSpec =
false;
431 if (R == TPResult::Ambiguous) {
434 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
439 if (
Tok.is(tok::l_brace) || (AllowSemi &&
Tok.is(tok::semi)))
447 return R != TPResult::False;
450Parser::ConditionOrInitStatement
451Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement,
452 bool CanBeForRangeDecl) {
456 if (CanBeInitStatement && Tok.is(tok::kw_using))
457 return ConditionOrInitStatement::InitStmtDecl;
459 return State.result();
462 RevertingTentativeParsingAction PA(*
this);
465 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
466 if (State.update(TryConsumeDeclarationSpecifier()))
467 return State.result();
468 assert(Tok.is(tok::l_paren) &&
"Expected '('");
472 if (State.update(TryParseDeclarator(
476 MayHaveTrailingReturnType)))
477 return State.result();
482 if (Tok.isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
484 State.markNotExpression();
485 return State.result();
489 if (State.CanBeForRangeDecl && Tok.is(tok::colon))
490 return ConditionOrInitStatement::ForRangeDecl;
494 if (State.markNotCondition())
495 return State.result();
498 if (State.markNotForRangeDecl())
499 return State.result();
503 if (Tok.is(tok::l_paren)) {
513 if (State.CanBeCondition && Tok.is(tok::r_paren))
514 return ConditionOrInitStatement::ConditionDecl;
515 else if (State.CanBeInitStatement && Tok.is(tok::semi))
516 return ConditionOrInitStatement::InitStmtDecl;
518 return ConditionOrInitStatement::Expression;
533 if (TPR != TPResult::Ambiguous)
534 return TPR != TPResult::False;
543 RevertingTentativeParsingAction PA(*
this);
544 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
547 TryConsumeDeclarationSpecifier();
548 assert(Tok.is(tok::l_paren) &&
"Expected '('");
551 TPR = TryParseDeclarator(
true ,
false ,
553 MayHaveTrailingReturnType);
556 if (TPR == TPResult::Error)
557 TPR = TPResult::True;
559 if (TPR == TPResult::Ambiguous) {
563 Tok.is(tok::r_paren)) {
564 TPR = TPResult::True;
569 }
else if (Context ==
571 Tok.is(tok::comma)) {
572 TPR = TPResult::True;
579 (Tok.isOneOf(tok::greater, tok::comma) ||
581 (Tok.isOneOf(tok::greatergreater,
582 tok::greatergreatergreater) ||
583 (Tok.is(tok::ellipsis) &&
585 tok::greatergreatergreater,
587 TPR = TPResult::True;
591 TPR = TPResult::True;
594 TPR = TPResult::True;
597 TPR = TPResult::False;
600 assert(TPR == TPResult::True || TPR == TPResult::False);
601 return TPR == TPResult::True;
605Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
606 bool OuterMightBeMessageSend) {
611 if (Tok.isRegularKeywordAttribute())
625 RevertingTentativeParsingAction PA(*
this);
633 bool IsAttribute =
SkipUntil(tok::r_square);
634 IsAttribute &= Tok.is(tok::r_square);
653 RevertingTentativeParsingAction LambdaTPA(*
this);
654 LambdaIntroducer Intro;
655 LambdaIntroducerTentativeParse Tentative;
656 if (ParseLambdaIntroducer(Intro, &Tentative)) {
664 case LambdaIntroducerTentativeParse::MessageSend:
669 case LambdaIntroducerTentativeParse::Success:
670 case LambdaIntroducerTentativeParse::Incomplete:
672 if (Tok.is(tok::r_square))
676 if (OuterMightBeMessageSend)
683 case LambdaIntroducerTentativeParse::Invalid:
694 bool IsAttribute =
true;
695 while (Tok.isNot(tok::r_square)) {
696 if (Tok.is(tok::comma)) {
707 if (!TryParseCXX11AttributeIdentifier(Loc)) {
711 if (Tok.is(tok::coloncolon)) {
713 if (!TryParseCXX11AttributeIdentifier(Loc)) {
720 if (Tok.is(tok::l_paren)) {
736 if (Tok.is(tok::r_square)) {
738 IsAttribute = Tok.is(tok::r_square);
752bool Parser::TrySkipAttributes() {
753 while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
755 Tok.isRegularKeywordAttribute()) {
756 if (Tok.is(tok::l_square)) {
763 if (!
SkipUntil(tok::r_square) || Tok.isNot(tok::r_square))
768 }
else if (Tok.isRegularKeywordAttribute() &&
773 if (Tok.isNot(tok::l_paren))
784Parser::TPResult Parser::TryParsePtrOperatorSeq() {
787 return TPResult::Error;
789 if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
790 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
795 if (!TrySkipAttributes())
796 return TPResult::Error;
798 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
799 tok::kw__Nonnull, tok::kw__Nullable,
800 tok::kw__Nullable_result, tok::kw__Null_unspecified,
804 return TPResult::True;
809Parser::TPResult Parser::TryParseOperatorId() {
810 assert(Tok.is(tok::kw_operator));
814 switch (Tok.getKind()) {
815 case tok::kw_new:
case tok::kw_delete:
817 if (Tok.is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
821 return TPResult::True;
823#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
825#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
826#include "clang/Basic/OperatorKinds.def"
828 return TPResult::True;
834 return TPResult::True;
842 return TPResult::True;
852 bool FoundUDSuffix =
false;
854 FoundUDSuffix |= Tok.hasUDSuffix();
855 ConsumeStringToken();
856 }
while (isTokenStringLiteral());
858 if (!FoundUDSuffix) {
859 if (Tok.is(tok::identifier))
862 return TPResult::Error;
864 return TPResult::True;
868 bool AnyDeclSpecifiers =
false;
871 if (TPR == TPResult::Error)
873 if (TPR == TPResult::False) {
874 if (!AnyDeclSpecifiers)
875 return TPResult::Error;
878 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
879 return TPResult::Error;
880 AnyDeclSpecifiers =
true;
882 return TryParsePtrOperatorSeq();
885Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
886 bool mayHaveIdentifier,
887 bool mayHaveDirectInit,
888 bool mayHaveTrailingReturnType) {
892 if (TryParsePtrOperatorSeq() == TPResult::Error)
893 return TPResult::Error;
897 if (Tok.is(tok::ellipsis))
900 if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||
901 (Tok.is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
905 if (Tok.is(tok::annot_cxxscope)) {
907 Actions.RestoreNestedNameSpecifierAnnotation(
908 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
910 return TPResult::Error;
911 ConsumeAnnotationToken();
912 }
else if (Tok.is(tok::identifier)) {
913 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
915 if (Tok.is(tok::kw_operator)) {
916 if (TryParseOperatorId() == TPResult::Error)
917 return TPResult::Error;
920 }
else if (Tok.is(tok::l_paren)) {
923 (Tok.is(tok::r_paren) ||
925 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren)) ||
926 isDeclarationSpecifier(
930 TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
931 if (TPR != TPResult::Ambiguous)
937 if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
938 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
939 tok::kw___regcall, tok::kw___vectorcall))
940 return TPResult::True;
941 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
942 if (TPR != TPResult::Ambiguous)
944 if (Tok.isNot(tok::r_paren))
945 return TPResult::False;
948 }
else if (!mayBeAbstract) {
949 return TPResult::False;
952 if (mayHaveDirectInit)
953 return TPResult::Ambiguous;
956 TPResult TPR(TPResult::Ambiguous);
958 if (Tok.is(tok::l_paren)) {
963 if (!mayBeAbstract && !isCXXFunctionDeclarator())
969 TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
970 }
else if (Tok.is(tok::l_square)) {
973 TPR = TryParseBracketDeclarator();
974 }
else if (Tok.is(tok::kw_requires)) {
977 TPR = TPResult::True;
982 if (TPR != TPResult::Ambiguous)
986 return TPResult::Ambiguous;
990 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
996 TentativeParseCCC(
const Token &
Next) {
997 WantRemainingKeywords =
false;
999 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
1000 tok::identifier, tok::comma);
1003 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1007 llvm::all_of(Candidate,
1008 [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
1014 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
1015 return std::make_unique<TentativeParseCCC>(*
this);
1022 Parser::TPResult BracedCastResult,
1023 bool *InvalidAsDeclSpec) {
1024 auto IsPlaceholderSpecifier = [&](TemplateIdAnnotation *TemplateId,
1030 .
isOneOf(tok::kw_auto, tok::kw_decltype,
1040 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
1053 switch (Tok.getKind()) {
1054 case tok::identifier: {
1059 return TPResult::Error;
1060 if (Tok.is(tok::identifier))
1061 return TPResult::False;
1063 BracedCastResult, InvalidAsDeclSpec);
1068 if (TryAltiVecVectorToken())
1069 return TPResult::True;
1074 return TPResult::True;
1079 if (
Next.is(tok::l_paren) &&
1080 Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier() &&
1081 isRevertibleTypeTrait(Tok.getIdentifierInfo())) {
1082 return TPResult::False;
1085 if (
Next.isNoneOf(tok::coloncolon, tok::less, tok::colon)) {
1090 TentativeParseCCC CCC(
Next);
1091 switch (TryAnnotateName(&CCC)) {
1093 return TPResult::Error;
1095 return TPResult::False;
1103 return TPResult::Error;
1104 if (Tok.isNot(tok::identifier))
1110 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1112 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1116 assert(Tok.isNot(tok::identifier) &&
1117 "TryAnnotateName succeeded without producing an annotation");
1124 return TPResult::Error;
1128 if (Tok.is(tok::identifier))
1129 return TPResult::False;
1133 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1137 case tok::kw_typename:
1141 return TPResult::Error;
1143 BracedCastResult, InvalidAsDeclSpec);
1145 case tok::kw_auto: {
1147 return TPResult::True;
1149 return TPResult::False;
1151 return TPResult::Ambiguous;
1152 return TPResult::True;
1155 case tok::coloncolon: {
1157 if (
Next.isOneOf(tok::kw_new,
1159 return TPResult::False;
1162 case tok::kw___super:
1163 case tok::kw_decltype:
1167 return TPResult::Error;
1168 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1178 case tok::kw_friend:
1179 case tok::kw_typedef:
1180 case tok::kw_constexpr:
1181 case tok::kw_consteval:
1182 case tok::kw_constinit:
1184 case tok::kw_register:
1185 case tok::kw_static:
1186 case tok::kw_extern:
1187 case tok::kw_mutable:
1188 case tok::kw___thread:
1189 case tok::kw_thread_local:
1190 case tok::kw__Thread_local:
1192 case tok::kw_inline:
1193 case tok::kw_virtual:
1194 case tok::kw_explicit:
1195 case tok::kw__Noreturn:
1198 case tok::kw___module_private__:
1201 case tok::kw___unknown_anytype:
1214 case tok::kw_struct:
1216 case tok::kw___interface:
1221 case tok::kw_volatile:
1222 return TPResult::True;
1225 case tok::kw_private:
1227 return TPResult::False;
1229 case tok::kw___private:
1230 case tok::kw___local:
1231 case tok::kw___global:
1232 case tok::kw___constant:
1233 case tok::kw___generic:
1235 case tok::kw___read_only:
1236 case tok::kw___write_only:
1237 case tok::kw___read_write:
1242 case tok::kw_groupshared:
1248 case tok::kw_restrict:
1249 case tok::kw__Complex:
1250 case tok::kw__Imaginary:
1251 case tok::kw___attribute:
1252 case tok::kw___auto_type:
1253 return TPResult::True;
1256 case tok::kw___ob_wrap:
1257 case tok::kw___ob_trap:
1258 return TPResult::True;
1261 case tok::kw___declspec:
1262 case tok::kw___cdecl:
1263 case tok::kw___stdcall:
1264 case tok::kw___fastcall:
1265 case tok::kw___thiscall:
1266 case tok::kw___regcall:
1267 case tok::kw___vectorcall:
1269 case tok::kw___sptr:
1270 case tok::kw___uptr:
1271 case tok::kw___ptr64:
1272 case tok::kw___ptr32:
1273 case tok::kw___forceinline:
1274 case tok::kw___unaligned:
1275 case tok::kw__Nonnull:
1276 case tok::kw__Nullable:
1277 case tok::kw__Nullable_result:
1278 case tok::kw__Null_unspecified:
1279 case tok::kw___kindof:
1280 return TPResult::True;
1283 case tok::kw___funcref:
1284 return TPResult::True;
1287 case tok::kw___pascal:
1288 return TPResult::True;
1291 case tok::kw___vector:
1292 return TPResult::True;
1294 case tok::kw_this: {
1298 RevertingTentativeParsingAction PA(*
this);
1300 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1303 return TPResult::False;
1305 case tok::annot_template_id: {
1306 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1311 InvalidAsDeclSpec) {
1316 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1317 return TPResult::Ambiguous;
1320 return TPResult::Error;
1321 if (IsPlaceholderSpecifier(TemplateId, 0))
1322 return TPResult::True;
1324 return TPResult::False;
1326 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1327 assert(Tok.is(tok::annot_typename));
1331 case tok::annot_cxxscope:
1334 return TPResult::Error;
1335 if (!Tok.is(tok::annot_typename)) {
1336 if (Tok.is(tok::annot_cxxscope) &&
1338 TemplateIdAnnotation *TemplateId =
1341 if (InvalidAsDeclSpec) {
1342 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1343 return TPResult::Ambiguous;
1345 return TPResult::Error;
1347 if (IsPlaceholderSpecifier(TemplateId, 1))
1348 return TPResult::True;
1352 if (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1354 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1355 Tok.getAnnotationRange(),
1358 RevertingTentativeParsingAction PA(*
this);
1359 ConsumeAnnotationToken();
1361 bool isIdentifier = Tok.is(tok::identifier);
1362 TPResult TPR = TPResult::False;
1364 TPR = isCXXDeclarationSpecifier(
1365 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1368 TPR == TPResult::True || TPR == TPResult::Error)
1369 return TPResult::Error;
1371 if (InvalidAsDeclSpec) {
1374 *InvalidAsDeclSpec =
true;
1375 return TPResult::Ambiguous;
1381 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1384 (Tok.is(tok::ampamp) &&
NextToken().
is(tok::greater)))
1385 return TPResult::True;
1391 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1393 return TPResult::Error;
1395 return TPResult::False;
1401 return TPResult::Error;
1405 if (Tok.isNot(tok::annot_cxxscope) && Tok.isNot(tok::identifier))
1416 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1422 assert(Tok.isNot(tok::annot_cxxscope) ||
1424 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1425 BracedCastResult, InvalidAsDeclSpec);
1428 return TPResult::False;
1451 case tok::annot_typename:
1456 RevertingTentativeParsingAction PA(*
this);
1459 TPResult TPR = TryParseProtocolQualifiers();
1460 bool isFollowedByParen = Tok.is(tok::l_paren);
1461 bool isFollowedByBrace = Tok.is(tok::l_brace);
1463 if (TPR == TPResult::Error)
1464 return TPResult::Error;
1466 if (isFollowedByParen)
1467 return TPResult::Ambiguous;
1470 return BracedCastResult;
1472 return TPResult::True;
1478 case tok::kw_wchar_t:
1479 case tok::kw_char8_t:
1480 case tok::kw_char16_t:
1481 case tok::kw_char32_t:
1486 case tok::kw___int64:
1487 case tok::kw___int128:
1488 case tok::kw_signed:
1489 case tok::kw_unsigned:
1492 case tok::kw_double:
1493 case tok::kw___bf16:
1494 case tok::kw__Float16:
1495 case tok::kw___float128:
1496 case tok::kw___ibm128:
1498 case tok::annot_decltype:
1499 case tok::kw__Accum:
1500 case tok::kw__Fract:
1502 case tok::annot_pack_indexing_type:
1503#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1504#include "clang/Basic/OpenCLImageTypes.def"
1505#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1506#include "clang/Basic/HLSLIntangibleTypes.def"
1508 return TPResult::Ambiguous;
1517 return BracedCastResult;
1519 if (isStartOfObjCClassMessageMissingOpenBracket())
1520 return TPResult::False;
1522 return TPResult::True;
1525 case tok::kw_typeof: {
1527 return TPResult::True;
1529 RevertingTentativeParsingAction PA(*
this);
1531 TPResult TPR = TryParseTypeofSpecifier();
1532 bool isFollowedByParen = Tok.is(tok::l_paren);
1533 bool isFollowedByBrace = Tok.is(tok::l_brace);
1535 if (TPR == TPResult::Error)
1536 return TPResult::Error;
1538 if (isFollowedByParen)
1539 return TPResult::Ambiguous;
1542 return BracedCastResult;
1544 return TPResult::True;
1547#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1548#include "clang/Basic/TransformTypeTraits.def"
1549 return TPResult::True;
1552 case tok::kw__Alignas:
1553 return TPResult::True;
1555 case tok::kw__Atomic:
1556 return TPResult::True;
1558 case tok::kw__BitInt:
1559 case tok::kw__ExtInt: {
1561 return TPResult::Error;
1562 RevertingTentativeParsingAction PA(*
this);
1567 return TPResult::Error;
1569 if (Tok.is(tok::l_paren))
1570 return TPResult::Ambiguous;
1573 return BracedCastResult;
1575 return TPResult::True;
1578 return TPResult::False;
1582bool Parser::isCXXDeclarationSpecifierAType() {
1583 switch (Tok.getKind()) {
1585 case tok::annot_decltype:
1586 case tok::annot_pack_indexing_type:
1587 case tok::annot_template_id:
1588 case tok::annot_typename:
1589 case tok::kw_typeof:
1590#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1591#include "clang/Basic/TransformTypeTraits.def"
1596 case tok::kw_struct:
1598 case tok::kw___interface:
1604 case tok::kw_wchar_t:
1605 case tok::kw_char8_t:
1606 case tok::kw_char16_t:
1607 case tok::kw_char32_t:
1611 case tok::kw__ExtInt:
1612 case tok::kw__BitInt:
1614 case tok::kw___int64:
1615 case tok::kw___int128:
1616 case tok::kw_signed:
1617 case tok::kw_unsigned:
1620 case tok::kw_double:
1621 case tok::kw___bf16:
1622 case tok::kw__Float16:
1623 case tok::kw___float128:
1624 case tok::kw___ibm128:
1626 case tok::kw___unknown_anytype:
1627 case tok::kw___auto_type:
1628 case tok::kw__Accum:
1629 case tok::kw__Fract:
1631#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1632#include "clang/Basic/OpenCLImageTypes.def"
1633#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1634#include "clang/Basic/HLSLIntangibleTypes.def"
1640 case tok::kw__Atomic:
1649Parser::TPResult Parser::TryParseTypeofSpecifier() {
1650 assert(Tok.is(tok::kw_typeof) &&
"Expected 'typeof'!");
1653 assert(Tok.is(tok::l_paren) &&
"Expected '('");
1657 return TPResult::Error;
1659 return TPResult::Ambiguous;
1662Parser::TPResult Parser::TryParseProtocolQualifiers() {
1663 assert(Tok.is(tok::less) &&
"Expected '<' for qualifier list");
1666 if (Tok.isNot(tok::identifier))
1667 return TPResult::Error;
1670 if (Tok.is(tok::comma)) {
1675 if (Tok.is(tok::greater)) {
1677 return TPResult::Ambiguous;
1681 return TPResult::Error;
1684bool Parser::isCXXFunctionDeclarator(
1696 RevertingTentativeParsingAction PA(*
this);
1699 bool InvalidAsDeclaration =
false;
1700 TPResult TPR = TryParseParameterDeclarationClause(
1701 &InvalidAsDeclaration,
false,
1702 AllowImplicitTypename);
1703 if (TPR == TPResult::Ambiguous) {
1704 if (Tok.isNot(tok::r_paren))
1705 TPR = TPResult::False;
1708 if (
Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1709 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1710 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1711 isCXX11VirtSpecifier(
Next))
1715 TPR = TPResult::True;
1716 else if (InvalidAsDeclaration)
1718 TPR = TPResult::False;
1722 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1723 *IsAmbiguous =
true;
1726 return TPR != TPResult::False;
1729Parser::TPResult Parser::TryParseParameterDeclarationClause(
1730 bool *InvalidAsDeclaration,
bool VersusTemplateArgument,
1733 if (Tok.is(tok::r_paren))
1734 return TPResult::Ambiguous;
1745 if (Tok.is(tok::ellipsis)) {
1747 if (Tok.is(tok::r_paren))
1748 return TPResult::True;
1750 return TPResult::False;
1754 if (isCXX11AttributeSpecifier(
false,
1757 return TPResult::True;
1759 ParsedAttributes attrs(AttrFactory);
1760 MaybeParseMicrosoftAttributes(attrs);
1765 TPResult TPR = isCXXDeclarationSpecifier(
1766 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
1769 if (TPR != TPResult::Ambiguous &&
1770 !(VersusTemplateArgument && TPR == TPResult::True))
1773 bool SeenType =
false;
1774 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
1776 SeenType |= isCXXDeclarationSpecifierAType();
1777 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1778 return TPResult::Error;
1781 if (SeenType && Tok.is(tok::identifier))
1782 return TPResult::True;
1784 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
1785 InvalidAsDeclaration);
1786 if (TPR == TPResult::Error)
1790 if (TPR == TPResult::True && !VersusTemplateArgument)
1792 }
while (TPR != TPResult::False);
1796 TPR = TryParseDeclarator(
1800 DeclarationSpecifierIsAuto);
1801 if (TPR != TPResult::Ambiguous)
1805 if (Tok.is(tok::kw___attribute))
1806 return TPResult::True;
1817 if (VersusTemplateArgument)
1818 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;
1820 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;
1843Parser::TryParseFunctionDeclarator(
bool MayHaveTrailingReturnType) {
1846 TPResult TPR = TryParseParameterDeclarationClause();
1847 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
1848 TPR = TPResult::False;
1850 if (TPR == TPResult::False || TPR == TPResult::Error)
1855 return TPResult::Error;
1858 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1863 if (Tok.isOneOf(tok::amp, tok::ampamp))
1867 if (Tok.is(tok::kw_throw)) {
1869 if (Tok.isNot(tok::l_paren))
1870 return TPResult::Error;
1875 return TPResult::Error;
1877 if (Tok.is(tok::kw_noexcept)) {
1880 if (Tok.is(tok::l_paren)) {
1884 return TPResult::Error;
1889 if (!TrySkipAttributes())
1890 return TPResult::Ambiguous;
1893 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
1894 if (TPR == TPResult::True)
1897 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
1898 return TPResult::False;
1901 return TPResult::True;
1904 return TPResult::Ambiguous;
1907bool Parser::NameAfterArrowIsNonType() {
1908 assert(Tok.is(tok::identifier));
1910 if (
Next.is(tok::coloncolon))
1912 IdentifierInfo *Name = Tok.getIdentifierInfo();
1913 SourceLocation NameLoc = Tok.getLocation();
1915 TentativeParseCCC CCC(
Next);
1916 Sema::NameClassification Classification =
1918 switch (Classification.
getKind()) {
1930Parser::TPResult Parser::TryParseBracketDeclarator() {
1935 if (Tok.is(tok::l_brace))
1936 return TPResult::False;
1939 return TPResult::Error;
1943 if (Tok.isNot(tok::r_square))
1944 return TPResult::False;
1947 return TPResult::Ambiguous;
1950Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
1951 if (!TokensToSkip) {
1952 if (Tok.isNot(tok::less))
1953 return TPResult::False;
1955 return TPResult::True;
1958 RevertingTentativeParsingAction PA(*
this);
1960 while (TokensToSkip) {
1966 return TPResult::False;
1971 bool InvalidAsTemplateArgumentList =
false;
1973 &InvalidAsTemplateArgumentList) ==
1975 return TPResult::True;
1976 if (InvalidAsTemplateArgumentList)
1977 return TPResult::False;
1991 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
1993 return TPResult::Ambiguous;
1994 return TPResult::False;
1997Parser::TPResult Parser::isExplicitBool() {
1998 assert(Tok.is(tok::l_paren) &&
"expected to be looking at a '(' token");
2000 RevertingTentativeParsingAction PA(*
this);
2008 while (Tok.is(tok::l_paren))
2012 return TPResult::Error;
2017 if (Tok.is(tok::annot_cxxscope)) {
2018 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2019 Tok.getAnnotationRange(),
2021 ConsumeAnnotationToken();
2026 if (Tok.is(tok::kw_operator))
2027 return TPResult::Ambiguous;
2030 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
2031 return TPResult::True;
2032 if (!Actions.isCurrentClassName(Tok.is(tok::identifier)
2033 ? *Tok.getIdentifierInfo()
2034 : *takeTemplateIdAnnotation(Tok)->Name,
2036 return TPResult::True;
2042 !isConstructorDeclarator(SS.
isEmpty(),
2044 return TPResult::True;
2047 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.
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.
@ StopAtSemi
Stop skipping at semicolon.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
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
The JSON file list parser is used to communicate input to InstallAPI.
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.