18bool Parser::isCXXDeclarationStatement(
19 bool DisambiguatingWithExpression ) {
22 switch (Tok.getKind()) {
26 case tok::kw_namespace:
31 case tok::kw_static_assert:
32 case tok::kw__Static_assert:
35 case tok::identifier: {
36 if (DisambiguatingWithExpression) {
37 RevertingTentativeParsingAction TPA(*
this);
40 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
44 switch (Tok.getKind()) {
45 case tok::identifier: {
46 IdentifierInfo *II = Tok.getIdentifierInfo();
47 bool isDeductionGuide = Actions.isDeductionGuideName(
48 getCurScope(), *II, Tok.getLocation(), SS,
nullptr);
49 if (Actions.isCurrentClassName(*II,
getCurScope(), &SS) ||
51 if (isConstructorDeclarator(
69 case tok::kw_operator:
81 return isCXXSimpleDeclaration(
false);
85bool Parser::isCXXSimpleDeclaration(
bool AllowForRangeDecl) {
110 bool InvalidAsDeclaration =
false;
111 TPResult TPR = isCXXDeclarationSpecifier(
113 if (TPR != TPResult::Ambiguous)
114 return TPR != TPResult::False;
122 if (InvalidAsDeclaration)
133 RevertingTentativeParsingAction PA(*
this);
134 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
138 if (TPR == TPResult::Error)
142 if (TPR == TPResult::Ambiguous)
143 TPR = TPResult::True;
145 assert(TPR == TPResult::True || TPR == TPResult::False);
146 return TPR == TPResult::True;
149Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
150 switch (Tok.getKind()) {
151 case tok::kw__Atomic:
158 case tok::kw___attribute:
159#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
160#include "clang/Basic/TransformTypeTraits.def"
163 if (Tok.isNot(tok::l_paren))
164 return TPResult::Error;
167 return TPResult::Error;
174 case tok::kw___interface:
186 if (!TrySkipAttributes())
187 return TPResult::Error;
190 return TPResult::Error;
191 if (Tok.is(tok::annot_cxxscope))
192 ConsumeAnnotationToken();
193 if (Tok.is(tok::identifier))
195 else if (Tok.is(tok::annot_template_id))
196 ConsumeAnnotationToken();
198 return TPResult::Error;
201 case tok::annot_cxxscope:
202 ConsumeAnnotationToken();
208 return TryParseProtocolQualifiers();
212 return TPResult::Ambiguous;
215Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
216 bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);
217 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
218 return TPResult::Error;
223 if (Tok.isNot(tok::l_paren)) {
225 if (TPR == TPResult::Ambiguous)
226 return TPResult::True;
227 if (TPR == TPResult::True || TPR == TPResult::Error)
229 assert(TPR == TPResult::False);
232 TPResult TPR = TryParseInitDeclaratorList(
233 DeclSpecifierIsAuto);
234 if (TPR != TPResult::Ambiguous)
237 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
238 return TPResult::False;
240 return TPResult::Ambiguous;
244Parser::TryParseInitDeclaratorList(
bool MayHaveTrailingReturnType) {
247 TPResult TPR = TryParseDeclarator(
251 MayHaveTrailingReturnType);
252 if (TPR != TPResult::Ambiguous)
256 if (Tok.isOneOf(tok::kw_asm, tok::kw___attribute))
257 return TPResult::True;
260 if (Tok.is(tok::l_paren)) {
264 return TPResult::Error;
265 }
else if (Tok.is(tok::l_brace)) {
268 return TPResult::True;
269 }
else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
286 return TPResult::True;
293 return TPResult::Ambiguous;
321 RevertingTentativeParsingAction PA(
P);
325 unsigned QuestionColonDepth = 0;
327 P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
329 if (
P.Tok.is(tok::question))
330 ++QuestionColonDepth;
331 else if (
P.Tok.is(tok::colon)) {
332 if (QuestionColonDepth)
333 --QuestionColonDepth;
348 if (
P.Tok.isNot(tok::r_paren))
350 if (
P.Tok.isNot(tok::semi))
369 assert(
resolved() &&
"can't continue after tentative parsing bails out");
371 case TPResult::False:
374 case TPResult::Ambiguous:
376 case TPResult::Error:
384 ConditionOrInitStatement
result()
const {
387 "result called but not yet resolved");
389 return ConditionOrInitStatement::Expression;
391 return ConditionOrInitStatement::ConditionDecl;
393 return ConditionOrInitStatement::InitStmtDecl;
395 return ConditionOrInitStatement::ForRangeDecl;
396 return ConditionOrInitStatement::Error;
400bool Parser::isEnumBase(
bool AllowSemi) {
401 assert(
Tok.is(tok::colon) &&
"should be looking at the ':'");
403 RevertingTentativeParsingAction PA(*
this);
408 bool InvalidAsDeclSpec =
false;
415 if (R == TPResult::Ambiguous) {
418 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
423 if (
Tok.is(tok::l_brace) || (AllowSemi &&
Tok.is(tok::semi)))
431 return R != TPResult::False;
434Parser::ConditionOrInitStatement
435Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement,
436 bool CanBeForRangeDecl) {
440 if (CanBeInitStatement && Tok.is(tok::kw_using))
441 return ConditionOrInitStatement::InitStmtDecl;
443 return State.result();
446 RevertingTentativeParsingAction PA(*
this);
449 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
450 if (State.update(TryConsumeDeclarationSpecifier()))
451 return State.result();
452 assert(Tok.is(tok::l_paren) &&
"Expected '('");
456 if (State.update(TryParseDeclarator(
460 MayHaveTrailingReturnType)))
461 return State.result();
466 if (Tok.isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
468 State.markNotExpression();
469 return State.result();
473 if (State.CanBeForRangeDecl && Tok.is(tok::colon))
474 return ConditionOrInitStatement::ForRangeDecl;
478 if (State.markNotCondition())
479 return State.result();
482 if (State.markNotForRangeDecl())
483 return State.result();
487 if (Tok.is(tok::l_paren)) {
497 if (State.CanBeCondition && Tok.is(tok::r_paren))
498 return ConditionOrInitStatement::ConditionDecl;
499 else if (State.CanBeInitStatement && Tok.is(tok::semi))
500 return ConditionOrInitStatement::InitStmtDecl;
502 return ConditionOrInitStatement::Expression;
517 if (TPR != TPResult::Ambiguous)
518 return TPR != TPResult::False;
527 RevertingTentativeParsingAction PA(*
this);
528 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);
531 TryConsumeDeclarationSpecifier();
532 assert(Tok.is(tok::l_paren) &&
"Expected '('");
535 TPR = TryParseDeclarator(
true ,
false ,
537 MayHaveTrailingReturnType);
540 if (TPR == TPResult::Error)
541 TPR = TPResult::True;
543 if (TPR == TPResult::Ambiguous) {
547 Tok.is(tok::r_paren)) {
548 TPR = TPResult::True;
553 }
else if (Context ==
555 Tok.is(tok::comma)) {
556 TPR = TPResult::True;
563 (Tok.isOneOf(tok::greater, tok::comma) ||
565 (Tok.isOneOf(tok::greatergreater,
566 tok::greatergreatergreater) ||
567 (Tok.is(tok::ellipsis) &&
569 tok::greatergreatergreater,
571 TPR = TPResult::True;
575 TPR = TPResult::True;
578 TPR = TPResult::False;
581 assert(TPR == TPResult::True || TPR == TPResult::False);
582 return TPR == TPResult::True;
586Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
587 bool OuterMightBeMessageSend) {
592 if (Tok.isRegularKeywordAttribute())
606 RevertingTentativeParsingAction PA(*
this);
614 bool IsAttribute =
SkipUntil(tok::r_square);
615 IsAttribute &= Tok.is(tok::r_square);
634 RevertingTentativeParsingAction LambdaTPA(*
this);
635 LambdaIntroducer Intro;
636 LambdaIntroducerTentativeParse Tentative;
637 if (ParseLambdaIntroducer(Intro, &Tentative)) {
645 case LambdaIntroducerTentativeParse::MessageSend:
650 case LambdaIntroducerTentativeParse::Success:
651 case LambdaIntroducerTentativeParse::Incomplete:
653 if (Tok.is(tok::r_square))
657 if (OuterMightBeMessageSend)
664 case LambdaIntroducerTentativeParse::Invalid:
675 bool IsAttribute =
true;
676 while (Tok.isNot(tok::r_square)) {
677 if (Tok.is(tok::comma)) {
688 if (!TryParseCXX11AttributeIdentifier(Loc)) {
692 if (Tok.is(tok::coloncolon)) {
694 if (!TryParseCXX11AttributeIdentifier(Loc)) {
701 if (Tok.is(tok::l_paren)) {
717 if (Tok.is(tok::r_square)) {
719 IsAttribute = Tok.is(tok::r_square);
733bool Parser::TrySkipAttributes() {
734 while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
736 Tok.isRegularKeywordAttribute()) {
737 if (Tok.is(tok::l_square)) {
744 if (!
SkipUntil(tok::r_square) || Tok.isNot(tok::r_square))
749 }
else if (Tok.isRegularKeywordAttribute() &&
754 if (Tok.isNot(tok::l_paren))
765Parser::TPResult Parser::TryParsePtrOperatorSeq() {
768 return TPResult::Error;
770 if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
771 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
776 if (!TrySkipAttributes())
777 return TPResult::Error;
779 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
780 tok::kw__Nonnull, tok::kw__Nullable,
781 tok::kw__Nullable_result, tok::kw__Null_unspecified,
785 return TPResult::True;
790Parser::TPResult Parser::TryParseOperatorId() {
791 assert(Tok.is(tok::kw_operator));
795 switch (Tok.getKind()) {
796 case tok::kw_new:
case tok::kw_delete:
798 if (Tok.is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
802 return TPResult::True;
804#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
806#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
807#include "clang/Basic/OperatorKinds.def"
809 return TPResult::True;
815 return TPResult::True;
823 return TPResult::True;
833 bool FoundUDSuffix =
false;
835 FoundUDSuffix |= Tok.hasUDSuffix();
836 ConsumeStringToken();
837 }
while (isTokenStringLiteral());
839 if (!FoundUDSuffix) {
840 if (Tok.is(tok::identifier))
843 return TPResult::Error;
845 return TPResult::True;
849 bool AnyDeclSpecifiers =
false;
852 if (TPR == TPResult::Error)
854 if (TPR == TPResult::False) {
855 if (!AnyDeclSpecifiers)
856 return TPResult::Error;
859 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
860 return TPResult::Error;
861 AnyDeclSpecifiers =
true;
863 return TryParsePtrOperatorSeq();
866Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
867 bool mayHaveIdentifier,
868 bool mayHaveDirectInit,
869 bool mayHaveTrailingReturnType) {
873 if (TryParsePtrOperatorSeq() == TPResult::Error)
874 return TPResult::Error;
878 if (Tok.is(tok::ellipsis))
881 if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||
882 (Tok.is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
886 if (Tok.is(tok::annot_cxxscope)) {
888 Actions.RestoreNestedNameSpecifierAnnotation(
889 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
891 return TPResult::Error;
892 ConsumeAnnotationToken();
893 }
else if (Tok.is(tok::identifier)) {
894 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
896 if (Tok.is(tok::kw_operator)) {
897 if (TryParseOperatorId() == TPResult::Error)
898 return TPResult::Error;
901 }
else if (Tok.is(tok::l_paren)) {
904 (Tok.is(tok::r_paren) ||
906 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren)) ||
907 isDeclarationSpecifier(
911 TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
912 if (TPR != TPResult::Ambiguous)
918 if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
919 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
920 tok::kw___regcall, tok::kw___vectorcall))
921 return TPResult::True;
922 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
923 if (TPR != TPResult::Ambiguous)
925 if (Tok.isNot(tok::r_paren))
926 return TPResult::False;
929 }
else if (!mayBeAbstract) {
930 return TPResult::False;
933 if (mayHaveDirectInit)
934 return TPResult::Ambiguous;
937 TPResult TPR(TPResult::Ambiguous);
939 if (Tok.is(tok::l_paren)) {
944 if (!mayBeAbstract && !isCXXFunctionDeclarator())
950 TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);
951 }
else if (Tok.is(tok::l_square)) {
954 TPR = TryParseBracketDeclarator();
955 }
else if (Tok.is(tok::kw_requires)) {
958 TPR = TPResult::True;
963 if (TPR != TPResult::Ambiguous)
967 return TPResult::Ambiguous;
971 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);
977 TentativeParseCCC(
const Token &
Next) {
978 WantRemainingKeywords =
false;
980 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,
981 tok::identifier, tok::comma);
984 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
988 llvm::all_of(Candidate,
989 [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
995 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
996 return std::make_unique<TentativeParseCCC>(*
this);
1003 Parser::TPResult BracedCastResult,
1004 bool *InvalidAsDeclSpec) {
1005 auto IsPlaceholderSpecifier = [&](TemplateIdAnnotation *TemplateId,
1011 .
isOneOf(tok::kw_auto, tok::kw_decltype,
1021 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||
1034 switch (Tok.getKind()) {
1035 case tok::identifier: {
1040 return TPResult::Error;
1041 if (Tok.is(tok::identifier))
1042 return TPResult::False;
1044 BracedCastResult, InvalidAsDeclSpec);
1049 if (TryAltiVecVectorToken())
1050 return TPResult::True;
1055 return TPResult::True;
1060 if (
Next.is(tok::l_paren) &&
1061 Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier() &&
1062 isRevertibleTypeTrait(Tok.getIdentifierInfo())) {
1063 return TPResult::False;
1066 if (
Next.isNot(tok::coloncolon) &&
Next.isNot(tok::less)) {
1071 TentativeParseCCC CCC(
Next);
1072 switch (TryAnnotateName(&CCC)) {
1074 return TPResult::Error;
1076 return TPResult::False;
1084 return TPResult::Error;
1085 if (Tok.isNot(tok::identifier))
1091 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
1093 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1097 assert(Tok.isNot(tok::identifier) &&
1098 "TryAnnotateName succeeded without producing an annotation");
1105 return TPResult::Error;
1109 if (Tok.is(tok::identifier))
1110 return TPResult::False;
1114 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1118 case tok::kw_typename:
1122 return TPResult::Error;
1124 BracedCastResult, InvalidAsDeclSpec);
1126 case tok::kw_auto: {
1128 return TPResult::True;
1130 return TPResult::False;
1132 return TPResult::Ambiguous;
1133 return TPResult::True;
1136 case tok::coloncolon: {
1138 if (
Next.isOneOf(tok::kw_new,
1140 return TPResult::False;
1143 case tok::kw___super:
1144 case tok::kw_decltype:
1148 return TPResult::Error;
1149 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1159 case tok::kw_friend:
1160 case tok::kw_typedef:
1161 case tok::kw_constexpr:
1162 case tok::kw_consteval:
1163 case tok::kw_constinit:
1165 case tok::kw_register:
1166 case tok::kw_static:
1167 case tok::kw_extern:
1168 case tok::kw_mutable:
1169 case tok::kw___thread:
1170 case tok::kw_thread_local:
1171 case tok::kw__Thread_local:
1173 case tok::kw_inline:
1174 case tok::kw_virtual:
1175 case tok::kw_explicit:
1178 case tok::kw___module_private__:
1181 case tok::kw___unknown_anytype:
1194 case tok::kw_struct:
1196 case tok::kw___interface:
1201 case tok::kw_volatile:
1202 return TPResult::True;
1205 case tok::kw_private:
1207 return TPResult::False;
1209 case tok::kw___private:
1210 case tok::kw___local:
1211 case tok::kw___global:
1212 case tok::kw___constant:
1213 case tok::kw___generic:
1215 case tok::kw___read_only:
1216 case tok::kw___write_only:
1217 case tok::kw___read_write:
1222 case tok::kw_groupshared:
1228 case tok::kw_restrict:
1229 case tok::kw__Complex:
1230 case tok::kw___attribute:
1231 case tok::kw___auto_type:
1232 return TPResult::True;
1235 case tok::kw___declspec:
1236 case tok::kw___cdecl:
1237 case tok::kw___stdcall:
1238 case tok::kw___fastcall:
1239 case tok::kw___thiscall:
1240 case tok::kw___regcall:
1241 case tok::kw___vectorcall:
1243 case tok::kw___sptr:
1244 case tok::kw___uptr:
1245 case tok::kw___ptr64:
1246 case tok::kw___ptr32:
1247 case tok::kw___forceinline:
1248 case tok::kw___unaligned:
1249 case tok::kw__Nonnull:
1250 case tok::kw__Nullable:
1251 case tok::kw__Nullable_result:
1252 case tok::kw__Null_unspecified:
1253 case tok::kw___kindof:
1254 return TPResult::True;
1257 case tok::kw___funcref:
1258 return TPResult::True;
1261 case tok::kw___pascal:
1262 return TPResult::True;
1265 case tok::kw___vector:
1266 return TPResult::True;
1268 case tok::kw_this: {
1272 RevertingTentativeParsingAction PA(*
this);
1274 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,
1277 return TPResult::False;
1279 case tok::annot_template_id: {
1280 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1285 InvalidAsDeclSpec) {
1290 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1291 return TPResult::Ambiguous;
1294 return TPResult::Error;
1295 if (IsPlaceholderSpecifier(TemplateId, 0))
1296 return TPResult::True;
1298 return TPResult::False;
1300 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
1301 assert(Tok.is(tok::annot_typename));
1305 case tok::annot_cxxscope:
1308 return TPResult::Error;
1309 if (!Tok.is(tok::annot_typename)) {
1310 if (Tok.is(tok::annot_cxxscope) &&
1312 TemplateIdAnnotation *TemplateId =
1315 if (InvalidAsDeclSpec) {
1316 *InvalidAsDeclSpec =
NextToken().
is(tok::l_paren);
1317 return TPResult::Ambiguous;
1319 return TPResult::Error;
1321 if (IsPlaceholderSpecifier(TemplateId, 1))
1322 return TPResult::True;
1326 if (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1328 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1329 Tok.getAnnotationRange(),
1332 RevertingTentativeParsingAction PA(*
this);
1333 ConsumeAnnotationToken();
1335 bool isIdentifier = Tok.is(tok::identifier);
1336 TPResult TPR = TPResult::False;
1338 TPR = isCXXDeclarationSpecifier(
1339 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);
1342 TPR == TPResult::True || TPR == TPResult::Error)
1343 return TPResult::Error;
1345 if (InvalidAsDeclSpec) {
1348 *InvalidAsDeclSpec =
true;
1349 return TPResult::Ambiguous;
1355 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1358 (Tok.is(tok::ampamp) &&
NextToken().
is(tok::greater)))
1359 return TPResult::True;
1365 switch (TryAnnotateName(
nullptr, AllowImplicitTypename)) {
1367 return TPResult::Error;
1369 return TPResult::False;
1375 return TPResult::Error;
1379 if (Tok.isNot(tok::annot_cxxscope) && Tok.isNot(tok::identifier))
1390 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;
1396 assert(Tok.isNot(tok::annot_cxxscope) ||
1398 return isCXXDeclarationSpecifier(AllowImplicitTypename,
1399 BracedCastResult, InvalidAsDeclSpec);
1402 return TPResult::False;
1425 case tok::annot_typename:
1430 RevertingTentativeParsingAction PA(*
this);
1433 TPResult TPR = TryParseProtocolQualifiers();
1434 bool isFollowedByParen = Tok.is(tok::l_paren);
1435 bool isFollowedByBrace = Tok.is(tok::l_brace);
1437 if (TPR == TPResult::Error)
1438 return TPResult::Error;
1440 if (isFollowedByParen)
1441 return TPResult::Ambiguous;
1444 return BracedCastResult;
1446 return TPResult::True;
1452 case tok::kw_wchar_t:
1453 case tok::kw_char8_t:
1454 case tok::kw_char16_t:
1455 case tok::kw_char32_t:
1460 case tok::kw___int64:
1461 case tok::kw___int128:
1462 case tok::kw_signed:
1463 case tok::kw_unsigned:
1466 case tok::kw_double:
1467 case tok::kw___bf16:
1468 case tok::kw__Float16:
1469 case tok::kw___float128:
1470 case tok::kw___ibm128:
1472 case tok::annot_decltype:
1473 case tok::kw__Accum:
1474 case tok::kw__Fract:
1476 case tok::annot_pack_indexing_type:
1477#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1478#include "clang/Basic/OpenCLImageTypes.def"
1479#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1480#include "clang/Basic/HLSLIntangibleTypes.def"
1482 return TPResult::Ambiguous;
1491 return BracedCastResult;
1493 if (isStartOfObjCClassMessageMissingOpenBracket())
1494 return TPResult::False;
1496 return TPResult::True;
1499 case tok::kw_typeof: {
1501 return TPResult::True;
1503 RevertingTentativeParsingAction PA(*
this);
1505 TPResult TPR = TryParseTypeofSpecifier();
1506 bool isFollowedByParen = Tok.is(tok::l_paren);
1507 bool isFollowedByBrace = Tok.is(tok::l_brace);
1509 if (TPR == TPResult::Error)
1510 return TPResult::Error;
1512 if (isFollowedByParen)
1513 return TPResult::Ambiguous;
1516 return BracedCastResult;
1518 return TPResult::True;
1521#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1522#include "clang/Basic/TransformTypeTraits.def"
1523 return TPResult::True;
1526 case tok::kw__Alignas:
1527 return TPResult::True;
1529 case tok::kw__Atomic:
1530 return TPResult::True;
1532 case tok::kw__BitInt:
1533 case tok::kw__ExtInt: {
1535 return TPResult::Error;
1536 RevertingTentativeParsingAction PA(*
this);
1541 return TPResult::Error;
1543 if (Tok.is(tok::l_paren))
1544 return TPResult::Ambiguous;
1547 return BracedCastResult;
1549 return TPResult::True;
1552 return TPResult::False;
1556bool Parser::isCXXDeclarationSpecifierAType() {
1557 switch (Tok.getKind()) {
1559 case tok::annot_decltype:
1560 case tok::annot_pack_indexing_type:
1561 case tok::annot_template_id:
1562 case tok::annot_typename:
1563 case tok::kw_typeof:
1564#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
1565#include "clang/Basic/TransformTypeTraits.def"
1570 case tok::kw_struct:
1572 case tok::kw___interface:
1578 case tok::kw_wchar_t:
1579 case tok::kw_char8_t:
1580 case tok::kw_char16_t:
1581 case tok::kw_char32_t:
1585 case tok::kw__ExtInt:
1586 case tok::kw__BitInt:
1588 case tok::kw___int64:
1589 case tok::kw___int128:
1590 case tok::kw_signed:
1591 case tok::kw_unsigned:
1594 case tok::kw_double:
1595 case tok::kw___bf16:
1596 case tok::kw__Float16:
1597 case tok::kw___float128:
1598 case tok::kw___ibm128:
1600 case tok::kw___unknown_anytype:
1601 case tok::kw___auto_type:
1602 case tok::kw__Accum:
1603 case tok::kw__Fract:
1605#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1606#include "clang/Basic/OpenCLImageTypes.def"
1607#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
1608#include "clang/Basic/HLSLIntangibleTypes.def"
1614 case tok::kw__Atomic:
1623Parser::TPResult Parser::TryParseTypeofSpecifier() {
1624 assert(Tok.is(tok::kw_typeof) &&
"Expected 'typeof'!");
1627 assert(Tok.is(tok::l_paren) &&
"Expected '('");
1631 return TPResult::Error;
1633 return TPResult::Ambiguous;
1636Parser::TPResult Parser::TryParseProtocolQualifiers() {
1637 assert(Tok.is(tok::less) &&
"Expected '<' for qualifier list");
1640 if (Tok.isNot(tok::identifier))
1641 return TPResult::Error;
1644 if (Tok.is(tok::comma)) {
1649 if (Tok.is(tok::greater)) {
1651 return TPResult::Ambiguous;
1655 return TPResult::Error;
1658bool Parser::isCXXFunctionDeclarator(
1670 RevertingTentativeParsingAction PA(*
this);
1673 bool InvalidAsDeclaration =
false;
1674 TPResult TPR = TryParseParameterDeclarationClause(
1675 &InvalidAsDeclaration,
false,
1676 AllowImplicitTypename);
1677 if (TPR == TPResult::Ambiguous) {
1678 if (Tok.isNot(tok::r_paren))
1679 TPR = TPResult::False;
1682 if (
Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1683 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1684 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1685 isCXX11VirtSpecifier(
Next))
1689 TPR = TPResult::True;
1690 else if (InvalidAsDeclaration)
1692 TPR = TPResult::False;
1696 if (IsAmbiguous && TPR == TPResult::Ambiguous)
1697 *IsAmbiguous =
true;
1700 return TPR != TPResult::False;
1703Parser::TPResult Parser::TryParseParameterDeclarationClause(
1704 bool *InvalidAsDeclaration,
bool VersusTemplateArgument,
1707 if (Tok.is(tok::r_paren))
1708 return TPResult::Ambiguous;
1719 if (Tok.is(tok::ellipsis)) {
1721 if (Tok.is(tok::r_paren))
1722 return TPResult::True;
1724 return TPResult::False;
1728 if (isCXX11AttributeSpecifier(
false,
1731 return TPResult::True;
1733 ParsedAttributes attrs(AttrFactory);
1734 MaybeParseMicrosoftAttributes(attrs);
1739 TPResult TPR = isCXXDeclarationSpecifier(
1740 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);
1743 if (TPR != TPResult::Ambiguous &&
1744 !(VersusTemplateArgument && TPR == TPResult::True))
1747 bool SeenType =
false;
1748 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);
1750 SeenType |= isCXXDeclarationSpecifierAType();
1751 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1752 return TPResult::Error;
1755 if (SeenType && Tok.is(tok::identifier))
1756 return TPResult::True;
1758 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,
1759 InvalidAsDeclaration);
1760 if (TPR == TPResult::Error)
1764 if (TPR == TPResult::True && !VersusTemplateArgument)
1766 }
while (TPR != TPResult::False);
1770 TPR = TryParseDeclarator(
1774 DeclarationSpecifierIsAuto);
1775 if (TPR != TPResult::Ambiguous)
1779 if (Tok.is(tok::kw___attribute))
1780 return TPResult::True;
1791 if (VersusTemplateArgument)
1792 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;
1794 if (Tok.is(tok::equal)) {
1798 return TPResult::Error;
1801 if (Tok.is(tok::ellipsis)) {
1803 if (Tok.is(tok::r_paren))
1804 return TPResult::True;
1806 return TPResult::False;
1813 return TPResult::Ambiguous;
1817Parser::TryParseFunctionDeclarator(
bool MayHaveTrailingReturnType) {
1820 TPResult TPR = TryParseParameterDeclarationClause();
1821 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
1822 TPR = TPResult::False;
1824 if (TPR == TPResult::False || TPR == TPResult::Error)
1829 return TPResult::Error;
1832 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1837 if (Tok.isOneOf(tok::amp, tok::ampamp))
1841 if (Tok.is(tok::kw_throw)) {
1843 if (Tok.isNot(tok::l_paren))
1844 return TPResult::Error;
1849 return TPResult::Error;
1851 if (Tok.is(tok::kw_noexcept)) {
1854 if (Tok.is(tok::l_paren)) {
1858 return TPResult::Error;
1863 if (!TrySkipAttributes())
1864 return TPResult::Ambiguous;
1867 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {
1868 if (TPR == TPResult::True)
1871 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {
1872 return TPResult::False;
1875 return TPResult::True;
1878 return TPResult::Ambiguous;
1881bool Parser::NameAfterArrowIsNonType() {
1882 assert(Tok.is(tok::identifier));
1884 if (
Next.is(tok::coloncolon))
1886 IdentifierInfo *Name = Tok.getIdentifierInfo();
1887 SourceLocation NameLoc = Tok.getLocation();
1889 TentativeParseCCC CCC(
Next);
1890 Sema::NameClassification Classification =
1892 switch (Classification.
getKind()) {
1904Parser::TPResult Parser::TryParseBracketDeclarator() {
1909 if (Tok.is(tok::l_brace))
1910 return TPResult::False;
1913 return TPResult::Error;
1917 if (Tok.isNot(tok::r_square))
1918 return TPResult::False;
1921 return TPResult::Ambiguous;
1924Parser::TPResult Parser::isTemplateArgumentList(
unsigned TokensToSkip) {
1925 if (!TokensToSkip) {
1926 if (Tok.isNot(tok::less))
1927 return TPResult::False;
1929 return TPResult::True;
1932 RevertingTentativeParsingAction PA(*
this);
1934 while (TokensToSkip) {
1940 return TPResult::False;
1945 bool InvalidAsTemplateArgumentList =
false;
1947 &InvalidAsTemplateArgumentList) ==
1949 return TPResult::True;
1950 if (InvalidAsTemplateArgumentList)
1951 return TPResult::False;
1965 if (
SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},
1967 return TPResult::Ambiguous;
1968 return TPResult::False;
1971Parser::TPResult Parser::isExplicitBool() {
1972 assert(Tok.is(tok::l_paren) &&
"expected to be looking at a '(' token");
1974 RevertingTentativeParsingAction PA(*
this);
1982 while (Tok.is(tok::l_paren))
1986 return TPResult::Error;
1991 if (Tok.is(tok::annot_cxxscope)) {
1992 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1993 Tok.getAnnotationRange(),
1995 ConsumeAnnotationToken();
2000 if (Tok.is(tok::kw_operator))
2001 return TPResult::Ambiguous;
2004 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
2005 return TPResult::True;
2006 if (!Actions.isCurrentClassName(Tok.is(tok::identifier)
2007 ? *Tok.getIdentifierInfo()
2008 : *takeTemplateIdAnnotation(Tok)->Name,
2010 return TPResult::True;
2016 !isConstructorDeclarator(SS.
isEmpty(),
2018 return TPResult::True;
2021 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.
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.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
NameClassificationKind getKind() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
bool isOneOf(Ts... Ks) const
The JSON file list parser is used to communicate input to InstallAPI.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
CXX11AttributeKind
The kind of attribute specifier we have found.
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ Unresolved
The identifier can't be resolved.
@ Success
Annotation was successful.
@ Error
Annotation has failed and emitted an error.
@ TentativeDecl
The identifier is a tentatively-declared name.
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
TentativeCXXTypeIdContext
Specifies the context in which type-id/expression disambiguation will occur.
@ AsGenericSelectionArgument
@ FunctionTemplate
The name was classified as a function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ VarTemplate
The name was classified as a variable template name.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
bool markNotForRangeDecl()
ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement, bool CanBeForRangeDecl)
bool update(TPResult IsDecl)
ConditionOrInitStatement result() const
bool hasInvalidName() const
TemplateNameKind Kind
The kind of template that Template refers to.
unsigned NumArgs
NumArgs - The number of template arguments.