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_typeof_unqual:
175 case tok::kw___attribute:
176#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
177#include "clang/Basic/TransformTypeTraits.def"
180 if (Tok.isNot(tok::l_paren))
181 return TPResult::Error;
184 return TPResult::Error;
191 case tok::kw___interface:
203 if (!TrySkipAttributes())
204 return TPResult::Error;
207 return TPResult::Error;
208 if (Tok.is(tok::annot_cxxscope))
209 ConsumeAnnotationToken();
210 if (Tok.is(tok::identifier))
212 else if (Tok.is(tok::annot_template_id))
213 ConsumeAnnotationToken();
215 return TPResult::Error;
218 case tok::annot_cxxscope:
219 ConsumeAnnotationToken();
225 return TryParseProtocolQualifiers();
229 return TPResult::Ambiguous;
232Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
233 bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);
234 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
235 return TPResult::Error;
240 if (Tok.isNot(tok::l_paren)) {
242 if (TPR == TPResult::Ambiguous)
243 return TPResult::True;
244 if (TPR == TPResult::True || TPR == TPResult::Error)
246 assert(TPR == TPResult::False);
249 TPResult TPR = TryParseInitDeclaratorList(
250 DeclSpecifierIsAuto);
251 if (TPR != TPResult::Ambiguous)
254 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
255 return TPResult::False;
257 return TPResult::Ambiguous;
261Parser::TryParseInitDeclaratorList(
bool MayHaveTrailingReturnType) {
264 TPResult TPR = TryParseDeclarator(
268 MayHaveTrailingReturnType);
269 if (TPR != TPResult::Ambiguous)
273 if (Tok.isOneOf(tok::kw_asm, tok::kw___attribute))
274 return TPResult::True;
277 if (Tok.is(tok::l_paren)) {
281 return TPResult::Error;
282 }
else if (Tok.is(tok::l_brace)) {
285 return TPResult::True;
286 }
else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
303 return TPResult::True;
310 return TPResult::Ambiguous;
338 RevertingTentativeParsingAction PA(
P);
342 unsigned QuestionColonDepth = 0;
344 P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
346 if (
P.Tok.is(tok::question))
347 ++QuestionColonDepth;
348 else if (
P.Tok.is(tok::colon)) {
349 if (QuestionColonDepth)
350 --QuestionColonDepth;
365 if (
P.Tok.isNot(tok::r_paren))
367 if (
P.Tok.isNot(tok::semi))
386 assert(
resolved() &&
"can't continue after tentative parsing bails out");
388 case TPResult::False:
391 case TPResult::Ambiguous:
393 case TPResult::Error:
401 ConditionOrInitStatement
result()
const {
404 "result called but not yet resolved");
406 return ConditionOrInitStatement::Expression;
408 return ConditionOrInitStatement::ConditionDecl;
410 return ConditionOrInitStatement::InitStmtDecl;
412 return ConditionOrInitStatement::ForRangeDecl;
413 return ConditionOrInitStatement::Error;
417bool Parser::isEnumBase(
bool AllowSemi) {
418 assert(
Tok.is(tok::colon) &&
"should be looking at the ':'");
420 RevertingTentativeParsingAction PA(*
this);
425 bool InvalidAsDeclSpec =
false;
432 if (R == TPResult::Ambiguous) {
435 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
440 if (
Tok.is(tok::l_brace) || (AllowSemi &&
Tok.is(tok::semi)))
448 return R != TPResult::False;
451Parser::ConditionOrInitStatement
452Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement,
453 bool CanBeForRangeDecl) {
457 if (CanBeInitStatement && Tok.is(tok::kw_using))
458 return ConditionOrInitStatement::InitStmtDecl;
460 return State.result();
463 RevertingTentativeParsingAction PA(*
this);
466 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
467 if (State.update(TryConsumeDeclarationSpecifier()))
468 return State.result();
469 assert(Tok.is(tok::l_paren) &&
"Expected '('");
473 if (State.update(TryParseDeclarator(
477 MayHaveTrailingReturnType)))
478 return State.result();
483 if (Tok.isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
485 State.markNotExpression();
486 return State.result();
490 if (State.CanBeForRangeDecl && Tok.is(tok::colon))
491 return ConditionOrInitStatement::ForRangeDecl;
495 if (State.markNotCondition())
496 return State.result();
499 if (State.markNotForRangeDecl())
500 return State.result();
504 if (Tok.is(tok::l_paren)) {
514 if (State.CanBeCondition && Tok.is(tok::r_paren))
515 return ConditionOrInitStatement::ConditionDecl;
516 else if (State.CanBeInitStatement && Tok.is(tok::semi))
517 return ConditionOrInitStatement::InitStmtDecl;
519 return ConditionOrInitStatement::Expression;
534 if (TPR != TPResult::Ambiguous)
535 return TPR != TPResult::False;
544 RevertingTentativeParsingAction PA(*
this);
545 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
548 TryConsumeDeclarationSpecifier();
549 assert(Tok.is(tok::l_paren) &&
"Expected '('");
552 TPR = TryParseDeclarator(
true ,
false ,
554 MayHaveTrailingReturnType);
557 if (TPR == TPResult::Error)
558 TPR = TPResult::True;
560 if (TPR == TPResult::Ambiguous) {
564 Tok.is(tok::r_paren)) {
565 TPR = TPResult::True;
570 }
else if (Context ==
572 Tok.is(tok::comma)) {
573 TPR = TPResult::True;
580 (Tok.isOneOf(tok::greater, tok::comma) ||
582 (Tok.isOneOf(tok::greatergreater,
583 tok::greatergreatergreater) ||
584 (Tok.is(tok::ellipsis) &&
586 tok::greatergreatergreater,
588 TPR = TPResult::True;
592 TPR = TPResult::True;
595 TPR = TPResult::True;
598 TPR = TPResult::False;
601 assert(TPR == TPResult::True || TPR == TPResult::False);
602 return TPR == TPResult::True;
606Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
607 bool OuterMightBeMessageSend) {
612 if (Tok.isRegularKeywordAttribute())
626 RevertingTentativeParsingAction PA(*
this);
634 bool IsAttribute =
SkipUntil(tok::r_square);
635 IsAttribute &= Tok.is(tok::r_square);
654 RevertingTentativeParsingAction LambdaTPA(*
this);
655 LambdaIntroducer Intro;
656 LambdaIntroducerTentativeParse Tentative;
657 if (ParseLambdaIntroducer(Intro, &Tentative)) {
665 case LambdaIntroducerTentativeParse::MessageSend:
670 case LambdaIntroducerTentativeParse::Success:
671 case LambdaIntroducerTentativeParse::Incomplete:
673 if (Tok.is(tok::r_square))
677 if (OuterMightBeMessageSend)
684 case LambdaIntroducerTentativeParse::Invalid:
695 bool IsAttribute =
true;
696 while (Tok.isNot(tok::r_square)) {
697 if (Tok.is(tok::comma)) {
708 if (!TryParseCXX11AttributeIdentifier(Loc)) {
712 if (Tok.is(tok::coloncolon)) {
714 if (!TryParseCXX11AttributeIdentifier(Loc)) {
721 if (Tok.is(tok::l_paren)) {
737 if (Tok.is(tok::r_square)) {
739 IsAttribute = Tok.is(tok::r_square);
753bool Parser::TrySkipAttributes() {
754 while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
756 Tok.isRegularKeywordAttribute()) {
757 if (Tok.is(tok::l_square)) {
764 if (!
SkipUntil(tok::r_square) || Tok.isNot(tok::r_square))
769 }
else if (Tok.isRegularKeywordAttribute() &&
774 if (Tok.isNot(tok::l_paren))
785Parser::TPResult Parser::TryParsePtrOperatorSeq() {
788 return TPResult::Error;
790 if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
791 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
796 if (!TrySkipAttributes())
797 return TPResult::Error;
799 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
800 tok::kw__Nonnull, tok::kw__Nullable,
801 tok::kw__Nullable_result, tok::kw__Null_unspecified,
805 return TPResult::True;
810Parser::TPResult Parser::TryParseOperatorId() {
811 assert(Tok.is(tok::kw_operator));
815 switch (Tok.getKind()) {
816 case tok::kw_new:
case tok::kw_delete:
818 if (Tok.is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
822 return TPResult::True;
824#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
826#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
827#include "clang/Basic/OperatorKinds.def"
829 return TPResult::True;
835 return TPResult::True;
843 return TPResult::True;
853 bool FoundUDSuffix =
false;
855 FoundUDSuffix |= Tok.hasUDSuffix();
856 ConsumeStringToken();
857 }
while (isTokenStringLiteral());
859 if (!FoundUDSuffix) {
860 if (Tok.is(tok::identifier))
863 return TPResult::Error;
865 return TPResult::True;
869 bool AnyDeclSpecifiers =
false;
872 if (TPR == TPResult::Error)
874 if (TPR == TPResult::False) {
875 if (!AnyDeclSpecifiers)
876 return TPResult::Error;
879 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
880 return TPResult::Error;
881 AnyDeclSpecifiers =
true;
883 return TryParsePtrOperatorSeq();
886Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
887 bool mayHaveIdentifier,
888 bool mayHaveDirectInit,
889 bool mayHaveTrailingReturnType) {
893 if (TryParsePtrOperatorSeq() == TPResult::Error)
894 return TPResult::Error;
898 if (Tok.is(tok::ellipsis))
901 if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||
902 (Tok.is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
906 if (Tok.is(tok::annot_cxxscope)) {
908 Actions.RestoreNestedNameSpecifierAnnotation(
909 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
911 return TPResult::Error;
912 ConsumeAnnotationToken();
913 }
else if (Tok.is(tok::identifier)) {
914 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
916 if (Tok.is(tok::kw_operator)) {
917 if (TryParseOperatorId() == TPResult::Error)
918 return TPResult::Error;
921 }
else if (Tok.is(tok::l_paren)) {
924 (Tok.is(tok::r_paren) ||
926 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren)) ||
927 isDeclarationSpecifier(
931 TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
932 if (TPR != TPResult::Ambiguous)
938 if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
939 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
940 tok::kw___regcall, tok::kw___vectorcall))
941 return TPResult::True;
942 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
943 if (TPR != TPResult::Ambiguous)
945 if (Tok.isNot(tok::r_paren))
946 return TPResult::False;
949 }
else if (!mayBeAbstract) {
950 return TPResult::False;
953 if (mayHaveDirectInit)
954 return TPResult::Ambiguous;
957 TPResult TPR(TPResult::Ambiguous);
959 if (Tok.is(tok::l_paren)) {
964 if (!mayBeAbstract && !isCXXFunctionDeclarator())
970 TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
971 }
else if (Tok.is(tok::l_square)) {
974 TPR = TryParseBracketDeclarator();
975 }
else if (Tok.is(tok::kw_requires)) {
978 TPR = TPResult::True;
983 if (TPR != TPResult::Ambiguous)
987 return TPResult::Ambiguous;
991 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
997 TentativeParseCCC(
const Token &
Next) {
998 WantRemainingKeywords =
false;
1000 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
1001 tok::identifier, tok::comma);
1004 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1008 llvm::all_of(Candidate,
1009 [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
1015 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
1016 return std::make_unique<TentativeParseCCC>(*
this);
1023 Parser::TPResult BracedCastResult,
1024 bool *InvalidAsDeclSpec) {
1025 auto IsPlaceholderSpecifier = [&](TemplateIdAnnotation *TemplateId,
1031 .
isOneOf(tok::kw_auto, tok::kw_decltype,
1041 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
1054 switch (Tok.getKind()) {
1055 case tok::identifier: {
1060 return TPResult::Error;
1061 if (Tok.is(tok::identifier))
1062 return TPResult::False;
1064 BracedCastResult, InvalidAsDeclSpec);
1069 if (TryAltiVecVectorToken())
1070 return TPResult::True;
1075 return TPResult::True;
1080 if (
Next.is(tok::l_paren) &&
1081 Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier() &&
1082 isRevertibleTypeTrait(Tok.getIdentifierInfo())) {
1083 return TPResult::False;
1086 if (
Next.isNoneOf(tok::coloncolon, tok::less, tok::colon)) {
1091 TentativeParseCCC CCC(
Next);
1092 switch (TryAnnotateName(&CCC)) {
1094 return TPResult::Error;
1096 return TPResult::False;
1104 return TPResult::Error;
1105 if (Tok.isNot(tok::identifier))
1111 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1113 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1117 assert(Tok.isNot(tok::identifier) &&
1118 "TryAnnotateName succeeded without producing an annotation");
1125 return TPResult::Error;
1129 if (Tok.is(tok::identifier))
1130 return TPResult::False;
1134 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1138 case tok::kw_typename:
1142 return TPResult::Error;
1144 BracedCastResult, InvalidAsDeclSpec);
1146 case tok::kw_auto: {
1148 return TPResult::True;
1150 return TPResult::False;
1152 return TPResult::Ambiguous;
1153 return TPResult::True;
1156 case tok::coloncolon: {
1158 if (
Next.isOneOf(tok::kw_new,
1160 return TPResult::False;
1163 case tok::kw___super:
1164 case tok::kw_decltype:
1168 return TPResult::Error;
1169 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1179 case tok::kw_friend:
1180 case tok::kw_typedef:
1181 case tok::kw_constexpr:
1182 case tok::kw_consteval:
1183 case tok::kw_constinit:
1185 case tok::kw_register:
1186 case tok::kw_static:
1187 case tok::kw_extern:
1188 case tok::kw_mutable:
1189 case tok::kw___thread:
1190 case tok::kw_thread_local:
1191 case tok::kw__Thread_local:
1193 case tok::kw_inline:
1194 case tok::kw_virtual:
1195 case tok::kw_explicit:
1196 case tok::kw__Noreturn:
1199 case tok::kw___module_private__:
1202 case tok::kw___unknown_anytype:
1215 case tok::kw_struct:
1217 case tok::kw___interface:
1222 case tok::kw_volatile:
1223 return TPResult::True;
1226 case tok::kw_private:
1228 return TPResult::False;
1230 case tok::kw___private:
1231 case tok::kw___local:
1232 case tok::kw___global:
1233 case tok::kw___constant:
1234 case tok::kw___generic:
1236 case tok::kw___read_only:
1237 case tok::kw___write_only:
1238 case tok::kw___read_write:
1243 case tok::kw_groupshared:
1248 case tok::kw_row_major:
1249 case tok::kw_column_major:
1252 case tok::kw_restrict:
1253 case tok::kw__Complex:
1254 case tok::kw__Imaginary:
1255 case tok::kw___attribute:
1256 case tok::kw___auto_type:
1257 return TPResult::True;
1260 case tok::kw___ob_wrap:
1261 case tok::kw___ob_trap:
1262 return TPResult::True;
1265 case tok::kw___declspec:
1266 case tok::kw___cdecl:
1267 case tok::kw___stdcall:
1268 case tok::kw___fastcall:
1269 case tok::kw___thiscall:
1270 case tok::kw___regcall:
1271 case tok::kw___vectorcall:
1273 case tok::kw___sptr:
1274 case tok::kw___uptr:
1275 case tok::kw___ptr64:
1276 case tok::kw___ptr32:
1277 case tok::kw___forceinline:
1278 case tok::kw___unaligned:
1279 case tok::kw__Nonnull:
1280 case tok::kw__Nullable:
1281 case tok::kw__Nullable_result:
1282 case tok::kw__Null_unspecified:
1283 case tok::kw___kindof:
1284 return TPResult::True;
1287 case tok::kw___funcref:
1288 return TPResult::True;
1291 case tok::kw___pascal:
1292 return TPResult::True;
1295 case tok::kw___vector:
1296 return TPResult::True;
1298 case tok::kw_this: {
1302 RevertingTentativeParsingAction PA(*
this);
1304 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1307 return TPResult::False;
1309 case tok::annot_template_id: {
1310 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1315 InvalidAsDeclSpec) {
1320 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1321 return TPResult::Ambiguous;
1324 return TPResult::Error;
1325 if (IsPlaceholderSpecifier(TemplateId, 0))
1326 return TPResult::True;
1328 return TPResult::False;
1330 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1331 assert(Tok.is(tok::annot_typename));
1335 case tok::annot_cxxscope:
1338 return TPResult::Error;
1339 if (!Tok.is(tok::annot_typename)) {
1340 if (Tok.is(tok::annot_cxxscope) &&
1342 TemplateIdAnnotation *TemplateId =
1345 if (InvalidAsDeclSpec) {
1346 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1347 return TPResult::Ambiguous;
1349 return TPResult::Error;
1351 if (IsPlaceholderSpecifier(TemplateId, 1))
1352 return TPResult::True;
1356 if (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1358 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1359 Tok.getAnnotationRange(),
1362 RevertingTentativeParsingAction PA(*
this);
1363 ConsumeAnnotationToken();
1365 bool isIdentifier = Tok.is(tok::identifier);
1366 TPResult TPR = TPResult::False;
1368 TPR = isCXXDeclarationSpecifier(
1369 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1372 TPR == TPResult::True || TPR == TPResult::Error)
1373 return TPResult::Error;
1375 if (InvalidAsDeclSpec) {
1378 *InvalidAsDeclSpec =
true;
1379 return TPResult::Ambiguous;
1385 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1388 (Tok.is(tok::ampamp) &&
NextToken().
is(tok::greater)))
1389 return TPResult::True;
1395 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1397 return TPResult::Error;
1399 return TPResult::False;
1405 return TPResult::Error;
1409 if (Tok.isNot(tok::annot_cxxscope) && Tok.isNot(tok::identifier))
1420 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1426 assert(Tok.isNot(tok::annot_cxxscope) ||
1428 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1429 BracedCastResult, InvalidAsDeclSpec);
1432 return TPResult::False;
1455 case tok::annot_typename:
1460 RevertingTentativeParsingAction PA(*
this);
1463 TPResult TPR = TryParseProtocolQualifiers();
1464 bool isFollowedByParen = Tok.is(tok::l_paren);
1465 bool isFollowedByBrace = Tok.is(tok::l_brace);
1467 if (TPR == TPResult::Error)
1468 return TPResult::Error;
1470 if (isFollowedByParen)
1471 return TPResult::Ambiguous;
1474 return BracedCastResult;
1476 return TPResult::True;
1482 case tok::kw_wchar_t:
1483 case tok::kw_char8_t:
1484 case tok::kw_char16_t:
1485 case tok::kw_char32_t:
1490 case tok::kw___int64:
1491 case tok::kw___int128:
1492 case tok::kw_signed:
1493 case tok::kw_unsigned:
1496 case tok::kw_double:
1497 case tok::kw___bf16:
1498 case tok::kw__Float16:
1499 case tok::kw___float128:
1500 case tok::kw___ibm128:
1502 case tok::annot_decltype:
1503 case tok::kw__Accum:
1504 case tok::kw__Fract:
1506 case tok::annot_pack_indexing_type:
1507#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1508#include "clang/Basic/OpenCLImageTypes.def"
1509#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1510#include "clang/Basic/HLSLIntangibleTypes.def"
1512 return TPResult::Ambiguous;
1521 return BracedCastResult;
1523 if (isStartOfObjCClassMessageMissingOpenBracket())
1524 return TPResult::False;
1526 return TPResult::True;
1529 case tok::kw_typeof:
1530 case tok::kw_typeof_unqual: {
1532 return TPResult::True;
1534 RevertingTentativeParsingAction PA(*
this);
1536 TPResult TPR = TryParseTypeofSpecifier();
1537 bool isFollowedByParen = Tok.is(tok::l_paren);
1538 bool isFollowedByBrace = Tok.is(tok::l_brace);
1540 if (TPR == TPResult::Error)
1541 return TPResult::Error;
1543 if (isFollowedByParen)
1544 return TPResult::Ambiguous;
1547 return BracedCastResult;
1549 return TPResult::True;
1552#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1553#include "clang/Basic/TransformTypeTraits.def"
1554 return TPResult::True;
1557 case tok::kw__Alignas:
1558 return TPResult::True;
1560 case tok::kw__Atomic:
1561 return TPResult::True;
1563 case tok::kw__BitInt:
1564 case tok::kw__ExtInt: {
1566 return TPResult::Error;
1567 RevertingTentativeParsingAction PA(*
this);
1572 return TPResult::Error;
1574 if (Tok.is(tok::l_paren))
1575 return TPResult::Ambiguous;
1578 return BracedCastResult;
1580 return TPResult::True;
1583 return TPResult::False;
1587bool Parser::isCXXDeclarationSpecifierAType() {
1588 switch (Tok.getKind()) {
1590 case tok::annot_decltype:
1591 case tok::annot_pack_indexing_type:
1592 case tok::annot_template_id:
1593 case tok::annot_typename:
1594 case tok::kw_typeof:
1595 case tok::kw_typeof_unqual:
1596#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1597#include "clang/Basic/TransformTypeTraits.def"
1602 case tok::kw_struct:
1604 case tok::kw___interface:
1610 case tok::kw_wchar_t:
1611 case tok::kw_char8_t:
1612 case tok::kw_char16_t:
1613 case tok::kw_char32_t:
1617 case tok::kw__ExtInt:
1618 case tok::kw__BitInt:
1620 case tok::kw___int64:
1621 case tok::kw___int128:
1622 case tok::kw_signed:
1623 case tok::kw_unsigned:
1626 case tok::kw_double:
1627 case tok::kw___bf16:
1628 case tok::kw__Float16:
1629 case tok::kw___float128:
1630 case tok::kw___ibm128:
1632 case tok::kw___unknown_anytype:
1633 case tok::kw___auto_type:
1634 case tok::kw__Accum:
1635 case tok::kw__Fract:
1637#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1638#include "clang/Basic/OpenCLImageTypes.def"
1639#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1640#include "clang/Basic/HLSLIntangibleTypes.def"
1646 case tok::kw__Atomic:
1655Parser::TPResult Parser::TryParseTypeofSpecifier() {
1656 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
1657 "Expected 'typeof' or 'typeof_unqual'!");
1660 assert(Tok.is(tok::l_paren) &&
"Expected '('");
1664 return TPResult::Error;
1666 return TPResult::Ambiguous;
1669Parser::TPResult Parser::TryParseProtocolQualifiers() {
1670 assert(Tok.is(tok::less) &&
"Expected '<' for qualifier list");
1673 if (Tok.isNot(tok::identifier))
1674 return TPResult::Error;
1677 if (Tok.is(tok::comma)) {
1682 if (Tok.is(tok::greater)) {
1684 return TPResult::Ambiguous;
1688 return TPResult::Error;
1691bool Parser::isCXXFunctionDeclarator(
1703 RevertingTentativeParsingAction PA(*
this);
1706 bool InvalidAsDeclaration =
false;
1707 TPResult TPR = TryParseParameterDeclarationClause(
1708 &InvalidAsDeclaration,
false,
1709 AllowImplicitTypename);
1710 if (TPR == TPResult::Ambiguous) {
1711 if (Tok.isNot(tok::r_paren))
1712 TPR = TPResult::False;
1715 if (
Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1716 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1717 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1718 isCXX11VirtSpecifier(
Next))
1722 TPR = TPResult::True;
1723 else if (InvalidAsDeclaration)
1725 TPR = TPResult::False;
1729 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1730 *IsAmbiguous =
true;
1733 return TPR != TPResult::False;
1736Parser::TPResult Parser::TryParseParameterDeclarationClause(
1737 bool *InvalidAsDeclaration,
bool VersusTemplateArgument,
1740 if (Tok.is(tok::r_paren))
1741 return TPResult::Ambiguous;
1752 if (Tok.is(tok::ellipsis)) {
1754 if (Tok.is(tok::r_paren))
1755 return TPResult::True;
1757 return TPResult::False;
1761 if (isCXX11AttributeSpecifier(
false,
1764 return TPResult::True;
1766 ParsedAttributes attrs(AttrFactory);
1767 MaybeParseMicrosoftAttributes(attrs);
1772 TPResult TPR = isCXXDeclarationSpecifier(
1773 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
1776 if (TPR != TPResult::Ambiguous &&
1777 !(VersusTemplateArgument && TPR == TPResult::True))
1780 bool SeenType =
false;
1781 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
1783 SeenType |= isCXXDeclarationSpecifierAType();
1784 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1785 return TPResult::Error;
1788 if (SeenType && Tok.is(tok::identifier))
1789 return TPResult::True;
1791 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
1792 InvalidAsDeclaration);
1793 if (TPR == TPResult::Error)
1797 if (TPR == TPResult::True && !VersusTemplateArgument)
1799 }
while (TPR != TPResult::False);
1803 TPR = TryParseDeclarator(
1807 DeclarationSpecifierIsAuto);
1808 if (TPR != TPResult::Ambiguous)
1812 if (Tok.is(tok::kw___attribute))
1813 return TPResult::True;
1824 if (VersusTemplateArgument)
1825 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;
1827 if (Tok.is(tok::equal)) {
1831 return TPResult::Error;
1834 if (Tok.is(tok::ellipsis)) {
1836 if (Tok.is(tok::r_paren))
1837 return TPResult::True;
1839 return TPResult::False;
1846 return TPResult::Ambiguous;
1850Parser::TryParseFunctionDeclarator(
bool MayHaveTrailingReturnType) {
1853 TPResult TPR = TryParseParameterDeclarationClause();
1854 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
1855 TPR = TPResult::False;
1857 if (TPR == TPResult::False || TPR == TPResult::Error)
1862 return TPResult::Error;
1865 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1870 if (Tok.isOneOf(tok::amp, tok::ampamp))
1874 if (Tok.is(tok::kw_throw)) {
1876 if (Tok.isNot(tok::l_paren))
1877 return TPResult::Error;
1882 return TPResult::Error;
1884 if (Tok.is(tok::kw_noexcept)) {
1887 if (Tok.is(tok::l_paren)) {
1891 return TPResult::Error;
1896 if (!TrySkipAttributes())
1897 return TPResult::Ambiguous;
1900 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
1901 if (TPR == TPResult::True)
1904 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
1905 return TPResult::False;
1908 return TPResult::True;
1911 return TPResult::Ambiguous;
1914bool Parser::NameAfterArrowIsNonType() {
1915 assert(Tok.is(tok::identifier));
1917 if (
Next.is(tok::coloncolon))
1919 IdentifierInfo *Name = Tok.getIdentifierInfo();
1920 SourceLocation NameLoc = Tok.getLocation();
1922 TentativeParseCCC CCC(
Next);
1923 Sema::NameClassification Classification =
1925 switch (Classification.
getKind()) {
1937Parser::TPResult Parser::TryParseBracketDeclarator() {
1942 if (Tok.is(tok::l_brace))
1943 return TPResult::False;
1946 return TPResult::Error;
1950 if (Tok.isNot(tok::r_square))
1951 return TPResult::False;
1954 return TPResult::Ambiguous;
1957Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
1958 if (!TokensToSkip) {
1959 if (Tok.isNot(tok::less))
1960 return TPResult::False;
1962 return TPResult::True;
1965 RevertingTentativeParsingAction PA(*
this);
1967 while (TokensToSkip) {
1973 return TPResult::False;
1978 bool InvalidAsTemplateArgumentList =
false;
1980 &InvalidAsTemplateArgumentList) ==
1982 return TPResult::True;
1983 if (InvalidAsTemplateArgumentList)
1984 return TPResult::False;
1998 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2000 return TPResult::Ambiguous;
2001 return TPResult::False;
2004Parser::TPResult Parser::isExplicitBool() {
2005 assert(Tok.is(tok::l_paren) &&
"expected to be looking at a '(' token");
2007 RevertingTentativeParsingAction PA(*
this);
2015 while (Tok.is(tok::l_paren))
2019 return TPResult::Error;
2024 if (Tok.is(tok::annot_cxxscope)) {
2025 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2026 Tok.getAnnotationRange(),
2028 ConsumeAnnotationToken();
2033 if (Tok.is(tok::kw_operator))
2034 return TPResult::Ambiguous;
2037 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
2038 return TPResult::True;
2039 if (!Actions.isCurrentClassName(Tok.is(tok::identifier)
2040 ? *Tok.getIdentifierInfo()
2041 : *takeTemplateIdAnnotation(Tok)->Name,
2043 return TPResult::True;
2049 !isConstructorDeclarator(SS.
isEmpty(),
2051 return TPResult::True;
2054 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.