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/BuiltinTraits.inc"
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::False;
1150 return TPResult::Ambiguous;
1151 return TPResult::True;
1154 case tok::coloncolon: {
1156 if (
Next.isOneOf(tok::kw_new,
1158 return TPResult::False;
1161 case tok::kw___super:
1162 case tok::kw_decltype:
1166 return TPResult::Error;
1167 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1177 case tok::kw_friend:
1178 case tok::kw_typedef:
1179 case tok::kw_constexpr:
1180 case tok::kw_consteval:
1181 case tok::kw_constinit:
1183 case tok::kw_register:
1184 case tok::kw_static:
1185 case tok::kw_extern:
1186 case tok::kw_mutable:
1187 case tok::kw___thread:
1188 case tok::kw_thread_local:
1189 case tok::kw__Thread_local:
1191 case tok::kw_inline:
1192 case tok::kw_virtual:
1193 case tok::kw_explicit:
1194 case tok::kw__Noreturn:
1197 case tok::kw___module_private__:
1200 case tok::kw___unknown_anytype:
1213 case tok::kw_struct:
1215 case tok::kw___interface:
1220 case tok::kw_volatile:
1221 return TPResult::True;
1224 case tok::kw_private:
1226 return TPResult::False;
1228 case tok::kw___private:
1229 case tok::kw___local:
1230 case tok::kw___global:
1231 case tok::kw___constant:
1232 case tok::kw___generic:
1234 case tok::kw___read_only:
1235 case tok::kw___write_only:
1236 case tok::kw___read_write:
1241 case tok::kw_groupshared:
1246 case tok::kw_row_major:
1247 case tok::kw_column_major:
1250 case tok::kw_restrict:
1251 case tok::kw__Complex:
1252 case tok::kw__Imaginary:
1253 case tok::kw___attribute:
1254 case tok::kw___auto_type:
1255 return TPResult::True;
1258 case tok::kw___ob_wrap:
1259 case tok::kw___ob_trap:
1260 return TPResult::True;
1263 case tok::kw___declspec:
1264 case tok::kw___cdecl:
1265 case tok::kw___stdcall:
1266 case tok::kw___fastcall:
1267 case tok::kw___thiscall:
1268 case tok::kw___regcall:
1269 case tok::kw___vectorcall:
1271 case tok::kw___sptr:
1272 case tok::kw___uptr:
1273 case tok::kw___ptr64:
1274 case tok::kw___ptr32:
1275 case tok::kw___forceinline:
1276 case tok::kw___unaligned:
1277 case tok::kw__Nonnull:
1278 case tok::kw__Nullable:
1279 case tok::kw__Nullable_result:
1280 case tok::kw__Null_unspecified:
1281 case tok::kw___kindof:
1282 return TPResult::True;
1285 case tok::kw___funcref:
1286 return TPResult::True;
1289 case tok::kw___pascal:
1290 return TPResult::True;
1293 case tok::kw___vector:
1294 return TPResult::True;
1296 case tok::kw_this: {
1300 RevertingTentativeParsingAction PA(*
this);
1302 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1305 return TPResult::False;
1307 case tok::annot_template_id: {
1308 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1313 InvalidAsDeclSpec) {
1318 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1319 return TPResult::Ambiguous;
1322 return TPResult::Error;
1323 if (IsPlaceholderSpecifier(TemplateId, 0))
1324 return TPResult::True;
1326 return TPResult::False;
1328 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1329 assert(Tok.is(tok::annot_typename));
1333 case tok::annot_cxxscope:
1336 return TPResult::Error;
1337 if (!Tok.is(tok::annot_typename)) {
1338 if (Tok.is(tok::annot_cxxscope) &&
1340 TemplateIdAnnotation *TemplateId =
1343 if (InvalidAsDeclSpec) {
1344 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1345 return TPResult::Ambiguous;
1347 return TPResult::Error;
1349 if (IsPlaceholderSpecifier(TemplateId, 1))
1350 return TPResult::True;
1354 if (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1356 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1357 Tok.getAnnotationRange(),
1360 RevertingTentativeParsingAction PA(*
this);
1361 ConsumeAnnotationToken();
1363 bool isIdentifier = Tok.is(tok::identifier);
1364 TPResult TPR = TPResult::False;
1366 TPR = isCXXDeclarationSpecifier(
1367 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1370 TPR == TPResult::True || TPR == TPResult::Error)
1371 return TPResult::Error;
1373 if (InvalidAsDeclSpec) {
1376 *InvalidAsDeclSpec =
true;
1377 return TPResult::Ambiguous;
1383 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1386 (Tok.is(tok::ampamp) &&
NextToken().
is(tok::greater)))
1387 return TPResult::True;
1393 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1395 return TPResult::Error;
1397 return TPResult::False;
1403 return TPResult::Error;
1407 if (Tok.isNot(tok::annot_cxxscope) && Tok.isNot(tok::identifier))
1418 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1424 assert(Tok.isNot(tok::annot_cxxscope) ||
1426 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1427 BracedCastResult, InvalidAsDeclSpec);
1430 return TPResult::False;
1453 case tok::annot_typename:
1458 RevertingTentativeParsingAction PA(*
this);
1461 TPResult TPR = TryParseProtocolQualifiers();
1462 bool isFollowedByParen = Tok.is(tok::l_paren);
1463 bool isFollowedByBrace = Tok.is(tok::l_brace);
1465 if (TPR == TPResult::Error)
1466 return TPResult::Error;
1468 if (isFollowedByParen)
1469 return TPResult::Ambiguous;
1472 return BracedCastResult;
1474 return TPResult::True;
1480 case tok::kw_wchar_t:
1481 case tok::kw_char8_t:
1482 case tok::kw_char16_t:
1483 case tok::kw_char32_t:
1488 case tok::kw___int64:
1489 case tok::kw___int128:
1490 case tok::kw_signed:
1491 case tok::kw_unsigned:
1494 case tok::kw_double:
1495 case tok::kw___bf16:
1496 case tok::kw__Float16:
1497 case tok::kw___float128:
1498 case tok::kw___ibm128:
1500 case tok::annot_decltype:
1501 case tok::kw__Accum:
1502 case tok::kw__Fract:
1504 case tok::annot_pack_indexing_type:
1505#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1506#include "clang/Basic/OpenCLImageTypes.def"
1507#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1508#include "clang/Basic/HLSLIntangibleTypes.def"
1510 return TPResult::Ambiguous;
1519 return BracedCastResult;
1521 if (isStartOfObjCClassMessageMissingOpenBracket())
1522 return TPResult::False;
1524 return TPResult::True;
1527 case tok::kw_typeof:
1528 case tok::kw_typeof_unqual: {
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/BuiltinTraits.inc"
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 case tok::kw_typeof_unqual:
1594#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1595#include "clang/Basic/BuiltinTraits.inc"
1600 case tok::kw_struct:
1602 case tok::kw___interface:
1608 case tok::kw_wchar_t:
1609 case tok::kw_char8_t:
1610 case tok::kw_char16_t:
1611 case tok::kw_char32_t:
1615 case tok::kw__ExtInt:
1616 case tok::kw__BitInt:
1618 case tok::kw___int64:
1619 case tok::kw___int128:
1620 case tok::kw_signed:
1621 case tok::kw_unsigned:
1624 case tok::kw_double:
1625 case tok::kw___bf16:
1626 case tok::kw__Float16:
1627 case tok::kw___float128:
1628 case tok::kw___ibm128:
1630 case tok::kw___unknown_anytype:
1631 case tok::kw___auto_type:
1632 case tok::kw__Accum:
1633 case tok::kw__Fract:
1635#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1636#include "clang/Basic/OpenCLImageTypes.def"
1637#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1638#include "clang/Basic/HLSLIntangibleTypes.def"
1644 case tok::kw__Atomic:
1653Parser::TPResult Parser::TryParseTypeofSpecifier() {
1654 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
1655 "Expected 'typeof' or 'typeof_unqual'!");
1658 assert(Tok.is(tok::l_paren) &&
"Expected '('");
1662 return TPResult::Error;
1664 return TPResult::Ambiguous;
1667Parser::TPResult Parser::TryParseProtocolQualifiers() {
1668 assert(Tok.is(tok::less) &&
"Expected '<' for qualifier list");
1671 if (Tok.isNot(tok::identifier))
1672 return TPResult::Error;
1675 if (Tok.is(tok::comma)) {
1680 if (Tok.is(tok::greater)) {
1682 return TPResult::Ambiguous;
1686 return TPResult::Error;
1689bool Parser::isCXXFunctionDeclarator(
1701 RevertingTentativeParsingAction PA(*
this);
1704 bool InvalidAsDeclaration =
false;
1705 TPResult TPR = TryParseParameterDeclarationClause(
1706 &InvalidAsDeclaration,
false,
1707 AllowImplicitTypename);
1708 if (TPR == TPResult::Ambiguous) {
1709 if (Tok.isNot(tok::r_paren))
1710 TPR = TPResult::False;
1713 if (
Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1714 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1715 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1716 isCXX11VirtSpecifier(
Next))
1720 TPR = TPResult::True;
1721 else if (InvalidAsDeclaration)
1723 TPR = TPResult::False;
1727 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1728 *IsAmbiguous =
true;
1731 return TPR != TPResult::False;
1734Parser::TPResult Parser::TryParseParameterDeclarationClause(
1735 bool *InvalidAsDeclaration,
bool VersusTemplateArgument,
1738 if (Tok.is(tok::r_paren))
1739 return TPResult::Ambiguous;
1750 if (Tok.is(tok::ellipsis)) {
1752 if (Tok.is(tok::r_paren))
1753 return TPResult::True;
1755 return TPResult::False;
1759 if (isCXX11AttributeSpecifier(
false,
1762 return TPResult::True;
1764 ParsedAttributes attrs(AttrFactory);
1765 MaybeParseMicrosoftAttributes(attrs);
1770 TPResult TPR = isCXXDeclarationSpecifier(
1771 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
1774 if (TPR != TPResult::Ambiguous &&
1775 !(VersusTemplateArgument && TPR == TPResult::True))
1778 bool SeenType =
false;
1779 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
1781 SeenType |= isCXXDeclarationSpecifierAType();
1782 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1783 return TPResult::Error;
1786 if (SeenType && Tok.is(tok::identifier))
1787 return TPResult::True;
1789 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
1790 InvalidAsDeclaration);
1791 if (TPR == TPResult::Error)
1795 if (TPR == TPResult::True && !VersusTemplateArgument)
1797 }
while (TPR != TPResult::False);
1801 TPR = TryParseDeclarator(
1805 DeclarationSpecifierIsAuto);
1806 if (TPR != TPResult::Ambiguous)
1810 if (Tok.is(tok::kw___attribute))
1811 return TPResult::True;
1822 if (VersusTemplateArgument)
1823 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;
1825 if (Tok.is(tok::equal)) {
1829 return TPResult::Error;
1832 if (Tok.is(tok::ellipsis)) {
1834 if (Tok.is(tok::r_paren))
1835 return TPResult::True;
1837 return TPResult::False;
1844 return TPResult::Ambiguous;
1848Parser::TryParseFunctionDeclarator(
bool MayHaveTrailingReturnType) {
1851 TPResult TPR = TryParseParameterDeclarationClause();
1852 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
1853 TPR = TPResult::False;
1855 if (TPR == TPResult::False || TPR == TPResult::Error)
1860 return TPResult::Error;
1863 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1868 if (Tok.isOneOf(tok::amp, tok::ampamp))
1872 if (Tok.is(tok::kw_throw)) {
1874 if (Tok.isNot(tok::l_paren))
1875 return TPResult::Error;
1880 return TPResult::Error;
1882 if (Tok.is(tok::kw_noexcept)) {
1885 if (Tok.is(tok::l_paren)) {
1889 return TPResult::Error;
1894 if (!TrySkipAttributes())
1895 return TPResult::Ambiguous;
1898 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
1899 if (TPR == TPResult::True)
1902 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
1903 return TPResult::False;
1906 return TPResult::True;
1909 return TPResult::Ambiguous;
1912bool Parser::NameAfterArrowIsNonType() {
1913 assert(Tok.is(tok::identifier));
1915 if (
Next.is(tok::coloncolon))
1917 IdentifierInfo *Name = Tok.getIdentifierInfo();
1918 SourceLocation NameLoc = Tok.getLocation();
1920 TentativeParseCCC CCC(
Next);
1921 Sema::NameClassification Classification =
1923 switch (Classification.
getKind()) {
1935Parser::TPResult Parser::TryParseBracketDeclarator() {
1940 if (Tok.is(tok::l_brace))
1941 return TPResult::False;
1944 return TPResult::Error;
1948 if (Tok.isNot(tok::r_square))
1949 return TPResult::False;
1952 return TPResult::Ambiguous;
1955Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
1956 if (!TokensToSkip) {
1957 if (Tok.isNot(tok::less))
1958 return TPResult::False;
1960 return TPResult::True;
1963 RevertingTentativeParsingAction PA(*
this);
1965 while (TokensToSkip) {
1971 return TPResult::False;
1976 bool InvalidAsTemplateArgumentList =
false;
1978 &InvalidAsTemplateArgumentList) ==
1980 return TPResult::True;
1981 if (InvalidAsTemplateArgumentList)
1982 return TPResult::False;
1996 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
1998 return TPResult::Ambiguous;
1999 return TPResult::False;
2002Parser::TPResult Parser::isExplicitBool() {
2003 assert(Tok.is(tok::l_paren) &&
"expected to be looking at a '(' token");
2005 RevertingTentativeParsingAction PA(*
this);
2013 while (Tok.is(tok::l_paren))
2017 return TPResult::Error;
2022 if (Tok.is(tok::annot_cxxscope)) {
2023 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2024 Tok.getAnnotationRange(),
2026 ConsumeAnnotationToken();
2031 if (Tok.is(tok::kw_operator))
2032 return TPResult::Ambiguous;
2035 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
2036 return TPResult::True;
2037 if (!Actions.isCurrentClassName(Tok.is(tok::identifier)
2038 ? *Tok.getIdentifierInfo()
2039 : *takeTemplateIdAnnotation(Tok)->Name,
2041 return TPResult::True;
2047 !isConstructorDeclarator(SS.
isEmpty(),
2049 return TPResult::True;
2052 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
Top level wrappers for InstallAPI frontend operations.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
CXX11AttributeKind
The kind of attribute specifier we have found.
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ Unresolved
The identifier can't be resolved.
@ Success
Annotation was successful.
@ Error
Annotation has failed and emitted an error.
@ TentativeDecl
The identifier is a tentatively-declared name.
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
TentativeCXXTypeIdContext
Specifies the context in which type-id/expression disambiguation will occur.
@ AsGenericSelectionArgument
@ FunctionTemplate
The name was classified as a function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ VarTemplate
The name was classified as a variable template name.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
bool markNotForRangeDecl()
ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement, bool CanBeForRangeDecl)
bool update(TPResult IsDecl)
ConditionOrInitStatement result() const
bool hasInvalidName() const
TemplateNameKind Kind
The kind of template that Template refers to.
unsigned NumArgs
NumArgs - The number of template arguments.