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);
82 bool Parser::isCXXSimpleDeclaration(
bool AllowForRangeDecl) {
107 bool InvalidAsDeclaration =
false;
109 &InvalidAsDeclaration);
119 if (InvalidAsDeclaration)
129 TentativeParsingAction PA(*
this);
130 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
147 Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
149 case tok::kw__Atomic:
156 case tok::kw___attribute:
157 case tok::kw___underlying_type: {
159 if (Tok.
isNot(tok::l_paren))
170 case tok::kw___interface:
182 while (Tok.
isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
184 if (Tok.
is(tok::l_square)) {
190 if (Tok.
isNot(tok::l_paren))
198 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
199 tok::annot_template_id) &&
202 if (Tok.
is(tok::annot_cxxscope))
204 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::annot_template_id))
209 case tok::annot_cxxscope:
216 return TryParseProtocolQualifiers();
231 Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
238 if (Tok.
isNot(tok::l_paren)) {
239 TPResult TPR = isCXXDeclarationSpecifier();
247 TPResult TPR = TryParseInitDeclaratorList();
251 if (Tok.
isNot(tok::semi) && (!AllowForRangeDecl || Tok.
isNot(tok::colon)))
284 Parser::TPResult Parser::TryParseInitDeclaratorList() {
287 TPResult TPR = TryParseDeclarator(
false);
292 if (Tok.
isOneOf(tok::kw_asm, tok::kw___attribute))
296 if (Tok.
is(tok::l_paren)) {
301 }
else if (Tok.
is(tok::l_brace)) {
305 }
else if (Tok.
is(tok::equal) || isTokIdentifier_in()) {
345 bool Parser::isCXXConditionDeclaration() {
346 TPResult TPR = isCXXDeclarationSpecifier();
357 TentativeParsingAction PA(*
this);
360 TryConsumeDeclarationSpecifier();
361 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
364 TPR = TryParseDeclarator(
false);
373 if (Tok.
isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute))
404 bool Parser::isCXXTypeId(TentativeCXXTypeIdContext
Context,
bool &isAmbiguous) {
415 TPResult TPR = isCXXDeclarationSpecifier();
426 TentativeParsingAction PA(*
this);
429 TryConsumeDeclarationSpecifier();
430 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
433 TPR = TryParseDeclarator(
true,
false);
442 if (Context == TypeIdInParens && Tok.
is(tok::r_paren)) {
449 }
else if (Context == TypeIdAsTemplateArgument &&
450 (Tok.
isOneOf(tok::greater, tok::comma) ||
451 (
getLangOpts().CPlusPlus11 && Tok.
is(tok::greatergreater)))) {
498 Parser::CXX11AttributeKind
499 Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
500 bool OuterMightBeMessageSend) {
501 if (Tok.
is(tok::kw_alignas))
502 return CAK_AttributeSpecifier;
505 return CAK_NotAttributeSpecifier;
509 return CAK_AttributeSpecifier;
511 TentativeParsingAction PA(*
this);
520 bool IsAttribute =
SkipUntil(tok::r_square);
521 IsAttribute &= Tok.
is(tok::r_square);
525 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
541 if (!TryParseLambdaIntroducer(Intro)) {
543 bool IsAttribute = Tok.
is(tok::r_square);
549 return CAK_AttributeSpecifier;
551 if (OuterMightBeMessageSend)
553 return CAK_NotAttributeSpecifier;
556 return CAK_InvalidAttributeSpecifier;
563 bool IsAttribute =
true;
564 while (Tok.
isNot(tok::r_square)) {
565 if (Tok.
is(tok::comma)) {
568 return CAK_AttributeSpecifier;
577 if (!TryParseCXX11AttributeIdentifier(Loc)) {
581 if (Tok.
is(tok::coloncolon)) {
583 if (!TryParseCXX11AttributeIdentifier(Loc)) {
590 if (Tok.
is(tok::l_paren)) {
606 if (Tok.
is(tok::r_square)) {
608 IsAttribute = Tok.
is(tok::r_square);
618 return CAK_AttributeSpecifier;
621 return CAK_NotAttributeSpecifier;
624 Parser::TPResult Parser::TryParsePtrOperatorSeq() {
626 if (Tok.
isOneOf(tok::coloncolon, tok::identifier))
630 if (Tok.
isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
631 (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
634 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
635 tok::kw__Nonnull, tok::kw__Nullable,
636 tok::kw__Null_unspecified))
662 Parser::TPResult Parser::TryParseOperatorId() {
663 assert(Tok.
is(tok::kw_operator));
668 case tok::kw_new:
case tok::kw_delete:
670 if (Tok.
is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
676 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
678 #define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
679 #include "clang/Basic/OperatorKinds.def"
705 bool FoundUDSuffix =
false;
708 ConsumeStringToken();
709 }
while (isTokenStringLiteral());
711 if (!FoundUDSuffix) {
712 if (Tok.
is(tok::identifier))
721 bool AnyDeclSpecifiers =
false;
723 TPResult TPR = isCXXDeclarationSpecifier();
727 if (!AnyDeclSpecifiers)
733 AnyDeclSpecifiers =
true;
735 return TryParsePtrOperatorSeq();
791 Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
792 bool mayHaveIdentifier) {
801 if (Tok.
is(tok::ellipsis))
804 if ((Tok.
isOneOf(tok::identifier, tok::kw_operator) ||
805 (Tok.
is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
809 if (Tok.
is(tok::annot_cxxscope))
811 else if (Tok.
is(tok::identifier))
813 if (Tok.
is(tok::kw_operator)) {
818 }
else if (Tok.
is(tok::l_paren)) {
821 (Tok.
is(tok::r_paren) ||
824 isDeclarationSpecifier())) {
827 TPResult TPR = TryParseFunctionDeclarator();
834 if (Tok.
isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
835 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
836 tok::kw___vectorcall, tok::kw___unaligned))
838 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
841 if (Tok.
isNot(tok::r_paren))
845 }
else if (!mayBeAbstract) {
853 if (Tok.
is(tok::ellipsis))
856 if (Tok.
is(tok::l_paren)) {
861 if (!mayBeAbstract && !isCXXFunctionDeclarator())
867 TPR = TryParseFunctionDeclarator();
868 }
else if (Tok.
is(tok::l_square)) {
871 TPR = TryParseBracketDeclarator();
887 case tok::numeric_constant:
888 case tok::char_constant:
889 case tok::wide_char_constant:
890 case tok::utf8_char_constant:
891 case tok::utf16_char_constant:
892 case tok::utf32_char_constant:
893 case tok::string_literal:
894 case tok::wide_string_literal:
895 case tok::utf8_string_literal:
896 case tok::utf16_string_literal:
897 case tok::utf32_string_literal:
906 case tok::minusminus:
910 case tok::kw___func__:
911 case tok::kw_const_cast:
913 case tok::kw_dynamic_cast:
916 case tok::kw_operator:
917 case tok::kw_reinterpret_cast:
918 case tok::kw_static_cast:
923 case tok::kw_alignof:
924 case tok::kw_noexcept:
925 case tok::kw_nullptr:
926 case tok::kw__Alignof:
928 case tok::kw___alignof:
929 case tok::kw___builtin_choose_expr:
930 case tok::kw___builtin_offsetof:
931 case tok::kw___builtin_va_arg:
934 case tok::kw___FUNCTION__:
935 case tok::kw___FUNCDNAME__:
936 case tok::kw___FUNCSIG__:
937 case tok::kw_L__FUNCTION__:
938 case tok::kw___PRETTY_FUNCTION__:
939 case tok::kw___uuidof:
940 #define TYPE_TRAIT(N,Spelling,K) \
941 case tok::kw_##Spelling:
942 #include "clang/Basic/TokenKinds.def"
954 case tok::kw___int64:
955 case tok::kw___int128:
956 case tok::kw_restrict:
961 case tok::kw_unsigned:
963 case tok::kw_volatile:
965 case tok::kw__Complex:
967 case tok::kw_typename:
968 case tok::kw_wchar_t:
969 case tok::kw_char16_t:
970 case tok::kw_char32_t:
971 case tok::kw__Decimal32:
972 case tok::kw__Decimal64:
973 case tok::kw__Decimal128:
974 case tok::kw___interface:
975 case tok::kw___thread:
976 case tok::kw_thread_local:
977 case tok::kw__Thread_local:
979 case tok::kw___underlying_type:
980 case tok::kw___cdecl:
981 case tok::kw___stdcall:
982 case tok::kw___fastcall:
983 case tok::kw___thiscall:
984 case tok::kw___vectorcall:
985 case tok::kw___unaligned:
986 case tok::kw___vector:
987 case tok::kw___pixel:
989 case tok::kw__Atomic:
990 case tok::kw___unknown_anytype:
1001 return std::find(TentativelyDeclaredIdentifiers.begin(),
1002 TentativelyDeclaredIdentifiers.end(), II)
1003 != TentativelyDeclaredIdentifiers.end();
1010 WantRemainingKeywords =
false;
1011 WantTypeSpecifiers = Next.
isOneOf(tok::l_paren, tok::r_paren, tok::greater,
1012 tok::l_brace, tok::identifier);
1015 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1019 std::all_of(Candidate.
begin(), Candidate.
end(),
1020 [](
NamedDecl *ND) {
return ND->isCXXInstanceMember(); }))
1133 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1134 bool *HasMissingTypename) {
1136 case tok::identifier: {
1139 if (TryAltiVecVectorToken())
1147 if (Next.
isNot(tok::coloncolon) && Next.
isNot(tok::less)) {
1152 switch (TryAnnotateName(
false ,
1153 llvm::make_unique<TentativeParseCCC>(Next))) {
1156 case ANK_TentativeDecl:
1158 case ANK_TemplateName:
1162 case ANK_Unresolved:
1167 assert(Tok.
isNot(tok::identifier) &&
1168 "TryAnnotateName succeeded without producing an annotation");
1179 if (Tok.
is(tok::identifier))
1184 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1187 case tok::kw_typename:
1192 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1194 case tok::coloncolon: {
1201 case tok::kw___super:
1202 case tok::kw_decltype:
1207 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1217 case tok::kw_friend:
1218 case tok::kw_typedef:
1219 case tok::kw_constexpr:
1220 case tok::kw_concept:
1222 case tok::kw_register:
1223 case tok::kw_static:
1224 case tok::kw_extern:
1225 case tok::kw_mutable:
1227 case tok::kw___thread:
1228 case tok::kw_thread_local:
1229 case tok::kw__Thread_local:
1231 case tok::kw_inline:
1232 case tok::kw_virtual:
1233 case tok::kw_explicit:
1236 case tok::kw___module_private__:
1239 case tok::kw___unknown_anytype:
1252 case tok::kw_struct:
1254 case tok::kw___interface:
1259 case tok::kw_volatile:
1262 case tok::kw_restrict:
1263 case tok::kw__Complex:
1264 case tok::kw___attribute:
1268 case tok::kw___declspec:
1269 case tok::kw___cdecl:
1270 case tok::kw___stdcall:
1271 case tok::kw___fastcall:
1272 case tok::kw___thiscall:
1273 case tok::kw___vectorcall:
1275 case tok::kw___sptr:
1276 case tok::kw___uptr:
1277 case tok::kw___ptr64:
1278 case tok::kw___ptr32:
1279 case tok::kw___forceinline:
1280 case tok::kw___unaligned:
1281 case tok::kw__Nonnull:
1282 case tok::kw__Nullable:
1283 case tok::kw__Null_unspecified:
1284 case tok::kw___kindof:
1288 case tok::kw___pascal:
1292 case tok::kw___vector:
1295 case tok::annot_template_id: {
1300 AnnotateTemplateIdTokenAsType();
1301 assert(Tok.
is(tok::annot_typename));
1305 case tok::annot_cxxscope:
1309 if (!Tok.
is(tok::annot_typename)) {
1312 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1318 TentativeParsingAction PA(*
this);
1321 bool isIdentifier = Tok.
is(tok::identifier);
1324 TPR = isCXXDeclarationSpecifier(BracedCastResult,
1325 HasMissingTypename);
1332 if (HasMissingTypename) {
1335 *HasMissingTypename =
true;
1341 switch (TryAnnotateName(
false )) {
1344 case ANK_TentativeDecl:
1346 case ANK_TemplateName:
1350 case ANK_Unresolved:
1355 assert(Tok.
isNot(tok::annot_cxxscope) ||
1357 return isCXXDeclarationSpecifier(BracedCastResult,
1358 HasMissingTypename);
1384 case tok::annot_typename:
1389 TentativeParsingAction PA(*
this);
1392 TPResult TPR = TryParseProtocolQualifiers();
1393 bool isFollowedByParen = Tok.
is(tok::l_paren);
1394 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1401 if (isFollowedByParen)
1405 return BracedCastResult;
1411 case tok::kw_wchar_t:
1412 case tok::kw_char16_t:
1413 case tok::kw_char32_t:
1418 case tok::kw___int64:
1419 case tok::kw___int128:
1420 case tok::kw_signed:
1421 case tok::kw_unsigned:
1424 case tok::kw_double:
1426 case tok::annot_decltype:
1437 return BracedCastResult;
1439 if (isStartOfObjCClassMessageMissingOpenBracket())
1445 case tok::kw_typeof: {
1449 TentativeParsingAction PA(*
this);
1451 TPResult TPR = TryParseTypeofSpecifier();
1452 bool isFollowedByParen = Tok.
is(tok::l_paren);
1453 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1460 if (isFollowedByParen)
1464 return BracedCastResult;
1470 case tok::kw___underlying_type:
1474 case tok::kw__Atomic:
1482 bool Parser::isCXXDeclarationSpecifierAType() {
1485 case tok::annot_decltype:
1486 case tok::annot_template_id:
1487 case tok::annot_typename:
1488 case tok::kw_typeof:
1489 case tok::kw___underlying_type:
1494 case tok::kw_struct:
1496 case tok::kw___interface:
1502 case tok::kw_wchar_t:
1503 case tok::kw_char16_t:
1504 case tok::kw_char32_t:
1509 case tok::kw___int64:
1510 case tok::kw___int128:
1511 case tok::kw_signed:
1512 case tok::kw_unsigned:
1515 case tok::kw_double:
1517 case tok::kw___unknown_anytype:
1523 case tok::kw__Atomic:
1536 Parser::TPResult Parser::TryParseTypeofSpecifier() {
1537 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1540 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1551 Parser::TPResult Parser::TryParseProtocolQualifiers() {
1552 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1555 if (Tok.
isNot(tok::identifier))
1559 if (Tok.
is(tok::comma)) {
1564 if (Tok.
is(tok::greater)) {
1583 bool Parser::isCXXFunctionDeclarator(
bool *IsAmbiguous) {
1594 TentativeParsingAction PA(*
this);
1597 bool InvalidAsDeclaration =
false;
1598 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
1600 if (Tok.
isNot(tok::r_paren))
1604 if (Next.
isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1605 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1606 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1607 isCXX11VirtSpecifier(Next))
1612 else if (InvalidAsDeclaration)
1621 *IsAmbiguous =
true;
1645 Parser::TryParseParameterDeclarationClause(
bool *InvalidAsDeclaration,
1646 bool VersusTemplateArgument) {
1648 if (Tok.
is(tok::r_paren))
1660 if (Tok.
is(tok::ellipsis)) {
1662 if (Tok.
is(tok::r_paren))
1669 if (isCXX11AttributeSpecifier(
false,
1674 MaybeParseMicrosoftAttributes(attrs);
1680 InvalidAsDeclaration);
1685 bool SeenType =
false;
1687 SeenType |= isCXXDeclarationSpecifierAType();
1692 if (SeenType && Tok.
is(tok::identifier))
1696 InvalidAsDeclaration);
1709 TPR = TryParseDeclarator(
true);
1714 if (Tok.
is(tok::kw___attribute))
1727 if (VersusTemplateArgument)
1731 if (Tok.
is(tok::equal)) {
1739 if (Tok.
is(tok::ellipsis)) {
1741 if (Tok.
is(tok::r_paren))
1766 Parser::TPResult Parser::TryParseFunctionDeclarator() {
1770 TPResult TPR = TryParseParameterDeclarationClause();
1782 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict))
1786 if (Tok.
isOneOf(tok::amp, tok::ampamp))
1790 if (Tok.
is(tok::kw_throw)) {
1792 if (Tok.
isNot(tok::l_paren))
1800 if (Tok.
is(tok::kw_noexcept)) {
1803 if (Tok.
is(tok::l_paren)) {
1816 Parser::TPResult Parser::TryParseBracketDeclarator() {
Simple class containing the result of Sema::CorrectTypo.
const LangOptions & getLangOpts() const
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TemplateNameKind Kind
The kind of template that Template refers to.
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
Information about a template-id annotation token.
const Token & NextToken()
bool TryConsumeToken(tok::TokenKind Expected)
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
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
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
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool is(tok::TokenKind K) const
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()
bool TryAnnotateTypeOrScopeToken(bool EnteringContext=false, bool NeedType=false)
Represents a complete lambda introducer.
Stop skipping at specified token, but don't skip the token itself.
IdentifierInfo * getIdentifierInfo() const