19bool Parser::isCXXDeclarationStatement(
20 bool DisambiguatingWithExpression ) {
23 switch (Tok.getKind()) {
27 case tok::kw_namespace:
32 case tok::kw_static_assert:
33 case tok::kw__Static_assert:
36 case tok::identifier: {
37 if (DisambiguatingWithExpression) {
42 RevertingTentativeParsingAction TPA(*
this,
true);
43 SuppressAccessChecks AccessSuppressor(*
this,
true);
46 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
50 switch (Tok.getKind()) {
51 case tok::identifier: {
52 IdentifierInfo *II = Tok.getIdentifierInfo();
53 bool isDeductionGuide = Actions.isDeductionGuideName(
54 getCurScope(), *II, Tok.getLocation(), SS,
nullptr);
55 if (Actions.isCurrentClassName(*II,
getCurScope(), &SS) ||
57 if (isConstructorDeclarator(
75 case tok::kw_operator:
86 RevertingTentativeParsingAction TPA(*
this);
88 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
97 if (DisambiguatingWithExpression) {
98 TentativeParsingAction TPA(*
this,
true);
102 SuppressAccessChecks AccessExporter(*
this,
true);
103 if (isCXXSimpleDeclaration(
false)) {
111 return isCXXSimpleDeclaration(
false);
115bool Parser::isCXXSimpleDeclaration(
bool AllowForRangeDecl) {
140 bool InvalidAsDeclaration =
false;
141 TPResult TPR = isCXXDeclarationSpecifier(
143 if (TPR != TPResult::Ambiguous)
144 return TPR != TPResult::False;
152 if (InvalidAsDeclaration)
163 RevertingTentativeParsingAction PA(*
this);
164 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
168 if (TPR == TPResult::Error)
172 if (TPR == TPResult::Ambiguous)
173 TPR = TPResult::True;
175 assert(TPR == TPResult::True || TPR == TPResult::False);
176 return TPR == TPResult::True;
179Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
180 switch (Tok.getKind()) {
181 case tok::kw__Atomic:
188 case tok::kw_typeof_unqual:
189 case tok::kw___attribute:
190#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
191#include "clang/Basic/BuiltinTraits.inc"
194 if (Tok.isNot(tok::l_paren))
195 return TPResult::Error;
198 return TPResult::Error;
205 case tok::kw___interface:
217 if (!TrySkipAttributes())
218 return TPResult::Error;
221 return TPResult::Error;
222 if (Tok.is(tok::annot_cxxscope))
223 ConsumeAnnotationToken();
224 if (Tok.is(tok::identifier))
226 else if (Tok.is(tok::annot_template_id))
227 ConsumeAnnotationToken();
229 return TPResult::Error;
232 case tok::annot_cxxscope:
233 ConsumeAnnotationToken();
239 return TryParseProtocolQualifiers();
243 return TPResult::Ambiguous;
246Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
247 bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);
248 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
249 return TPResult::Error;
254 if (Tok.isNot(tok::l_paren)) {
256 if (TPR == TPResult::Ambiguous)
257 return TPResult::True;
258 if (TPR == TPResult::True || TPR == TPResult::Error)
260 assert(TPR == TPResult::False);
263 TPResult TPR = TryParseInitDeclaratorList(
264 DeclSpecifierIsAuto);
265 if (TPR != TPResult::Ambiguous)
268 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
269 return TPResult::False;
271 return TPResult::Ambiguous;
275Parser::TryParseInitDeclaratorList(
bool MayHaveTrailingReturnType) {
278 TPResult TPR = TryParseDeclarator(
282 MayHaveTrailingReturnType);
283 if (TPR != TPResult::Ambiguous)
287 if (Tok.isOneOf(tok::kw_asm, tok::kw___attribute))
288 return TPResult::True;
291 if (Tok.is(tok::l_paren)) {
295 return TPResult::Error;
296 }
else if (Tok.is(tok::l_brace)) {
299 return TPResult::True;
300 }
else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
317 return TPResult::True;
324 return TPResult::Ambiguous;
352 RevertingTentativeParsingAction PA(
P);
356 unsigned QuestionColonDepth = 0;
358 P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
360 if (
P.Tok.is(tok::question))
361 ++QuestionColonDepth;
362 else if (
P.Tok.is(tok::colon)) {
363 if (QuestionColonDepth)
364 --QuestionColonDepth;
379 if (
P.Tok.isNot(tok::r_paren))
381 if (
P.Tok.isNot(tok::semi))
400 assert(
resolved() &&
"can't continue after tentative parsing bails out");
402 case TPResult::False:
405 case TPResult::Ambiguous:
407 case TPResult::Error:
415 ConditionOrInitStatement
result()
const {
418 "result called but not yet resolved");
420 return ConditionOrInitStatement::Expression;
422 return ConditionOrInitStatement::ConditionDecl;
424 return ConditionOrInitStatement::InitStmtDecl;
426 return ConditionOrInitStatement::ForRangeDecl;
427 return ConditionOrInitStatement::Error;
431bool Parser::isEnumBase(
bool AllowSemi) {
432 assert(
Tok.is(tok::colon) &&
"should be looking at the ':'");
434 RevertingTentativeParsingAction PA(*
this);
439 bool InvalidAsDeclSpec =
false;
446 if (R == TPResult::Ambiguous) {
449 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
454 if (
Tok.is(tok::l_brace) || (AllowSemi &&
Tok.is(tok::semi)))
462 return R != TPResult::False;
465Parser::ConditionOrInitStatement
466Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement,
467 bool CanBeForRangeDecl) {
471 if (CanBeInitStatement && Tok.is(tok::kw_using))
472 return ConditionOrInitStatement::InitStmtDecl;
474 return State.result();
477 RevertingTentativeParsingAction PA(*
this);
480 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
481 if (State.update(TryConsumeDeclarationSpecifier()))
482 return State.result();
483 assert(Tok.is(tok::l_paren) &&
"Expected '('");
487 if (State.update(TryParseDeclarator(
491 MayHaveTrailingReturnType)))
492 return State.result();
497 if (Tok.isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
499 State.markNotExpression();
500 return State.result();
504 if (State.CanBeForRangeDecl && Tok.is(tok::colon))
505 return ConditionOrInitStatement::ForRangeDecl;
509 if (State.markNotCondition())
510 return State.result();
513 if (State.markNotForRangeDecl())
514 return State.result();
518 if (Tok.is(tok::l_paren)) {
528 if (State.CanBeCondition && Tok.is(tok::r_paren))
529 return ConditionOrInitStatement::ConditionDecl;
530 else if (State.CanBeInitStatement && Tok.is(tok::semi))
531 return ConditionOrInitStatement::InitStmtDecl;
533 return ConditionOrInitStatement::Expression;
548 if (TPR != TPResult::Ambiguous)
549 return TPR != TPResult::False;
558 RevertingTentativeParsingAction PA(*
this);
559 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
562 TryConsumeDeclarationSpecifier();
563 assert(Tok.is(tok::l_paren) &&
"Expected '('");
566 TPR = TryParseDeclarator(
true ,
false ,
568 MayHaveTrailingReturnType);
571 if (TPR == TPResult::Error)
572 TPR = TPResult::True;
574 if (TPR == TPResult::Ambiguous) {
578 Tok.is(tok::r_paren)) {
579 TPR = TPResult::True;
584 }
else if (Context ==
586 Tok.is(tok::comma)) {
587 TPR = TPResult::True;
594 (Tok.isOneOf(tok::greater, tok::comma) ||
596 (Tok.isOneOf(tok::greatergreater,
597 tok::greatergreatergreater) ||
598 (Tok.is(tok::ellipsis) &&
600 tok::greatergreatergreater,
602 TPR = TPResult::True;
606 TPR = TPResult::True;
609 TPR = TPResult::True;
612 TPR = TPResult::False;
615 assert(TPR == TPResult::True || TPR == TPResult::False);
616 return TPR == TPResult::True;
620Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
621 bool OuterMightBeMessageSend) {
626 if (Tok.isRegularKeywordAttribute())
640 RevertingTentativeParsingAction PA(*
this);
648 bool IsAttribute =
SkipUntil(tok::r_square);
649 IsAttribute &= Tok.is(tok::r_square);
668 RevertingTentativeParsingAction LambdaTPA(*
this);
669 LambdaIntroducer Intro;
670 LambdaIntroducerTentativeParse Tentative;
671 if (ParseLambdaIntroducer(Intro, &Tentative)) {
679 case LambdaIntroducerTentativeParse::MessageSend:
684 case LambdaIntroducerTentativeParse::Success:
685 case LambdaIntroducerTentativeParse::Incomplete:
687 if (Tok.is(tok::r_square))
691 if (OuterMightBeMessageSend)
698 case LambdaIntroducerTentativeParse::Invalid:
709 bool IsAttribute =
true;
710 while (Tok.isNot(tok::r_square)) {
711 if (Tok.is(tok::comma)) {
722 if (!TryParseCXX11AttributeIdentifier(Loc)) {
726 if (Tok.is(tok::coloncolon)) {
728 if (!TryParseCXX11AttributeIdentifier(Loc)) {
735 if (Tok.is(tok::l_paren)) {
751 if (Tok.is(tok::r_square)) {
753 IsAttribute = Tok.is(tok::r_square);
767bool Parser::TrySkipAttributes() {
768 while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
770 Tok.isRegularKeywordAttribute()) {
771 if (Tok.is(tok::l_square)) {
778 if (!
SkipUntil(tok::r_square) || Tok.isNot(tok::r_square))
783 }
else if (Tok.isRegularKeywordAttribute() &&
788 if (Tok.isNot(tok::l_paren))
799bool Parser::hasLambdaLikeContinuation() {
800 RevertingTentativeParsingAction TPA(*
this);
808 if (!TrySkipAttributes())
811 if (Tok.isOneOf(tok::l_paren, tok::l_brace, tok::less, tok::arrow,
812 tok::kw_requires, tok::kw_noexcept))
820 if (!isLambdaSpecifier())
827Parser::TPResult Parser::TryParsePtrOperatorSeq() {
830 return TPResult::Error;
832 if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
833 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
838 if (!TrySkipAttributes())
839 return TPResult::Error;
841 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
842 tok::kw__Nonnull, tok::kw__Nullable,
843 tok::kw__Nullable_result, tok::kw__Null_unspecified,
847 return TPResult::True;
852Parser::TPResult Parser::TryParseOperatorId() {
853 assert(Tok.is(tok::kw_operator));
857 switch (Tok.getKind()) {
858 case tok::kw_new:
case tok::kw_delete:
860 if (Tok.is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
864 return TPResult::True;
866#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
868#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
869#include "clang/Basic/OperatorKinds.def"
871 return TPResult::True;
877 return TPResult::True;
885 return TPResult::True;
889 case tok::lesslessless:
894 return TPResult::True;
902 bool FoundUDSuffix =
false;
904 FoundUDSuffix |= Tok.hasUDSuffix();
905 ConsumeStringToken();
906 }
while (isTokenStringLiteral());
908 if (!FoundUDSuffix) {
909 if (Tok.is(tok::identifier))
912 return TPResult::Error;
914 return TPResult::True;
918 bool AnyDeclSpecifiers =
false;
921 if (TPR == TPResult::Error)
923 if (TPR == TPResult::False) {
924 if (!AnyDeclSpecifiers)
925 return TPResult::Error;
928 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
929 return TPResult::Error;
930 AnyDeclSpecifiers =
true;
932 return TryParsePtrOperatorSeq();
935Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
936 bool mayHaveIdentifier,
937 bool mayHaveDirectInit,
938 bool mayHaveTrailingReturnType) {
942 if (TryParsePtrOperatorSeq() == TPResult::Error)
943 return TPResult::Error;
947 if (Tok.is(tok::ellipsis))
950 if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||
951 (Tok.is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
955 if (Tok.is(tok::annot_cxxscope)) {
957 Actions.RestoreNestedNameSpecifierAnnotation(
958 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
960 return TPResult::Error;
961 ConsumeAnnotationToken();
962 }
else if (Tok.is(tok::identifier)) {
963 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
965 if (Tok.is(tok::kw_operator)) {
966 if (TryParseOperatorId() == TPResult::Error)
967 return TPResult::Error;
970 }
else if (Tok.is(tok::l_paren)) {
973 (Tok.is(tok::r_paren) ||
975 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren)) ||
976 isDeclarationSpecifier(
980 TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
981 if (TPR != TPResult::Ambiguous)
987 if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
988 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
989 tok::kw___regcall, tok::kw___vectorcall))
990 return TPResult::True;
991 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
992 if (TPR != TPResult::Ambiguous)
994 if (Tok.isNot(tok::r_paren))
995 return TPResult::False;
998 }
else if (!mayBeAbstract) {
999 return TPResult::False;
1002 if (mayHaveDirectInit)
1003 return TPResult::Ambiguous;
1006 TPResult TPR(TPResult::Ambiguous);
1008 if (Tok.is(tok::l_paren)) {
1013 if (!mayBeAbstract && !isCXXFunctionDeclarator())
1019 TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
1020 }
else if (Tok.is(tok::l_square)) {
1023 TPR = TryParseBracketDeclarator();
1024 }
else if (Tok.is(tok::kw_requires)) {
1027 TPR = TPResult::True;
1032 if (TPR != TPResult::Ambiguous)
1036 return TPResult::Ambiguous;
1040 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
1046 TentativeParseCCC(
const Token &
Next) {
1047 WantRemainingKeywords =
false;
1048 WantTypeSpecifiers =
1049 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
1050 tok::identifier, tok::comma);
1053 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1057 llvm::all_of(Candidate,
1058 [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
1064 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
1065 return std::make_unique<TentativeParseCCC>(*
this);
1072 Parser::TPResult BracedCastResult,
1073 bool *InvalidAsDeclSpec) {
1074 auto IsPlaceholderSpecifier = [&](TemplateIdAnnotation *TemplateId,
1080 .
isOneOf(tok::kw_auto, tok::kw_decltype,
1090 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
1103 switch (Tok.getKind()) {
1104 case tok::identifier: {
1109 return TPResult::Error;
1110 if (Tok.is(tok::identifier))
1111 return TPResult::False;
1113 BracedCastResult, InvalidAsDeclSpec);
1118 if (TryAltiVecVectorToken())
1119 return TPResult::True;
1124 return TPResult::True;
1129 if (
Next.is(tok::l_paren) &&
1130 Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier() &&
1131 isRevertibleTypeTrait(Tok.getIdentifierInfo())) {
1132 return TPResult::False;
1135 if (
Next.isNoneOf(tok::coloncolon, tok::less, tok::colon)) {
1140 TentativeParseCCC CCC(
Next);
1141 switch (TryAnnotateName(&CCC)) {
1143 return TPResult::Error;
1145 return TPResult::False;
1153 return TPResult::Error;
1154 if (Tok.isNot(tok::identifier))
1160 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1162 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1166 assert(Tok.isNot(tok::identifier) &&
1167 "TryAnnotateName succeeded without producing an annotation");
1174 return TPResult::Error;
1178 if (Tok.is(tok::identifier))
1179 return TPResult::False;
1183 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1187 case tok::kw_typename:
1191 return TPResult::Error;
1193 BracedCastResult, InvalidAsDeclSpec);
1195 case tok::kw_auto: {
1197 return TPResult::False;
1199 return TPResult::Ambiguous;
1200 return TPResult::True;
1203 case tok::coloncolon: {
1205 if (
Next.isOneOf(tok::kw_new,
1207 return TPResult::False;
1210 case tok::kw___super:
1211 case tok::kw_decltype:
1215 return TPResult::Error;
1216 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1226 case tok::kw_friend:
1227 case tok::kw_typedef:
1228 case tok::kw_constexpr:
1229 case tok::kw_consteval:
1230 case tok::kw_constinit:
1232 case tok::kw_register:
1233 case tok::kw_static:
1234 case tok::kw_extern:
1235 case tok::kw_mutable:
1236 case tok::kw___thread:
1237 case tok::kw_thread_local:
1238 case tok::kw__Thread_local:
1240 case tok::kw_inline:
1241 case tok::kw_virtual:
1242 case tok::kw_explicit:
1243 case tok::kw__Noreturn:
1246 case tok::kw___module_private__:
1249 case tok::kw___unknown_anytype:
1262 case tok::kw_struct:
1264 case tok::kw___interface:
1269 case tok::kw_volatile:
1270 return TPResult::True;
1273 case tok::kw_private:
1275 return TPResult::False;
1277 case tok::kw___private:
1278 case tok::kw___local:
1279 case tok::kw___global:
1280 case tok::kw___constant:
1281 case tok::kw___generic:
1283 case tok::kw___read_only:
1284 case tok::kw___write_only:
1285 case tok::kw___read_write:
1290 case tok::kw_nointerpolation:
1291 case tok::kw_linear:
1292 case tok::kw_centroid:
1293 case tok::kw_noperspective:
1294 case tok::kw_sample:
1295 case tok::kw_center:
1296 case tok::kw_groupshared:
1301 case tok::kw_row_major:
1302 case tok::kw_column_major:
1305 case tok::kw_restrict:
1306 case tok::kw__Complex:
1307 case tok::kw__Imaginary:
1308 case tok::kw___attribute:
1309 case tok::kw___auto_type:
1310 return TPResult::True;
1313 case tok::kw___ob_wrap:
1314 case tok::kw___ob_trap:
1315 return TPResult::True;
1318 case tok::kw___declspec:
1319 case tok::kw___cdecl:
1320 case tok::kw___stdcall:
1321 case tok::kw___fastcall:
1322 case tok::kw___thiscall:
1323 case tok::kw___regcall:
1324 case tok::kw___vectorcall:
1326 case tok::kw___sptr:
1327 case tok::kw___uptr:
1328 case tok::kw___ptr64:
1329 case tok::kw___ptr32:
1330 case tok::kw___forceinline:
1331 case tok::kw___unaligned:
1332 case tok::kw__Nonnull:
1333 case tok::kw__Nullable:
1334 case tok::kw__Nullable_result:
1335 case tok::kw__Null_unspecified:
1336 case tok::kw___kindof:
1337 return TPResult::True;
1340 case tok::kw___funcref:
1341 return TPResult::True;
1344 case tok::kw___pascal:
1345 return TPResult::True;
1348 case tok::kw___vector:
1349 return TPResult::True;
1351 case tok::kw_this: {
1355 RevertingTentativeParsingAction PA(*
this);
1357 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1360 return TPResult::False;
1362 case tok::annot_template_id: {
1363 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1368 InvalidAsDeclSpec) {
1373 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1374 return TPResult::Ambiguous;
1377 return TPResult::Error;
1378 if (IsPlaceholderSpecifier(TemplateId, 0))
1379 return TPResult::True;
1381 return TPResult::False;
1383 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1384 assert(Tok.is(tok::annot_typename));
1388 case tok::annot_cxxscope:
1391 return TPResult::Error;
1392 if (!Tok.is(tok::annot_typename)) {
1393 if (Tok.is(tok::annot_cxxscope) &&
1395 TemplateIdAnnotation *TemplateId =
1398 if (InvalidAsDeclSpec) {
1399 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1400 return TPResult::Ambiguous;
1402 return TPResult::Error;
1404 if (IsPlaceholderSpecifier(TemplateId, 1))
1405 return TPResult::True;
1409 if (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1411 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1412 Tok.getAnnotationRange(),
1415 RevertingTentativeParsingAction PA(*
this);
1416 ConsumeAnnotationToken();
1418 bool isIdentifier = Tok.is(tok::identifier);
1419 TPResult TPR = TPResult::False;
1421 TPR = isCXXDeclarationSpecifier(
1422 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1425 TPR == TPResult::True || TPR == TPResult::Error)
1426 return TPResult::Error;
1428 if (InvalidAsDeclSpec) {
1431 *InvalidAsDeclSpec =
true;
1432 return TPResult::Ambiguous;
1438 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1441 (Tok.is(tok::ampamp) &&
NextToken().
is(tok::greater)))
1442 return TPResult::True;
1448 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1450 return TPResult::Error;
1452 return TPResult::False;
1458 return TPResult::Error;
1462 if (Tok.isNot(tok::annot_cxxscope) && Tok.isNot(tok::identifier))
1473 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1479 assert(Tok.isNot(tok::annot_cxxscope) ||
1481 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1482 BracedCastResult, InvalidAsDeclSpec);
1485 return TPResult::False;
1508 case tok::annot_typename:
1513 RevertingTentativeParsingAction PA(*
this);
1516 TPResult TPR = TryParseProtocolQualifiers();
1517 bool isFollowedByParen = Tok.is(tok::l_paren);
1518 bool isFollowedByBrace = Tok.is(tok::l_brace);
1520 if (TPR == TPResult::Error)
1521 return TPResult::Error;
1523 if (isFollowedByParen)
1524 return TPResult::Ambiguous;
1527 return BracedCastResult;
1529 return TPResult::True;
1535 case tok::kw_wchar_t:
1536 case tok::kw_char8_t:
1537 case tok::kw_char16_t:
1538 case tok::kw_char32_t:
1543 case tok::kw___int64:
1544 case tok::kw___int128:
1545 case tok::kw_signed:
1546 case tok::kw_unsigned:
1549 case tok::kw_double:
1550 case tok::kw___bf16:
1551 case tok::kw__Float16:
1552 case tok::kw___float128:
1553 case tok::kw___ibm128:
1555 case tok::annot_decltype:
1556 case tok::kw__Accum:
1557 case tok::kw__Fract:
1559 case tok::annot_pack_indexing_type:
1560#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1561#include "clang/Basic/OpenCLImageTypes.def"
1562#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1563#include "clang/Basic/HLSLIntangibleTypes.def"
1564#define HLSL_PACKED_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1565#include "clang/Basic/HLSLPackedTypes.def"
1567 return TPResult::Ambiguous;
1576 if (ParsingGenericAssociationType) {
1577 RevertingTentativeParsingAction PA(*
this);
1582 if (Tok.is(tok::colon)) {
1583 return TPResult::True;
1587 return BracedCastResult;
1590 if (isStartOfObjCClassMessageMissingOpenBracket())
1591 return TPResult::False;
1593 return TPResult::True;
1596 case tok::kw_typeof:
1597 case tok::kw_typeof_unqual: {
1599 return TPResult::True;
1601 RevertingTentativeParsingAction PA(*
this);
1603 TPResult TPR = TryParseTypeofSpecifier();
1604 bool isFollowedByParen = Tok.is(tok::l_paren);
1605 bool isFollowedByBrace = Tok.is(tok::l_brace);
1607 if (TPR == TPResult::Error)
1608 return TPResult::Error;
1610 if (isFollowedByParen)
1611 return TPResult::Ambiguous;
1614 return BracedCastResult;
1616 return TPResult::True;
1619#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1620#include "clang/Basic/BuiltinTraits.inc"
1621 return TPResult::True;
1624 case tok::kw__Alignas:
1625 return TPResult::True;
1627 case tok::kw__Atomic:
1628 return TPResult::True;
1630 case tok::kw__BitInt:
1631 case tok::kw__ExtInt: {
1633 return TPResult::Error;
1634 RevertingTentativeParsingAction PA(*
this);
1639 return TPResult::Error;
1641 if (Tok.is(tok::l_paren))
1642 return TPResult::Ambiguous;
1645 return BracedCastResult;
1647 return TPResult::True;
1650 return TPResult::False;
1654bool Parser::isCXXDeclarationSpecifierAType() {
1655 switch (Tok.getKind()) {
1657 case tok::annot_decltype:
1658 case tok::annot_pack_indexing_type:
1659 case tok::annot_template_id:
1660 case tok::annot_typename:
1661 case tok::kw_typeof:
1662 case tok::kw_typeof_unqual:
1663#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1664#include "clang/Basic/BuiltinTraits.inc"
1669 case tok::kw_struct:
1671 case tok::kw___interface:
1677 case tok::kw_wchar_t:
1678 case tok::kw_char8_t:
1679 case tok::kw_char16_t:
1680 case tok::kw_char32_t:
1684 case tok::kw__ExtInt:
1685 case tok::kw__BitInt:
1687 case tok::kw___int64:
1688 case tok::kw___int128:
1689 case tok::kw_signed:
1690 case tok::kw_unsigned:
1693 case tok::kw_double:
1694 case tok::kw___bf16:
1695 case tok::kw__Float16:
1696 case tok::kw___float128:
1697 case tok::kw___ibm128:
1699 case tok::kw___unknown_anytype:
1700 case tok::kw___auto_type:
1701 case tok::kw__Accum:
1702 case tok::kw__Fract:
1704#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1705#include "clang/Basic/OpenCLImageTypes.def"
1706#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1707#include "clang/Basic/HLSLIntangibleTypes.def"
1708#define HLSL_PACKED_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1709#include "clang/Basic/HLSLPackedTypes.def"
1715 case tok::kw__Atomic:
1724Parser::TPResult Parser::TryParseTypeofSpecifier() {
1725 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
1726 "Expected 'typeof' or 'typeof_unqual'!");
1729 assert(Tok.is(tok::l_paren) &&
"Expected '('");
1733 return TPResult::Error;
1735 return TPResult::Ambiguous;
1738Parser::TPResult Parser::TryParseProtocolQualifiers() {
1739 assert(Tok.is(tok::less) &&
"Expected '<' for qualifier list");
1742 if (Tok.isNot(tok::identifier))
1743 return TPResult::Error;
1746 if (Tok.is(tok::comma)) {
1751 if (Tok.is(tok::greater)) {
1753 return TPResult::Ambiguous;
1757 return TPResult::Error;
1760bool Parser::isCXXFunctionDeclarator(
1772 RevertingTentativeParsingAction PA(*
this);
1775 bool InvalidAsDeclaration =
false;
1776 TPResult TPR = TryParseParameterDeclarationClause(
1777 &InvalidAsDeclaration,
false,
1778 AllowImplicitTypename);
1779 if (TPR == TPResult::Ambiguous) {
1780 if (Tok.isNot(tok::r_paren))
1781 TPR = TPResult::False;
1784 if (
Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1785 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1786 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1787 isCXX11VirtSpecifier(
Next))
1791 TPR = TPResult::True;
1792 else if (InvalidAsDeclaration)
1794 TPR = TPResult::False;
1798 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1799 *IsAmbiguous =
true;
1802 return TPR != TPResult::False;
1805Parser::TPResult Parser::TryParseParameterDeclarationClause(
1806 bool *InvalidAsDeclaration,
bool VersusTemplateArgument,
1809 if (Tok.is(tok::r_paren))
1810 return TPResult::Ambiguous;
1821 if (Tok.is(tok::ellipsis)) {
1823 if (Tok.is(tok::r_paren))
1824 return TPResult::True;
1826 return TPResult::False;
1830 if (isCXX11AttributeSpecifier(
false,
1833 return TPResult::True;
1836 Tok.is(tok::l_square) && hasLambdaLikeContinuation())
1837 return TPResult::False;
1839 ParsedAttributes attrs(AttrFactory);
1840 MaybeParseMicrosoftAttributes(attrs);
1845 TPResult TPR = isCXXDeclarationSpecifier(
1846 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
1849 if (TPR != TPResult::Ambiguous &&
1850 !(VersusTemplateArgument && TPR == TPResult::True))
1853 bool SeenType =
false;
1854 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
1856 SeenType |= isCXXDeclarationSpecifierAType();
1857 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1858 return TPResult::Error;
1861 if (SeenType && Tok.is(tok::identifier))
1862 return TPResult::True;
1864 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
1865 InvalidAsDeclaration);
1866 if (TPR == TPResult::Error)
1870 if (TPR == TPResult::True && !VersusTemplateArgument)
1872 }
while (TPR != TPResult::False);
1876 TPR = TryParseDeclarator(
1880 DeclarationSpecifierIsAuto);
1881 if (TPR != TPResult::Ambiguous)
1885 if (Tok.is(tok::kw___attribute))
1886 return TPResult::True;
1897 if (VersusTemplateArgument)
1898 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;
1900 if (Tok.is(tok::equal)) {
1904 return TPResult::Error;
1907 if (Tok.is(tok::ellipsis)) {
1909 if (Tok.is(tok::r_paren))
1910 return TPResult::True;
1912 return TPResult::False;
1919 return TPResult::Ambiguous;
1923Parser::TryParseFunctionDeclarator(
bool MayHaveTrailingReturnType) {
1926 TPResult TPR = TryParseParameterDeclarationClause();
1927 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
1928 TPR = TPResult::False;
1930 if (TPR == TPResult::False || TPR == TPResult::Error)
1935 return TPResult::Error;
1938 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1943 if (Tok.isOneOf(tok::amp, tok::ampamp))
1947 if (Tok.is(tok::kw_throw)) {
1949 if (Tok.isNot(tok::l_paren))
1950 return TPResult::Error;
1955 return TPResult::Error;
1957 if (Tok.is(tok::kw_noexcept)) {
1960 if (Tok.is(tok::l_paren)) {
1964 return TPResult::Error;
1969 if (!TrySkipAttributes())
1970 return TPResult::Ambiguous;
1973 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
1974 if (TPR == TPResult::True)
1977 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
1978 return TPResult::False;
1981 return TPResult::True;
1984 return TPResult::Ambiguous;
1987bool Parser::NameAfterArrowIsNonType() {
1988 assert(Tok.is(tok::identifier));
1990 if (
Next.is(tok::coloncolon))
1992 IdentifierInfo *Name = Tok.getIdentifierInfo();
1993 SourceLocation NameLoc = Tok.getLocation();
1995 TentativeParseCCC CCC(
Next);
1996 Sema::NameClassification Classification =
1998 switch (Classification.
getKind()) {
2010Parser::TPResult Parser::TryParseBracketDeclarator() {
2015 if (Tok.is(tok::l_brace))
2016 return TPResult::False;
2019 return TPResult::Error;
2023 if (Tok.isNot(tok::r_square))
2024 return TPResult::False;
2027 return TPResult::Ambiguous;
2030Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
2031 if (!TokensToSkip) {
2032 if (Tok.isNot(tok::less))
2033 return TPResult::False;
2035 return TPResult::True;
2038 RevertingTentativeParsingAction PA(*
this);
2040 while (TokensToSkip) {
2046 return TPResult::False;
2051 bool InvalidAsTemplateArgumentList =
false;
2053 &InvalidAsTemplateArgumentList) ==
2055 return TPResult::True;
2056 if (InvalidAsTemplateArgumentList)
2057 return TPResult::False;
2071 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2073 return TPResult::Ambiguous;
2074 return TPResult::False;
2077Parser::TPResult Parser::isExplicitBool() {
2078 assert(Tok.is(tok::l_paren) &&
"expected to be looking at a '(' token");
2080 RevertingTentativeParsingAction PA(*
this);
2088 while (Tok.is(tok::l_paren))
2092 return TPResult::Error;
2097 if (Tok.is(tok::annot_cxxscope)) {
2098 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2099 Tok.getAnnotationRange(),
2101 ConsumeAnnotationToken();
2106 if (Tok.is(tok::kw_operator))
2107 return TPResult::Ambiguous;
2110 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
2111 return TPResult::True;
2112 if (!Actions.isCurrentClassName(Tok.is(tok::identifier)
2113 ? *Tok.getIdentifierInfo()
2114 : *takeTemplateIdAnnotation(Tok)->Name,
2116 return TPResult::True;
2122 !isConstructorDeclarator(SS.
isEmpty(),
2124 return TPResult::True;
2127 return TPResult::Ambiguous;
static constexpr bool isOneOf()
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
NestedNameSpecifier getScopeRep() const
Retrieve the representation of the nested-name-specifier.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
bool isEmpty() const
No scope specifier.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
One of these records is kept for each identifier that is lexed.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, bool IsAddressOfOperand=false)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies)
bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext=false)
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
const LangOptions & getLangOpts() const
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
NameClassificationKind getKind() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
bool isOneOf(Ts... Ks) const
Top level wrappers for InstallAPI frontend operations.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
CXX11AttributeKind
The kind of attribute specifier we have found.
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ Unresolved
The identifier can't be resolved.
@ Success
Annotation was successful.
@ Error
Annotation has failed and emitted an error.
@ TentativeDecl
The identifier is a tentatively-declared name.
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
TentativeCXXTypeIdContext
Specifies the context in which type-id/expression disambiguation will occur.
@ AsGenericSelectionArgument
@ FunctionTemplate
The name was classified as a function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ VarTemplate
The name was classified as a variable template name.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
bool markNotForRangeDecl()
ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement, bool CanBeForRangeDecl)
bool update(TPResult IsDecl)
ConditionOrInitStatement result() const
bool hasInvalidName() const
TemplateNameKind Kind
The kind of template that Template refers to.
unsigned NumArgs
NumArgs - The number of template arguments.