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))
799Parser::TPResult Parser::TryParsePtrOperatorSeq() {
802 return TPResult::Error;
804 if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
805 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
810 if (!TrySkipAttributes())
811 return TPResult::Error;
813 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
814 tok::kw__Nonnull, tok::kw__Nullable,
815 tok::kw__Nullable_result, tok::kw__Null_unspecified,
819 return TPResult::True;
824Parser::TPResult Parser::TryParseOperatorId() {
825 assert(Tok.is(tok::kw_operator));
829 switch (Tok.getKind()) {
830 case tok::kw_new:
case tok::kw_delete:
832 if (Tok.is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
836 return TPResult::True;
838#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
840#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
841#include "clang/Basic/OperatorKinds.def"
843 return TPResult::True;
849 return TPResult::True;
857 return TPResult::True;
867 bool FoundUDSuffix =
false;
869 FoundUDSuffix |= Tok.hasUDSuffix();
870 ConsumeStringToken();
871 }
while (isTokenStringLiteral());
873 if (!FoundUDSuffix) {
874 if (Tok.is(tok::identifier))
877 return TPResult::Error;
879 return TPResult::True;
883 bool AnyDeclSpecifiers =
false;
886 if (TPR == TPResult::Error)
888 if (TPR == TPResult::False) {
889 if (!AnyDeclSpecifiers)
890 return TPResult::Error;
893 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
894 return TPResult::Error;
895 AnyDeclSpecifiers =
true;
897 return TryParsePtrOperatorSeq();
900Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
901 bool mayHaveIdentifier,
902 bool mayHaveDirectInit,
903 bool mayHaveTrailingReturnType) {
907 if (TryParsePtrOperatorSeq() == TPResult::Error)
908 return TPResult::Error;
912 if (Tok.is(tok::ellipsis))
915 if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||
916 (Tok.is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
920 if (Tok.is(tok::annot_cxxscope)) {
922 Actions.RestoreNestedNameSpecifierAnnotation(
923 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
925 return TPResult::Error;
926 ConsumeAnnotationToken();
927 }
else if (Tok.is(tok::identifier)) {
928 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
930 if (Tok.is(tok::kw_operator)) {
931 if (TryParseOperatorId() == TPResult::Error)
932 return TPResult::Error;
935 }
else if (Tok.is(tok::l_paren)) {
938 (Tok.is(tok::r_paren) ||
940 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren)) ||
941 isDeclarationSpecifier(
945 TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
946 if (TPR != TPResult::Ambiguous)
952 if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
953 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
954 tok::kw___regcall, tok::kw___vectorcall))
955 return TPResult::True;
956 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
957 if (TPR != TPResult::Ambiguous)
959 if (Tok.isNot(tok::r_paren))
960 return TPResult::False;
963 }
else if (!mayBeAbstract) {
964 return TPResult::False;
967 if (mayHaveDirectInit)
968 return TPResult::Ambiguous;
971 TPResult TPR(TPResult::Ambiguous);
973 if (Tok.is(tok::l_paren)) {
978 if (!mayBeAbstract && !isCXXFunctionDeclarator())
984 TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
985 }
else if (Tok.is(tok::l_square)) {
988 TPR = TryParseBracketDeclarator();
989 }
else if (Tok.is(tok::kw_requires)) {
992 TPR = TPResult::True;
997 if (TPR != TPResult::Ambiguous)
1001 return TPResult::Ambiguous;
1005 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
1011 TentativeParseCCC(
const Token &
Next) {
1012 WantRemainingKeywords =
false;
1013 WantTypeSpecifiers =
1014 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
1015 tok::identifier, tok::comma);
1018 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1022 llvm::all_of(Candidate,
1023 [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
1029 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
1030 return std::make_unique<TentativeParseCCC>(*
this);
1037 Parser::TPResult BracedCastResult,
1038 bool *InvalidAsDeclSpec) {
1039 auto IsPlaceholderSpecifier = [&](TemplateIdAnnotation *TemplateId,
1045 .
isOneOf(tok::kw_auto, tok::kw_decltype,
1055 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
1068 switch (Tok.getKind()) {
1069 case tok::identifier: {
1074 return TPResult::Error;
1075 if (Tok.is(tok::identifier))
1076 return TPResult::False;
1078 BracedCastResult, InvalidAsDeclSpec);
1083 if (TryAltiVecVectorToken())
1084 return TPResult::True;
1089 return TPResult::True;
1094 if (
Next.is(tok::l_paren) &&
1095 Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier() &&
1096 isRevertibleTypeTrait(Tok.getIdentifierInfo())) {
1097 return TPResult::False;
1100 if (
Next.isNoneOf(tok::coloncolon, tok::less, tok::colon)) {
1105 TentativeParseCCC CCC(
Next);
1106 switch (TryAnnotateName(&CCC)) {
1108 return TPResult::Error;
1110 return TPResult::False;
1118 return TPResult::Error;
1119 if (Tok.isNot(tok::identifier))
1125 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1127 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1131 assert(Tok.isNot(tok::identifier) &&
1132 "TryAnnotateName succeeded without producing an annotation");
1139 return TPResult::Error;
1143 if (Tok.is(tok::identifier))
1144 return TPResult::False;
1148 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1152 case tok::kw_typename:
1156 return TPResult::Error;
1158 BracedCastResult, InvalidAsDeclSpec);
1160 case tok::kw_auto: {
1162 return TPResult::False;
1164 return TPResult::Ambiguous;
1165 return TPResult::True;
1168 case tok::coloncolon: {
1170 if (
Next.isOneOf(tok::kw_new,
1172 return TPResult::False;
1175 case tok::kw___super:
1176 case tok::kw_decltype:
1180 return TPResult::Error;
1181 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1191 case tok::kw_friend:
1192 case tok::kw_typedef:
1193 case tok::kw_constexpr:
1194 case tok::kw_consteval:
1195 case tok::kw_constinit:
1197 case tok::kw_register:
1198 case tok::kw_static:
1199 case tok::kw_extern:
1200 case tok::kw_mutable:
1201 case tok::kw___thread:
1202 case tok::kw_thread_local:
1203 case tok::kw__Thread_local:
1205 case tok::kw_inline:
1206 case tok::kw_virtual:
1207 case tok::kw_explicit:
1208 case tok::kw__Noreturn:
1211 case tok::kw___module_private__:
1214 case tok::kw___unknown_anytype:
1227 case tok::kw_struct:
1229 case tok::kw___interface:
1234 case tok::kw_volatile:
1235 return TPResult::True;
1238 case tok::kw_private:
1240 return TPResult::False;
1242 case tok::kw___private:
1243 case tok::kw___local:
1244 case tok::kw___global:
1245 case tok::kw___constant:
1246 case tok::kw___generic:
1248 case tok::kw___read_only:
1249 case tok::kw___write_only:
1250 case tok::kw___read_write:
1255 case tok::kw_groupshared:
1260 case tok::kw_row_major:
1261 case tok::kw_column_major:
1264 case tok::kw_restrict:
1265 case tok::kw__Complex:
1266 case tok::kw__Imaginary:
1267 case tok::kw___attribute:
1268 case tok::kw___auto_type:
1269 return TPResult::True;
1272 case tok::kw___ob_wrap:
1273 case tok::kw___ob_trap:
1274 return TPResult::True;
1277 case tok::kw___declspec:
1278 case tok::kw___cdecl:
1279 case tok::kw___stdcall:
1280 case tok::kw___fastcall:
1281 case tok::kw___thiscall:
1282 case tok::kw___regcall:
1283 case tok::kw___vectorcall:
1285 case tok::kw___sptr:
1286 case tok::kw___uptr:
1287 case tok::kw___ptr64:
1288 case tok::kw___ptr32:
1289 case tok::kw___forceinline:
1290 case tok::kw___unaligned:
1291 case tok::kw__Nonnull:
1292 case tok::kw__Nullable:
1293 case tok::kw__Nullable_result:
1294 case tok::kw__Null_unspecified:
1295 case tok::kw___kindof:
1296 return TPResult::True;
1299 case tok::kw___funcref:
1300 return TPResult::True;
1303 case tok::kw___pascal:
1304 return TPResult::True;
1307 case tok::kw___vector:
1308 return TPResult::True;
1310 case tok::kw_this: {
1314 RevertingTentativeParsingAction PA(*
this);
1316 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1319 return TPResult::False;
1321 case tok::annot_template_id: {
1322 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1327 InvalidAsDeclSpec) {
1332 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1333 return TPResult::Ambiguous;
1336 return TPResult::Error;
1337 if (IsPlaceholderSpecifier(TemplateId, 0))
1338 return TPResult::True;
1340 return TPResult::False;
1342 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1343 assert(Tok.is(tok::annot_typename));
1347 case tok::annot_cxxscope:
1350 return TPResult::Error;
1351 if (!Tok.is(tok::annot_typename)) {
1352 if (Tok.is(tok::annot_cxxscope) &&
1354 TemplateIdAnnotation *TemplateId =
1357 if (InvalidAsDeclSpec) {
1358 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1359 return TPResult::Ambiguous;
1361 return TPResult::Error;
1363 if (IsPlaceholderSpecifier(TemplateId, 1))
1364 return TPResult::True;
1368 if (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1370 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1371 Tok.getAnnotationRange(),
1374 RevertingTentativeParsingAction PA(*
this);
1375 ConsumeAnnotationToken();
1377 bool isIdentifier = Tok.is(tok::identifier);
1378 TPResult TPR = TPResult::False;
1380 TPR = isCXXDeclarationSpecifier(
1381 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1384 TPR == TPResult::True || TPR == TPResult::Error)
1385 return TPResult::Error;
1387 if (InvalidAsDeclSpec) {
1390 *InvalidAsDeclSpec =
true;
1391 return TPResult::Ambiguous;
1397 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1400 (Tok.is(tok::ampamp) &&
NextToken().
is(tok::greater)))
1401 return TPResult::True;
1407 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1409 return TPResult::Error;
1411 return TPResult::False;
1417 return TPResult::Error;
1421 if (Tok.isNot(tok::annot_cxxscope) && Tok.isNot(tok::identifier))
1432 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1438 assert(Tok.isNot(tok::annot_cxxscope) ||
1440 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1441 BracedCastResult, InvalidAsDeclSpec);
1444 return TPResult::False;
1467 case tok::annot_typename:
1472 RevertingTentativeParsingAction PA(*
this);
1475 TPResult TPR = TryParseProtocolQualifiers();
1476 bool isFollowedByParen = Tok.is(tok::l_paren);
1477 bool isFollowedByBrace = Tok.is(tok::l_brace);
1479 if (TPR == TPResult::Error)
1480 return TPResult::Error;
1482 if (isFollowedByParen)
1483 return TPResult::Ambiguous;
1486 return BracedCastResult;
1488 return TPResult::True;
1494 case tok::kw_wchar_t:
1495 case tok::kw_char8_t:
1496 case tok::kw_char16_t:
1497 case tok::kw_char32_t:
1502 case tok::kw___int64:
1503 case tok::kw___int128:
1504 case tok::kw_signed:
1505 case tok::kw_unsigned:
1508 case tok::kw_double:
1509 case tok::kw___bf16:
1510 case tok::kw__Float16:
1511 case tok::kw___float128:
1512 case tok::kw___ibm128:
1514 case tok::annot_decltype:
1515 case tok::kw__Accum:
1516 case tok::kw__Fract:
1518 case tok::annot_pack_indexing_type:
1519#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1520#include "clang/Basic/OpenCLImageTypes.def"
1521#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1522#include "clang/Basic/HLSLIntangibleTypes.def"
1524 return TPResult::Ambiguous;
1533 return BracedCastResult;
1535 if (isStartOfObjCClassMessageMissingOpenBracket())
1536 return TPResult::False;
1538 return TPResult::True;
1541 case tok::kw_typeof:
1542 case tok::kw_typeof_unqual: {
1544 return TPResult::True;
1546 RevertingTentativeParsingAction PA(*
this);
1548 TPResult TPR = TryParseTypeofSpecifier();
1549 bool isFollowedByParen = Tok.is(tok::l_paren);
1550 bool isFollowedByBrace = Tok.is(tok::l_brace);
1552 if (TPR == TPResult::Error)
1553 return TPResult::Error;
1555 if (isFollowedByParen)
1556 return TPResult::Ambiguous;
1559 return BracedCastResult;
1561 return TPResult::True;
1564#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1565#include "clang/Basic/BuiltinTraits.inc"
1566 return TPResult::True;
1569 case tok::kw__Alignas:
1570 return TPResult::True;
1572 case tok::kw__Atomic:
1573 return TPResult::True;
1575 case tok::kw__BitInt:
1576 case tok::kw__ExtInt: {
1578 return TPResult::Error;
1579 RevertingTentativeParsingAction PA(*
this);
1584 return TPResult::Error;
1586 if (Tok.is(tok::l_paren))
1587 return TPResult::Ambiguous;
1590 return BracedCastResult;
1592 return TPResult::True;
1595 return TPResult::False;
1599bool Parser::isCXXDeclarationSpecifierAType() {
1600 switch (Tok.getKind()) {
1602 case tok::annot_decltype:
1603 case tok::annot_pack_indexing_type:
1604 case tok::annot_template_id:
1605 case tok::annot_typename:
1606 case tok::kw_typeof:
1607 case tok::kw_typeof_unqual:
1608#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1609#include "clang/Basic/BuiltinTraits.inc"
1614 case tok::kw_struct:
1616 case tok::kw___interface:
1622 case tok::kw_wchar_t:
1623 case tok::kw_char8_t:
1624 case tok::kw_char16_t:
1625 case tok::kw_char32_t:
1629 case tok::kw__ExtInt:
1630 case tok::kw__BitInt:
1632 case tok::kw___int64:
1633 case tok::kw___int128:
1634 case tok::kw_signed:
1635 case tok::kw_unsigned:
1638 case tok::kw_double:
1639 case tok::kw___bf16:
1640 case tok::kw__Float16:
1641 case tok::kw___float128:
1642 case tok::kw___ibm128:
1644 case tok::kw___unknown_anytype:
1645 case tok::kw___auto_type:
1646 case tok::kw__Accum:
1647 case tok::kw__Fract:
1649#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1650#include "clang/Basic/OpenCLImageTypes.def"
1651#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1652#include "clang/Basic/HLSLIntangibleTypes.def"
1658 case tok::kw__Atomic:
1667Parser::TPResult Parser::TryParseTypeofSpecifier() {
1668 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
1669 "Expected 'typeof' or 'typeof_unqual'!");
1672 assert(Tok.is(tok::l_paren) &&
"Expected '('");
1676 return TPResult::Error;
1678 return TPResult::Ambiguous;
1681Parser::TPResult Parser::TryParseProtocolQualifiers() {
1682 assert(Tok.is(tok::less) &&
"Expected '<' for qualifier list");
1685 if (Tok.isNot(tok::identifier))
1686 return TPResult::Error;
1689 if (Tok.is(tok::comma)) {
1694 if (Tok.is(tok::greater)) {
1696 return TPResult::Ambiguous;
1700 return TPResult::Error;
1703bool Parser::isCXXFunctionDeclarator(
1715 RevertingTentativeParsingAction PA(*
this);
1718 bool InvalidAsDeclaration =
false;
1719 TPResult TPR = TryParseParameterDeclarationClause(
1720 &InvalidAsDeclaration,
false,
1721 AllowImplicitTypename);
1722 if (TPR == TPResult::Ambiguous) {
1723 if (Tok.isNot(tok::r_paren))
1724 TPR = TPResult::False;
1727 if (
Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1728 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1729 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1730 isCXX11VirtSpecifier(
Next))
1734 TPR = TPResult::True;
1735 else if (InvalidAsDeclaration)
1737 TPR = TPResult::False;
1741 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1742 *IsAmbiguous =
true;
1745 return TPR != TPResult::False;
1748Parser::TPResult Parser::TryParseParameterDeclarationClause(
1749 bool *InvalidAsDeclaration,
bool VersusTemplateArgument,
1752 if (Tok.is(tok::r_paren))
1753 return TPResult::Ambiguous;
1764 if (Tok.is(tok::ellipsis)) {
1766 if (Tok.is(tok::r_paren))
1767 return TPResult::True;
1769 return TPResult::False;
1773 if (isCXX11AttributeSpecifier(
false,
1776 return TPResult::True;
1778 ParsedAttributes attrs(AttrFactory);
1779 MaybeParseMicrosoftAttributes(attrs);
1784 TPResult TPR = isCXXDeclarationSpecifier(
1785 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
1788 if (TPR != TPResult::Ambiguous &&
1789 !(VersusTemplateArgument && TPR == TPResult::True))
1792 bool SeenType =
false;
1793 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
1795 SeenType |= isCXXDeclarationSpecifierAType();
1796 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1797 return TPResult::Error;
1800 if (SeenType && Tok.is(tok::identifier))
1801 return TPResult::True;
1803 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
1804 InvalidAsDeclaration);
1805 if (TPR == TPResult::Error)
1809 if (TPR == TPResult::True && !VersusTemplateArgument)
1811 }
while (TPR != TPResult::False);
1815 TPR = TryParseDeclarator(
1819 DeclarationSpecifierIsAuto);
1820 if (TPR != TPResult::Ambiguous)
1824 if (Tok.is(tok::kw___attribute))
1825 return TPResult::True;
1836 if (VersusTemplateArgument)
1837 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;
1839 if (Tok.is(tok::equal)) {
1843 return TPResult::Error;
1846 if (Tok.is(tok::ellipsis)) {
1848 if (Tok.is(tok::r_paren))
1849 return TPResult::True;
1851 return TPResult::False;
1858 return TPResult::Ambiguous;
1862Parser::TryParseFunctionDeclarator(
bool MayHaveTrailingReturnType) {
1865 TPResult TPR = TryParseParameterDeclarationClause();
1866 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
1867 TPR = TPResult::False;
1869 if (TPR == TPResult::False || TPR == TPResult::Error)
1874 return TPResult::Error;
1877 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1882 if (Tok.isOneOf(tok::amp, tok::ampamp))
1886 if (Tok.is(tok::kw_throw)) {
1888 if (Tok.isNot(tok::l_paren))
1889 return TPResult::Error;
1894 return TPResult::Error;
1896 if (Tok.is(tok::kw_noexcept)) {
1899 if (Tok.is(tok::l_paren)) {
1903 return TPResult::Error;
1908 if (!TrySkipAttributes())
1909 return TPResult::Ambiguous;
1912 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
1913 if (TPR == TPResult::True)
1916 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
1917 return TPResult::False;
1920 return TPResult::True;
1923 return TPResult::Ambiguous;
1926bool Parser::NameAfterArrowIsNonType() {
1927 assert(Tok.is(tok::identifier));
1929 if (
Next.is(tok::coloncolon))
1931 IdentifierInfo *Name = Tok.getIdentifierInfo();
1932 SourceLocation NameLoc = Tok.getLocation();
1934 TentativeParseCCC CCC(
Next);
1935 Sema::NameClassification Classification =
1937 switch (Classification.
getKind()) {
1949Parser::TPResult Parser::TryParseBracketDeclarator() {
1954 if (Tok.is(tok::l_brace))
1955 return TPResult::False;
1958 return TPResult::Error;
1962 if (Tok.isNot(tok::r_square))
1963 return TPResult::False;
1966 return TPResult::Ambiguous;
1969Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
1970 if (!TokensToSkip) {
1971 if (Tok.isNot(tok::less))
1972 return TPResult::False;
1974 return TPResult::True;
1977 RevertingTentativeParsingAction PA(*
this);
1979 while (TokensToSkip) {
1985 return TPResult::False;
1990 bool InvalidAsTemplateArgumentList =
false;
1992 &InvalidAsTemplateArgumentList) ==
1994 return TPResult::True;
1995 if (InvalidAsTemplateArgumentList)
1996 return TPResult::False;
2010 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
2012 return TPResult::Ambiguous;
2013 return TPResult::False;
2016Parser::TPResult Parser::isExplicitBool() {
2017 assert(Tok.is(tok::l_paren) &&
"expected to be looking at a '(' token");
2019 RevertingTentativeParsingAction PA(*
this);
2027 while (Tok.is(tok::l_paren))
2031 return TPResult::Error;
2036 if (Tok.is(tok::annot_cxxscope)) {
2037 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2038 Tok.getAnnotationRange(),
2040 ConsumeAnnotationToken();
2045 if (Tok.is(tok::kw_operator))
2046 return TPResult::Ambiguous;
2049 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
2050 return TPResult::True;
2051 if (!Actions.isCurrentClassName(Tok.is(tok::identifier)
2052 ? *Tok.getIdentifierInfo()
2053 : *takeTemplateIdAnnotation(Tok)->Name,
2055 return TPResult::True;
2061 !isConstructorDeclarator(SS.
isEmpty(),
2063 return TPResult::True;
2066 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.