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:
1247 case tok::kw_row_major:
1248 case tok::kw_column_major:
1251 case tok::kw_restrict:
1252 case tok::kw__Complex:
1253 case tok::kw__Imaginary:
1254 case tok::kw___attribute:
1255 case tok::kw___auto_type:
1256 return TPResult::True;
1259 case tok::kw___ob_wrap:
1260 case tok::kw___ob_trap:
1261 return TPResult::True;
1264 case tok::kw___declspec:
1265 case tok::kw___cdecl:
1266 case tok::kw___stdcall:
1267 case tok::kw___fastcall:
1268 case tok::kw___thiscall:
1269 case tok::kw___regcall:
1270 case tok::kw___vectorcall:
1272 case tok::kw___sptr:
1273 case tok::kw___uptr:
1274 case tok::kw___ptr64:
1275 case tok::kw___ptr32:
1276 case tok::kw___forceinline:
1277 case tok::kw___unaligned:
1278 case tok::kw__Nonnull:
1279 case tok::kw__Nullable:
1280 case tok::kw__Nullable_result:
1281 case tok::kw__Null_unspecified:
1282 case tok::kw___kindof:
1283 return TPResult::True;
1286 case tok::kw___funcref:
1287 return TPResult::True;
1290 case tok::kw___pascal:
1291 return TPResult::True;
1294 case tok::kw___vector:
1295 return TPResult::True;
1297 case tok::kw_this: {
1301 RevertingTentativeParsingAction PA(*
this);
1303 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1306 return TPResult::False;
1308 case tok::annot_template_id: {
1309 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1314 InvalidAsDeclSpec) {
1319 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1320 return TPResult::Ambiguous;
1323 return TPResult::Error;
1324 if (IsPlaceholderSpecifier(TemplateId, 0))
1325 return TPResult::True;
1327 return TPResult::False;
1329 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1330 assert(Tok.is(tok::annot_typename));
1334 case tok::annot_cxxscope:
1337 return TPResult::Error;
1338 if (!Tok.is(tok::annot_typename)) {
1339 if (Tok.is(tok::annot_cxxscope) &&
1341 TemplateIdAnnotation *TemplateId =
1344 if (InvalidAsDeclSpec) {
1345 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1346 return TPResult::Ambiguous;
1348 return TPResult::Error;
1350 if (IsPlaceholderSpecifier(TemplateId, 1))
1351 return TPResult::True;
1355 if (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1357 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1358 Tok.getAnnotationRange(),
1361 RevertingTentativeParsingAction PA(*
this);
1362 ConsumeAnnotationToken();
1364 bool isIdentifier = Tok.is(tok::identifier);
1365 TPResult TPR = TPResult::False;
1367 TPR = isCXXDeclarationSpecifier(
1368 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1371 TPR == TPResult::True || TPR == TPResult::Error)
1372 return TPResult::Error;
1374 if (InvalidAsDeclSpec) {
1377 *InvalidAsDeclSpec =
true;
1378 return TPResult::Ambiguous;
1384 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1387 (Tok.is(tok::ampamp) &&
NextToken().
is(tok::greater)))
1388 return TPResult::True;
1394 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1396 return TPResult::Error;
1398 return TPResult::False;
1404 return TPResult::Error;
1408 if (Tok.isNot(tok::annot_cxxscope) && Tok.isNot(tok::identifier))
1419 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1425 assert(Tok.isNot(tok::annot_cxxscope) ||
1427 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1428 BracedCastResult, InvalidAsDeclSpec);
1431 return TPResult::False;
1454 case tok::annot_typename:
1459 RevertingTentativeParsingAction PA(*
this);
1462 TPResult TPR = TryParseProtocolQualifiers();
1463 bool isFollowedByParen = Tok.is(tok::l_paren);
1464 bool isFollowedByBrace = Tok.is(tok::l_brace);
1466 if (TPR == TPResult::Error)
1467 return TPResult::Error;
1469 if (isFollowedByParen)
1470 return TPResult::Ambiguous;
1473 return BracedCastResult;
1475 return TPResult::True;
1481 case tok::kw_wchar_t:
1482 case tok::kw_char8_t:
1483 case tok::kw_char16_t:
1484 case tok::kw_char32_t:
1489 case tok::kw___int64:
1490 case tok::kw___int128:
1491 case tok::kw_signed:
1492 case tok::kw_unsigned:
1495 case tok::kw_double:
1496 case tok::kw___bf16:
1497 case tok::kw__Float16:
1498 case tok::kw___float128:
1499 case tok::kw___ibm128:
1501 case tok::annot_decltype:
1502 case tok::kw__Accum:
1503 case tok::kw__Fract:
1505 case tok::annot_pack_indexing_type:
1506#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1507#include "clang/Basic/OpenCLImageTypes.def"
1508#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1509#include "clang/Basic/HLSLIntangibleTypes.def"
1511 return TPResult::Ambiguous;
1520 return BracedCastResult;
1522 if (isStartOfObjCClassMessageMissingOpenBracket())
1523 return TPResult::False;
1525 return TPResult::True;
1528 case tok::kw_typeof: {
1530 return TPResult::True;
1532 RevertingTentativeParsingAction PA(*
this);
1534 TPResult TPR = TryParseTypeofSpecifier();
1535 bool isFollowedByParen = Tok.is(tok::l_paren);
1536 bool isFollowedByBrace = Tok.is(tok::l_brace);
1538 if (TPR == TPResult::Error)
1539 return TPResult::Error;
1541 if (isFollowedByParen)
1542 return TPResult::Ambiguous;
1545 return BracedCastResult;
1547 return TPResult::True;
1550#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1551#include "clang/Basic/TransformTypeTraits.def"
1552 return TPResult::True;
1555 case tok::kw__Alignas:
1556 return TPResult::True;
1558 case tok::kw__Atomic:
1559 return TPResult::True;
1561 case tok::kw__BitInt:
1562 case tok::kw__ExtInt: {
1564 return TPResult::Error;
1565 RevertingTentativeParsingAction PA(*
this);
1570 return TPResult::Error;
1572 if (Tok.is(tok::l_paren))
1573 return TPResult::Ambiguous;
1576 return BracedCastResult;
1578 return TPResult::True;
1581 return TPResult::False;
1585bool Parser::isCXXDeclarationSpecifierAType() {
1586 switch (Tok.getKind()) {
1588 case tok::annot_decltype:
1589 case tok::annot_pack_indexing_type:
1590 case tok::annot_template_id:
1591 case tok::annot_typename:
1592 case tok::kw_typeof:
1593#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1594#include "clang/Basic/TransformTypeTraits.def"
1599 case tok::kw_struct:
1601 case tok::kw___interface:
1607 case tok::kw_wchar_t:
1608 case tok::kw_char8_t:
1609 case tok::kw_char16_t:
1610 case tok::kw_char32_t:
1614 case tok::kw__ExtInt:
1615 case tok::kw__BitInt:
1617 case tok::kw___int64:
1618 case tok::kw___int128:
1619 case tok::kw_signed:
1620 case tok::kw_unsigned:
1623 case tok::kw_double:
1624 case tok::kw___bf16:
1625 case tok::kw__Float16:
1626 case tok::kw___float128:
1627 case tok::kw___ibm128:
1629 case tok::kw___unknown_anytype:
1630 case tok::kw___auto_type:
1631 case tok::kw__Accum:
1632 case tok::kw__Fract:
1634#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1635#include "clang/Basic/OpenCLImageTypes.def"
1636#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1637#include "clang/Basic/HLSLIntangibleTypes.def"
1643 case tok::kw__Atomic:
1652Parser::TPResult Parser::TryParseTypeofSpecifier() {
1653 assert(Tok.is(tok::kw_typeof) &&
"Expected 'typeof'!");
1656 assert(Tok.is(tok::l_paren) &&
"Expected '('");
1660 return TPResult::Error;
1662 return TPResult::Ambiguous;
1665Parser::TPResult Parser::TryParseProtocolQualifiers() {
1666 assert(Tok.is(tok::less) &&
"Expected '<' for qualifier list");
1669 if (Tok.isNot(tok::identifier))
1670 return TPResult::Error;
1673 if (Tok.is(tok::comma)) {
1678 if (Tok.is(tok::greater)) {
1680 return TPResult::Ambiguous;
1684 return TPResult::Error;
1687bool Parser::isCXXFunctionDeclarator(
1699 RevertingTentativeParsingAction PA(*
this);
1702 bool InvalidAsDeclaration =
false;
1703 TPResult TPR = TryParseParameterDeclarationClause(
1704 &InvalidAsDeclaration,
false,
1705 AllowImplicitTypename);
1706 if (TPR == TPResult::Ambiguous) {
1707 if (Tok.isNot(tok::r_paren))
1708 TPR = TPResult::False;
1711 if (
Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1712 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1713 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1714 isCXX11VirtSpecifier(
Next))
1718 TPR = TPResult::True;
1719 else if (InvalidAsDeclaration)
1721 TPR = TPResult::False;
1725 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1726 *IsAmbiguous =
true;
1729 return TPR != TPResult::False;
1732Parser::TPResult Parser::TryParseParameterDeclarationClause(
1733 bool *InvalidAsDeclaration,
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,
1760 return TPResult::True;
1762 ParsedAttributes attrs(AttrFactory);
1763 MaybeParseMicrosoftAttributes(attrs);
1768 TPResult TPR = isCXXDeclarationSpecifier(
1769 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
1772 if (TPR != TPResult::Ambiguous &&
1773 !(VersusTemplateArgument && TPR == TPResult::True))
1776 bool SeenType =
false;
1777 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
1779 SeenType |= isCXXDeclarationSpecifierAType();
1780 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1781 return TPResult::Error;
1784 if (SeenType && Tok.is(tok::identifier))
1785 return TPResult::True;
1787 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
1788 InvalidAsDeclaration);
1789 if (TPR == TPResult::Error)
1793 if (TPR == TPResult::True && !VersusTemplateArgument)
1795 }
while (TPR != TPResult::False);
1799 TPR = TryParseDeclarator(
1803 DeclarationSpecifierIsAuto);
1804 if (TPR != TPResult::Ambiguous)
1808 if (Tok.is(tok::kw___attribute))
1809 return TPResult::True;
1820 if (VersusTemplateArgument)
1821 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;
1823 if (Tok.is(tok::equal)) {
1827 return TPResult::Error;
1830 if (Tok.is(tok::ellipsis)) {
1832 if (Tok.is(tok::r_paren))
1833 return TPResult::True;
1835 return TPResult::False;
1842 return TPResult::Ambiguous;
1846Parser::TryParseFunctionDeclarator(
bool MayHaveTrailingReturnType) {
1849 TPResult TPR = TryParseParameterDeclarationClause();
1850 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
1851 TPR = TPResult::False;
1853 if (TPR == TPResult::False || TPR == TPResult::Error)
1858 return TPResult::Error;
1861 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1866 if (Tok.isOneOf(tok::amp, tok::ampamp))
1870 if (Tok.is(tok::kw_throw)) {
1872 if (Tok.isNot(tok::l_paren))
1873 return TPResult::Error;
1878 return TPResult::Error;
1880 if (Tok.is(tok::kw_noexcept)) {
1883 if (Tok.is(tok::l_paren)) {
1887 return TPResult::Error;
1892 if (!TrySkipAttributes())
1893 return TPResult::Ambiguous;
1896 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
1897 if (TPR == TPResult::True)
1900 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
1901 return TPResult::False;
1904 return TPResult::True;
1907 return TPResult::Ambiguous;
1910bool Parser::NameAfterArrowIsNonType() {
1911 assert(Tok.is(tok::identifier));
1913 if (
Next.is(tok::coloncolon))
1915 IdentifierInfo *Name = Tok.getIdentifierInfo();
1916 SourceLocation NameLoc = Tok.getLocation();
1918 TentativeParseCCC CCC(
Next);
1919 Sema::NameClassification Classification =
1921 switch (Classification.
getKind()) {
1933Parser::TPResult Parser::TryParseBracketDeclarator() {
1938 if (Tok.is(tok::l_brace))
1939 return TPResult::False;
1942 return TPResult::Error;
1946 if (Tok.isNot(tok::r_square))
1947 return TPResult::False;
1950 return TPResult::Ambiguous;
1953Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
1954 if (!TokensToSkip) {
1955 if (Tok.isNot(tok::less))
1956 return TPResult::False;
1958 return TPResult::True;
1961 RevertingTentativeParsingAction PA(*
this);
1963 while (TokensToSkip) {
1969 return TPResult::False;
1974 bool InvalidAsTemplateArgumentList =
false;
1976 &InvalidAsTemplateArgumentList) ==
1978 return TPResult::True;
1979 if (InvalidAsTemplateArgumentList)
1980 return TPResult::False;
1994 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
1996 return TPResult::Ambiguous;
1997 return TPResult::False;
2000Parser::TPResult Parser::isExplicitBool() {
2001 assert(Tok.is(tok::l_paren) &&
"expected to be looking at a '(' token");
2003 RevertingTentativeParsingAction PA(*
this);
2011 while (Tok.is(tok::l_paren))
2015 return TPResult::Error;
2020 if (Tok.is(tok::annot_cxxscope)) {
2021 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2022 Tok.getAnnotationRange(),
2024 ConsumeAnnotationToken();
2029 if (Tok.is(tok::kw_operator))
2030 return TPResult::Ambiguous;
2033 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
2034 return TPResult::True;
2035 if (!Actions.isCurrentClassName(Tok.is(tok::identifier)
2036 ? *Tok.getIdentifierInfo()
2037 : *takeTemplateIdAnnotation(Tok)->Name,
2039 return TPResult::True;
2045 !isConstructorDeclarator(SS.
isEmpty(),
2047 return TPResult::True;
2050 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.
@ 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
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.