18 using namespace clang;
50 bool Parser::isCXXDeclarationStatement() {
55 case tok::kw_namespace:
60 case tok::kw_static_assert:
61 case tok::kw__Static_assert:
65 return isCXXSimpleDeclaration(
false);
89 bool Parser::isCXXSimpleDeclaration(
bool AllowForRangeDecl) {
114 bool InvalidAsDeclaration =
false;
116 &InvalidAsDeclaration);
126 if (InvalidAsDeclaration)
137 RevertingTentativeParsingAction PA(*
this);
138 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
155 Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
157 case tok::kw__Atomic:
164 case tok::kw___attribute:
165 case tok::kw___underlying_type: {
167 if (Tok.
isNot(tok::l_paren))
178 case tok::kw___interface:
190 while (Tok.
isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
192 if (Tok.
is(tok::l_square)) {
198 if (Tok.
isNot(tok::l_paren))
206 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
207 tok::annot_template_id) &&
210 if (Tok.
is(tok::annot_cxxscope))
211 ConsumeAnnotationToken();
212 if (Tok.
is(tok::identifier))
214 else if (Tok.
is(tok::annot_template_id))
215 ConsumeAnnotationToken();
220 case tok::annot_cxxscope:
221 ConsumeAnnotationToken();
227 return TryParseProtocolQualifiers();
242 Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
249 if (Tok.
isNot(tok::l_paren)) {
250 TPResult TPR = isCXXDeclarationSpecifier();
258 TPResult TPR = TryParseInitDeclaratorList();
262 if (Tok.
isNot(tok::semi) && (!AllowForRangeDecl || Tok.
isNot(tok::colon)))
295 Parser::TPResult Parser::TryParseInitDeclaratorList() {
298 TPResult TPR = TryParseDeclarator(
false);
303 if (Tok.
isOneOf(tok::kw_asm, tok::kw___attribute))
307 if (Tok.
is(tok::l_paren)) {
312 }
else if (Tok.
is(tok::l_brace)) {
316 }
else if (Tok.
is(tok::equal) || isTokIdentifier_in()) {
350 : P(P), CanBeInitStatement(CanBeInitStatement) {}
360 RevertingTentativeParsingAction PA(
P);
362 if (
P.Tok.
isNot(tok::r_paren))
364 if (
P.Tok.
isNot(tok::semi))
388 llvm_unreachable(
"unknown tentative parse result");
391 ConditionOrInitStatement
result()
const {
393 "result called but not yet resolved");
421 Parser::ConditionOrInitStatement
422 Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement) {
423 ConditionDeclarationOrInitStatementState
State(*
this, CanBeInitStatement);
425 if (
State.update(isCXXDeclarationSpecifier()))
426 return State.result();
429 RevertingTentativeParsingAction PA(*
this);
432 if (
State.update(TryConsumeDeclarationSpecifier()))
433 return State.result();
434 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
438 if (
State.update(TryParseDeclarator(
false)))
439 return State.result();
444 if (Tok.
isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
446 State.markNotExpression();
447 return State.result();
452 if (
State.markNotCondition())
453 return State.result();
457 if (Tok.
is(tok::l_paren)) {
467 if (
State.CanBeCondition && Tok.
is(tok::r_paren))
469 else if (
State.CanBeInitStatement && Tok.
is(tok::semi))
492 bool Parser::isCXXTypeId(TentativeCXXTypeIdContext
Context,
bool &isAmbiguous) {
503 TPResult TPR = isCXXDeclarationSpecifier();
514 RevertingTentativeParsingAction PA(*
this);
517 TryConsumeDeclarationSpecifier();
518 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
521 TPR = TryParseDeclarator(
true,
false);
530 if (Context == TypeIdInParens && Tok.
is(tok::r_paren)) {
538 }
else if (Context == TypeIdAsTemplateArgument &&
539 (Tok.
isOneOf(tok::greater, tok::comma) ||
541 (Tok.
is(tok::greatergreater) ||
542 (Tok.
is(tok::ellipsis) &&
589 Parser::CXX11AttributeKind
590 Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
591 bool OuterMightBeMessageSend) {
592 if (Tok.
is(tok::kw_alignas))
593 return CAK_AttributeSpecifier;
596 return CAK_NotAttributeSpecifier;
600 return CAK_AttributeSpecifier;
602 RevertingTentativeParsingAction PA(*
this);
611 bool IsAttribute =
SkipUntil(tok::r_square);
612 IsAttribute &= Tok.
is(tok::r_square);
614 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
630 if (!TryParseLambdaIntroducer(Intro)) {
632 bool IsAttribute = Tok.
is(tok::r_square);
636 return CAK_AttributeSpecifier;
638 if (OuterMightBeMessageSend)
640 return CAK_NotAttributeSpecifier;
643 return CAK_InvalidAttributeSpecifier;
650 bool IsAttribute =
true;
651 while (Tok.
isNot(tok::r_square)) {
652 if (Tok.
is(tok::comma)) {
654 return CAK_AttributeSpecifier;
663 if (!TryParseCXX11AttributeIdentifier(Loc)) {
667 if (Tok.
is(tok::coloncolon)) {
669 if (!TryParseCXX11AttributeIdentifier(Loc)) {
676 if (Tok.
is(tok::l_paren)) {
692 if (Tok.
is(tok::r_square)) {
694 IsAttribute = Tok.
is(tok::r_square);
702 return CAK_AttributeSpecifier;
705 return CAK_NotAttributeSpecifier;
708 Parser::TPResult Parser::TryParsePtrOperatorSeq() {
710 if (Tok.
isOneOf(tok::coloncolon, tok::identifier))
714 if (Tok.
isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
715 (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
718 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
719 tok::kw__Nonnull, tok::kw__Nullable,
720 tok::kw__Null_unspecified))
746 Parser::TPResult Parser::TryParseOperatorId() {
747 assert(Tok.
is(tok::kw_operator));
752 case tok::kw_new:
case tok::kw_delete:
754 if (Tok.
is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
760 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
762 #define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
763 #include "clang/Basic/OperatorKinds.def"
789 bool FoundUDSuffix =
false;
792 ConsumeStringToken();
793 }
while (isTokenStringLiteral());
795 if (!FoundUDSuffix) {
796 if (Tok.
is(tok::identifier))
805 bool AnyDeclSpecifiers =
false;
807 TPResult TPR = isCXXDeclarationSpecifier();
811 if (!AnyDeclSpecifiers)
817 AnyDeclSpecifiers =
true;
819 return TryParsePtrOperatorSeq();
875 Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
876 bool mayHaveIdentifier) {
885 if (Tok.
is(tok::ellipsis))
888 if ((Tok.
isOneOf(tok::identifier, tok::kw_operator) ||
889 (Tok.
is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
893 if (Tok.
is(tok::annot_cxxscope))
894 ConsumeAnnotationToken();
895 else if (Tok.
is(tok::identifier))
897 if (Tok.
is(tok::kw_operator)) {
902 }
else if (Tok.
is(tok::l_paren)) {
905 (Tok.
is(tok::r_paren) ||
908 isDeclarationSpecifier())) {
911 TPResult TPR = TryParseFunctionDeclarator();
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))
922 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
925 if (Tok.
isNot(tok::r_paren))
929 }
else if (!mayBeAbstract) {
936 if (Tok.
is(tok::l_paren)) {
941 if (!mayBeAbstract && !isCXXFunctionDeclarator())
947 TPR = TryParseFunctionDeclarator();
948 }
else if (Tok.
is(tok::l_square)) {
951 TPR = TryParseBracketDeclarator();
967 case tok::numeric_constant:
968 case tok::char_constant:
969 case tok::wide_char_constant:
970 case tok::utf8_char_constant:
971 case tok::utf16_char_constant:
972 case tok::utf32_char_constant:
973 case tok::string_literal:
974 case tok::wide_string_literal:
975 case tok::utf8_string_literal:
976 case tok::utf16_string_literal:
977 case tok::utf32_string_literal:
986 case tok::minusminus:
990 case tok::kw___func__:
991 case tok::kw_const_cast:
993 case tok::kw_dynamic_cast:
996 case tok::kw_operator:
997 case tok::kw_reinterpret_cast:
998 case tok::kw_static_cast:
1002 case tok::kw_typeid:
1003 case tok::kw_alignof:
1004 case tok::kw_noexcept:
1005 case tok::kw_nullptr:
1006 case tok::kw__Alignof:
1007 case tok::kw___null:
1008 case tok::kw___alignof:
1009 case tok::kw___builtin_choose_expr:
1010 case tok::kw___builtin_offsetof:
1011 case tok::kw___builtin_va_arg:
1012 case tok::kw___imag:
1013 case tok::kw___real:
1014 case tok::kw___FUNCTION__:
1015 case tok::kw___FUNCDNAME__:
1016 case tok::kw___FUNCSIG__:
1017 case tok::kw_L__FUNCTION__:
1018 case tok::kw___PRETTY_FUNCTION__:
1019 case tok::kw___uuidof:
1020 #define TYPE_TRAIT(N,Spelling,K) \
1021 case tok::kw_##Spelling:
1022 #include "clang/Basic/TokenKinds.def"
1028 case tok::kw_double:
1029 case tok::kw___float128:
1035 case tok::kw___int64:
1036 case tok::kw___int128:
1037 case tok::kw_restrict:
1039 case tok::kw_signed:
1040 case tok::kw_struct:
1042 case tok::kw_unsigned:
1044 case tok::kw_volatile:
1046 case tok::kw__Complex:
1048 case tok::kw_typename:
1049 case tok::kw_wchar_t:
1050 case tok::kw_char16_t:
1051 case tok::kw_char32_t:
1052 case tok::kw__Decimal32:
1053 case tok::kw__Decimal64:
1054 case tok::kw__Decimal128:
1055 case tok::kw___interface:
1056 case tok::kw___thread:
1057 case tok::kw_thread_local:
1058 case tok::kw__Thread_local:
1059 case tok::kw_typeof:
1060 case tok::kw___underlying_type:
1061 case tok::kw___cdecl:
1062 case tok::kw___stdcall:
1063 case tok::kw___fastcall:
1064 case tok::kw___thiscall:
1065 case tok::kw___regcall:
1066 case tok::kw___vectorcall:
1067 case tok::kw___unaligned:
1068 case tok::kw___vector:
1069 case tok::kw___pixel:
1070 case tok::kw___bool:
1071 case tok::kw__Atomic:
1072 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1073 #include "clang/Basic/OpenCLImageTypes.def"
1074 case tok::kw___unknown_anytype:
1085 return std::find(TentativelyDeclaredIdentifiers.begin(),
1086 TentativelyDeclaredIdentifiers.end(), II)
1087 != TentativelyDeclaredIdentifiers.end();
1094 WantRemainingKeywords =
false;
1095 WantTypeSpecifiers = Next.
isOneOf(tok::l_paren, tok::r_paren, tok::greater,
1096 tok::l_brace, tok::identifier);
1099 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1103 std::all_of(Candidate.
begin(), Candidate.
end(),
1104 [](
NamedDecl *ND) {
return ND->isCXXInstanceMember(); }))
1218 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1219 bool *HasMissingTypename) {
1221 case tok::identifier: {
1224 if (TryAltiVecVectorToken())
1232 if (Next.
isNot(tok::coloncolon) && Next.
isNot(tok::less)) {
1237 switch (TryAnnotateName(
false ,
1238 llvm::make_unique<TentativeParseCCC>(Next))) {
1241 case ANK_TentativeDecl:
1243 case ANK_TemplateName:
1247 case ANK_Unresolved:
1252 assert(Tok.
isNot(tok::identifier) &&
1253 "TryAnnotateName succeeded without producing an annotation");
1264 if (Tok.
is(tok::identifier))
1269 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1272 case tok::kw_typename:
1277 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1279 case tok::coloncolon: {
1286 case tok::kw___super:
1287 case tok::kw_decltype:
1292 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1302 case tok::kw_friend:
1303 case tok::kw_typedef:
1304 case tok::kw_constexpr:
1305 case tok::kw_concept:
1307 case tok::kw_register:
1308 case tok::kw_static:
1309 case tok::kw_extern:
1310 case tok::kw_mutable:
1312 case tok::kw___thread:
1313 case tok::kw_thread_local:
1314 case tok::kw__Thread_local:
1316 case tok::kw_inline:
1317 case tok::kw_virtual:
1318 case tok::kw_explicit:
1321 case tok::kw___module_private__:
1324 case tok::kw___unknown_anytype:
1337 case tok::kw_struct:
1339 case tok::kw___interface:
1344 case tok::kw_volatile:
1347 case tok::kw_restrict:
1348 case tok::kw__Complex:
1349 case tok::kw___attribute:
1350 case tok::kw___auto_type:
1354 case tok::kw___declspec:
1355 case tok::kw___cdecl:
1356 case tok::kw___stdcall:
1357 case tok::kw___fastcall:
1358 case tok::kw___thiscall:
1359 case tok::kw___regcall:
1360 case tok::kw___vectorcall:
1362 case tok::kw___sptr:
1363 case tok::kw___uptr:
1364 case tok::kw___ptr64:
1365 case tok::kw___ptr32:
1366 case tok::kw___forceinline:
1367 case tok::kw___unaligned:
1368 case tok::kw__Nonnull:
1369 case tok::kw__Nullable:
1370 case tok::kw__Null_unspecified:
1371 case tok::kw___kindof:
1375 case tok::kw___pascal:
1379 case tok::kw___vector:
1382 case tok::annot_template_id: {
1387 AnnotateTemplateIdTokenAsType();
1388 assert(Tok.
is(tok::annot_typename));
1392 case tok::annot_cxxscope:
1396 if (!Tok.
is(tok::annot_typename)) {
1399 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1405 RevertingTentativeParsingAction PA(*
this);
1406 ConsumeAnnotationToken();
1408 bool isIdentifier = Tok.
is(tok::identifier);
1411 TPR = isCXXDeclarationSpecifier(BracedCastResult,
1412 HasMissingTypename);
1418 if (HasMissingTypename) {
1421 *HasMissingTypename =
true;
1429 switch (TryAnnotateName(
false )) {
1432 case ANK_TentativeDecl:
1434 case ANK_TemplateName:
1438 case ANK_Unresolved:
1443 assert(Tok.
isNot(tok::annot_cxxscope) ||
1445 return isCXXDeclarationSpecifier(BracedCastResult,
1446 HasMissingTypename);
1473 case tok::annot_typename:
1478 RevertingTentativeParsingAction PA(*
this);
1481 TPResult TPR = TryParseProtocolQualifiers();
1482 bool isFollowedByParen = Tok.
is(tok::l_paren);
1483 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1488 if (isFollowedByParen)
1492 return BracedCastResult;
1499 case tok::kw_wchar_t:
1500 case tok::kw_char16_t:
1501 case tok::kw_char32_t:
1506 case tok::kw___int64:
1507 case tok::kw___int128:
1508 case tok::kw_signed:
1509 case tok::kw_unsigned:
1512 case tok::kw_double:
1513 case tok::kw___float128:
1515 case tok::annot_decltype:
1526 return BracedCastResult;
1528 if (isStartOfObjCClassMessageMissingOpenBracket())
1534 case tok::kw_typeof: {
1538 RevertingTentativeParsingAction PA(*
this);
1540 TPResult TPR = TryParseTypeofSpecifier();
1541 bool isFollowedByParen = Tok.
is(tok::l_paren);
1542 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1547 if (isFollowedByParen)
1551 return BracedCastResult;
1557 case tok::kw___underlying_type:
1561 case tok::kw__Atomic:
1569 bool Parser::isCXXDeclarationSpecifierAType() {
1572 case tok::annot_decltype:
1573 case tok::annot_template_id:
1574 case tok::annot_typename:
1575 case tok::kw_typeof:
1576 case tok::kw___underlying_type:
1581 case tok::kw_struct:
1583 case tok::kw___interface:
1589 case tok::kw_wchar_t:
1590 case tok::kw_char16_t:
1591 case tok::kw_char32_t:
1596 case tok::kw___int64:
1597 case tok::kw___int128:
1598 case tok::kw_signed:
1599 case tok::kw_unsigned:
1602 case tok::kw_double:
1603 case tok::kw___float128:
1605 case tok::kw___unknown_anytype:
1606 case tok::kw___auto_type:
1612 case tok::kw__Atomic:
1625 Parser::TPResult Parser::TryParseTypeofSpecifier() {
1626 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1629 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1640 Parser::TPResult Parser::TryParseProtocolQualifiers() {
1641 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1644 if (Tok.
isNot(tok::identifier))
1648 if (Tok.
is(tok::comma)) {
1653 if (Tok.
is(tok::greater)) {
1672 bool Parser::isCXXFunctionDeclarator(
bool *IsAmbiguous) {
1683 RevertingTentativeParsingAction PA(*
this);
1686 bool InvalidAsDeclaration =
false;
1687 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
1689 if (Tok.
isNot(tok::r_paren))
1693 if (Next.
isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1694 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1695 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1696 isCXX11VirtSpecifier(Next))
1701 else if (InvalidAsDeclaration)
1708 *IsAmbiguous =
true;
1732 Parser::TryParseParameterDeclarationClause(
bool *InvalidAsDeclaration,
1733 bool VersusTemplateArgument) {
1735 if (Tok.
is(tok::r_paren))
1747 if (Tok.
is(tok::ellipsis)) {
1749 if (Tok.
is(tok::r_paren))
1756 if (isCXX11AttributeSpecifier(
false,
1761 MaybeParseMicrosoftAttributes(attrs);
1767 InvalidAsDeclaration);
1772 bool SeenType =
false;
1774 SeenType |= isCXXDeclarationSpecifierAType();
1779 if (SeenType && Tok.
is(tok::identifier))
1783 InvalidAsDeclaration);
1796 TPR = TryParseDeclarator(
true);
1801 if (Tok.
is(tok::kw___attribute))
1814 if (VersusTemplateArgument)
1818 if (Tok.
is(tok::equal)) {
1826 if (Tok.
is(tok::ellipsis)) {
1828 if (Tok.
is(tok::r_paren))
1853 Parser::TPResult Parser::TryParseFunctionDeclarator() {
1857 TPResult TPR = TryParseParameterDeclarationClause();
1869 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict))
1873 if (Tok.
isOneOf(tok::amp, tok::ampamp))
1877 if (Tok.
is(tok::kw_throw)) {
1879 if (Tok.
isNot(tok::l_paren))
1887 if (Tok.
is(tok::kw_noexcept)) {
1890 if (Tok.
is(tok::l_paren)) {
1903 Parser::TPResult Parser::TryParseBracketDeclarator() {
Disambiguated as an expression (either kind).
Simple class containing the result of Sema::CorrectTypo.
const LangOptions & getLangOpts() const
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
TemplateNameKind Kind
The kind of template that Template refers to.
Parser - This implements a parser for the C family of languages.
ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement)
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 ...
Information about a template-id annotation token.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
Disambiguated as a simple-declaration init-statement.
bool TryConsumeToken(tok::TokenKind Expected)
One of these records is kept for each identifier that is lexed.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
Token - This structure provides full information about a lexed token.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
Represents a C++ nested-name-specifier or a global scope specifier.
tok::TokenKind getKind() const
void * getAnnotationValue() const
Disambiguated as the declaration form of condition.
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
SourceRange getAnnotationRange() const
SourceRange of the group of tokens that this annotation token represents.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix. ...
bool isNot(tok::TokenKind K) const
Can't be any of the above!
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
Stop skipping at semicolon.
Encodes a location in the source.
bool TryAnnotateTypeOrScopeToken()
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
bool update(TPResult IsDecl)
ConditionOrInitStatement result() const
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
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)) {...
The name refers to a template whose specialization produces a type.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)
Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure...
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Represents a complete lambda introducer.
NamedDecl - This represents a decl with a name.
ParsedAttributes - A collection of parsed attributes.
Stop skipping at specified token, but don't skip the token itself.
IdentifierInfo * getIdentifierInfo() const