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(); }))
1134 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1135 bool *HasMissingTypename) {
1137 case tok::identifier: {
1140 if (TryAltiVecVectorToken())
1148 if (Next.
isNot(tok::coloncolon) && Next.
isNot(tok::less)) {
1153 switch (TryAnnotateName(
false ,
1154 llvm::make_unique<TentativeParseCCC>(Next))) {
1157 case ANK_TentativeDecl:
1159 case ANK_TemplateName:
1163 case ANK_Unresolved:
1168 assert(Tok.
isNot(tok::identifier) &&
1169 "TryAnnotateName succeeded without producing an annotation");
1180 if (Tok.
is(tok::identifier))
1185 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1188 case tok::kw_typename:
1193 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1195 case tok::coloncolon: {
1202 case tok::kw___super:
1203 case tok::kw_decltype:
1208 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1218 case tok::kw_friend:
1219 case tok::kw_typedef:
1220 case tok::kw_constexpr:
1221 case tok::kw_concept:
1223 case tok::kw_register:
1224 case tok::kw_static:
1225 case tok::kw_extern:
1226 case tok::kw_mutable:
1228 case tok::kw___thread:
1229 case tok::kw_thread_local:
1230 case tok::kw__Thread_local:
1232 case tok::kw_inline:
1233 case tok::kw_virtual:
1234 case tok::kw_explicit:
1237 case tok::kw___module_private__:
1240 case tok::kw___unknown_anytype:
1253 case tok::kw_struct:
1255 case tok::kw___interface:
1260 case tok::kw_volatile:
1263 case tok::kw_restrict:
1264 case tok::kw__Complex:
1265 case tok::kw___attribute:
1266 case tok::kw___auto_type:
1270 case tok::kw___declspec:
1271 case tok::kw___cdecl:
1272 case tok::kw___stdcall:
1273 case tok::kw___fastcall:
1274 case tok::kw___thiscall:
1275 case tok::kw___vectorcall:
1277 case tok::kw___sptr:
1278 case tok::kw___uptr:
1279 case tok::kw___ptr64:
1280 case tok::kw___ptr32:
1281 case tok::kw___forceinline:
1282 case tok::kw___unaligned:
1283 case tok::kw__Nonnull:
1284 case tok::kw__Nullable:
1285 case tok::kw__Null_unspecified:
1286 case tok::kw___kindof:
1290 case tok::kw___pascal:
1294 case tok::kw___vector:
1297 case tok::annot_template_id: {
1302 AnnotateTemplateIdTokenAsType();
1303 assert(Tok.
is(tok::annot_typename));
1307 case tok::annot_cxxscope:
1311 if (!Tok.
is(tok::annot_typename)) {
1314 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1320 TentativeParsingAction PA(*
this);
1323 bool isIdentifier = Tok.
is(tok::identifier);
1326 TPR = isCXXDeclarationSpecifier(BracedCastResult,
1327 HasMissingTypename);
1334 if (HasMissingTypename) {
1337 *HasMissingTypename =
true;
1343 switch (TryAnnotateName(
false )) {
1346 case ANK_TentativeDecl:
1348 case ANK_TemplateName:
1352 case ANK_Unresolved:
1357 assert(Tok.
isNot(tok::annot_cxxscope) ||
1359 return isCXXDeclarationSpecifier(BracedCastResult,
1360 HasMissingTypename);
1386 case tok::annot_typename:
1391 TentativeParsingAction PA(*
this);
1394 TPResult TPR = TryParseProtocolQualifiers();
1395 bool isFollowedByParen = Tok.
is(tok::l_paren);
1396 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1403 if (isFollowedByParen)
1407 return BracedCastResult;
1413 case tok::kw_wchar_t:
1414 case tok::kw_char16_t:
1415 case tok::kw_char32_t:
1420 case tok::kw___int64:
1421 case tok::kw___int128:
1422 case tok::kw_signed:
1423 case tok::kw_unsigned:
1426 case tok::kw_double:
1428 case tok::annot_decltype:
1439 return BracedCastResult;
1441 if (isStartOfObjCClassMessageMissingOpenBracket())
1447 case tok::kw_typeof: {
1451 TentativeParsingAction PA(*
this);
1453 TPResult TPR = TryParseTypeofSpecifier();
1454 bool isFollowedByParen = Tok.
is(tok::l_paren);
1455 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1462 if (isFollowedByParen)
1466 return BracedCastResult;
1472 case tok::kw___underlying_type:
1476 case tok::kw__Atomic:
1484 bool Parser::isCXXDeclarationSpecifierAType() {
1487 case tok::annot_decltype:
1488 case tok::annot_template_id:
1489 case tok::annot_typename:
1490 case tok::kw_typeof:
1491 case tok::kw___underlying_type:
1496 case tok::kw_struct:
1498 case tok::kw___interface:
1504 case tok::kw_wchar_t:
1505 case tok::kw_char16_t:
1506 case tok::kw_char32_t:
1511 case tok::kw___int64:
1512 case tok::kw___int128:
1513 case tok::kw_signed:
1514 case tok::kw_unsigned:
1517 case tok::kw_double:
1519 case tok::kw___unknown_anytype:
1520 case tok::kw___auto_type:
1526 case tok::kw__Atomic:
1539 Parser::TPResult Parser::TryParseTypeofSpecifier() {
1540 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1543 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1554 Parser::TPResult Parser::TryParseProtocolQualifiers() {
1555 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1558 if (Tok.
isNot(tok::identifier))
1562 if (Tok.
is(tok::comma)) {
1567 if (Tok.
is(tok::greater)) {
1586 bool Parser::isCXXFunctionDeclarator(
bool *IsAmbiguous) {
1597 TentativeParsingAction PA(*
this);
1600 bool InvalidAsDeclaration =
false;
1601 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
1603 if (Tok.
isNot(tok::r_paren))
1607 if (Next.
isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1608 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1609 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1610 isCXX11VirtSpecifier(Next))
1615 else if (InvalidAsDeclaration)
1624 *IsAmbiguous =
true;
1648 Parser::TryParseParameterDeclarationClause(
bool *InvalidAsDeclaration,
1649 bool VersusTemplateArgument) {
1651 if (Tok.
is(tok::r_paren))
1663 if (Tok.
is(tok::ellipsis)) {
1665 if (Tok.
is(tok::r_paren))
1672 if (isCXX11AttributeSpecifier(
false,
1677 MaybeParseMicrosoftAttributes(attrs);
1683 InvalidAsDeclaration);
1688 bool SeenType =
false;
1690 SeenType |= isCXXDeclarationSpecifierAType();
1695 if (SeenType && Tok.
is(tok::identifier))
1699 InvalidAsDeclaration);
1712 TPR = TryParseDeclarator(
true);
1717 if (Tok.
is(tok::kw___attribute))
1730 if (VersusTemplateArgument)
1734 if (Tok.
is(tok::equal)) {
1742 if (Tok.
is(tok::ellipsis)) {
1744 if (Tok.
is(tok::r_paren))
1769 Parser::TPResult Parser::TryParseFunctionDeclarator() {
1773 TPResult TPR = TryParseParameterDeclarationClause();
1785 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict))
1789 if (Tok.
isOneOf(tok::amp, tok::ampamp))
1793 if (Tok.
is(tok::kw_throw)) {
1795 if (Tok.
isNot(tok::l_paren))
1803 if (Tok.
is(tok::kw_noexcept)) {
1806 if (Tok.
is(tok::l_paren)) {
1819 Parser::TPResult Parser::TryParseBracketDeclarator() {
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.
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.
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
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.
Stop skipping at semicolon.
Encodes a location in the source.
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.
bool TryAnnotateTypeOrScopeToken(bool EnteringContext=false, bool NeedType=false)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
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