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)
130 RevertingTentativeParsingAction PA(*
this);
131 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
148 Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
150 case tok::kw__Atomic:
157 case tok::kw___attribute:
158 case tok::kw___underlying_type: {
160 if (Tok.
isNot(tok::l_paren))
171 case tok::kw___interface:
183 while (Tok.
isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
185 if (Tok.
is(tok::l_square)) {
191 if (Tok.
isNot(tok::l_paren))
199 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
200 tok::annot_template_id) &&
203 if (Tok.
is(tok::annot_cxxscope))
205 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::annot_template_id))
210 case tok::annot_cxxscope:
217 return TryParseProtocolQualifiers();
232 Parser::TPResult Parser::TryParseSimpleDeclaration(
bool AllowForRangeDecl) {
239 if (Tok.
isNot(tok::l_paren)) {
240 TPResult TPR = isCXXDeclarationSpecifier();
248 TPResult TPR = TryParseInitDeclaratorList();
252 if (Tok.
isNot(tok::semi) && (!AllowForRangeDecl || Tok.
isNot(tok::colon)))
285 Parser::TPResult Parser::TryParseInitDeclaratorList() {
288 TPResult TPR = TryParseDeclarator(
false);
293 if (Tok.
isOneOf(tok::kw_asm, tok::kw___attribute))
297 if (Tok.
is(tok::l_paren)) {
302 }
else if (Tok.
is(tok::l_brace)) {
306 }
else if (Tok.
is(tok::equal) || isTokIdentifier_in()) {
340 : P(P), CanBeInitStatement(CanBeInitStatement) {}
350 RevertingTentativeParsingAction PA(
P);
352 if (
P.Tok.
isNot(tok::r_paren))
354 if (
P.Tok.
isNot(tok::semi))
378 llvm_unreachable(
"unknown tentative parse result");
381 ConditionOrInitStatement
result()
const {
383 "result called but not yet resolved");
411 Parser::ConditionOrInitStatement
412 Parser::isCXXConditionDeclarationOrInitStatement(
bool CanBeInitStatement) {
413 ConditionDeclarationOrInitStatementState
State(*
this, CanBeInitStatement);
415 if (
State.update(isCXXDeclarationSpecifier()))
416 return State.result();
419 RevertingTentativeParsingAction PA(*
this);
422 if (
State.update(TryConsumeDeclarationSpecifier()))
423 return State.result();
424 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
428 if (
State.update(TryParseDeclarator(
false)))
429 return State.result();
434 if (Tok.
isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
436 State.markNotExpression();
437 return State.result();
442 if (
State.markNotCondition())
443 return State.result();
447 if (Tok.
is(tok::l_paren)) {
457 if (
State.CanBeCondition && Tok.
is(tok::r_paren))
459 else if (
State.CanBeInitStatement && Tok.
is(tok::semi))
482 bool Parser::isCXXTypeId(TentativeCXXTypeIdContext
Context,
bool &isAmbiguous) {
493 TPResult TPR = isCXXDeclarationSpecifier();
504 RevertingTentativeParsingAction PA(*
this);
507 TryConsumeDeclarationSpecifier();
508 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
511 TPR = TryParseDeclarator(
true,
false);
520 if (Context == TypeIdInParens && Tok.
is(tok::r_paren)) {
527 }
else if (Context == TypeIdAsTemplateArgument &&
528 (Tok.
isOneOf(tok::greater, tok::comma) ||
529 (
getLangOpts().CPlusPlus11 && Tok.
is(tok::greatergreater)))) {
574 Parser::CXX11AttributeKind
575 Parser::isCXX11AttributeSpecifier(
bool Disambiguate,
576 bool OuterMightBeMessageSend) {
577 if (Tok.
is(tok::kw_alignas))
578 return CAK_AttributeSpecifier;
581 return CAK_NotAttributeSpecifier;
585 return CAK_AttributeSpecifier;
587 RevertingTentativeParsingAction PA(*
this);
596 bool IsAttribute =
SkipUntil(tok::r_square);
597 IsAttribute &= Tok.
is(tok::r_square);
599 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
615 if (!TryParseLambdaIntroducer(Intro)) {
617 bool IsAttribute = Tok.
is(tok::r_square);
621 return CAK_AttributeSpecifier;
623 if (OuterMightBeMessageSend)
625 return CAK_NotAttributeSpecifier;
628 return CAK_InvalidAttributeSpecifier;
635 bool IsAttribute =
true;
636 while (Tok.
isNot(tok::r_square)) {
637 if (Tok.
is(tok::comma)) {
639 return CAK_AttributeSpecifier;
648 if (!TryParseCXX11AttributeIdentifier(Loc)) {
652 if (Tok.
is(tok::coloncolon)) {
654 if (!TryParseCXX11AttributeIdentifier(Loc)) {
661 if (Tok.
is(tok::l_paren)) {
677 if (Tok.
is(tok::r_square)) {
679 IsAttribute = Tok.
is(tok::r_square);
687 return CAK_AttributeSpecifier;
690 return CAK_NotAttributeSpecifier;
693 Parser::TPResult Parser::TryParsePtrOperatorSeq() {
695 if (Tok.
isOneOf(tok::coloncolon, tok::identifier))
699 if (Tok.
isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
700 (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::star))) {
703 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
704 tok::kw__Nonnull, tok::kw__Nullable,
705 tok::kw__Null_unspecified))
731 Parser::TPResult Parser::TryParseOperatorId() {
732 assert(Tok.
is(tok::kw_operator));
737 case tok::kw_new:
case tok::kw_delete:
739 if (Tok.
is(tok::l_square) &&
NextToken().
is(tok::r_square)) {
745 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
747 #define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
748 #include "clang/Basic/OperatorKinds.def"
774 bool FoundUDSuffix =
false;
777 ConsumeStringToken();
778 }
while (isTokenStringLiteral());
780 if (!FoundUDSuffix) {
781 if (Tok.
is(tok::identifier))
790 bool AnyDeclSpecifiers =
false;
792 TPResult TPR = isCXXDeclarationSpecifier();
796 if (!AnyDeclSpecifiers)
802 AnyDeclSpecifiers =
true;
804 return TryParsePtrOperatorSeq();
860 Parser::TPResult Parser::TryParseDeclarator(
bool mayBeAbstract,
861 bool mayHaveIdentifier) {
870 if (Tok.
is(tok::ellipsis))
873 if ((Tok.
isOneOf(tok::identifier, tok::kw_operator) ||
874 (Tok.
is(tok::annot_cxxscope) && (
NextToken().
is(tok::identifier) ||
878 if (Tok.
is(tok::annot_cxxscope))
880 else if (Tok.
is(tok::identifier))
882 if (Tok.
is(tok::kw_operator)) {
887 }
else if (Tok.
is(tok::l_paren)) {
890 (Tok.
is(tok::r_paren) ||
893 isDeclarationSpecifier())) {
896 TPResult TPR = TryParseFunctionDeclarator();
903 if (Tok.
isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
904 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
905 tok::kw___vectorcall))
907 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
910 if (Tok.
isNot(tok::r_paren))
914 }
else if (!mayBeAbstract) {
922 if (Tok.
is(tok::ellipsis))
925 if (Tok.
is(tok::l_paren)) {
930 if (!mayBeAbstract && !isCXXFunctionDeclarator())
936 TPR = TryParseFunctionDeclarator();
937 }
else if (Tok.
is(tok::l_square)) {
940 TPR = TryParseBracketDeclarator();
956 case tok::numeric_constant:
957 case tok::char_constant:
958 case tok::wide_char_constant:
959 case tok::utf8_char_constant:
960 case tok::utf16_char_constant:
961 case tok::utf32_char_constant:
962 case tok::string_literal:
963 case tok::wide_string_literal:
964 case tok::utf8_string_literal:
965 case tok::utf16_string_literal:
966 case tok::utf32_string_literal:
975 case tok::minusminus:
979 case tok::kw___func__:
980 case tok::kw_const_cast:
982 case tok::kw_dynamic_cast:
985 case tok::kw_operator:
986 case tok::kw_reinterpret_cast:
987 case tok::kw_static_cast:
992 case tok::kw_alignof:
993 case tok::kw_noexcept:
994 case tok::kw_nullptr:
995 case tok::kw__Alignof:
997 case tok::kw___alignof:
998 case tok::kw___builtin_choose_expr:
999 case tok::kw___builtin_offsetof:
1000 case tok::kw___builtin_va_arg:
1001 case tok::kw___imag:
1002 case tok::kw___real:
1003 case tok::kw___FUNCTION__:
1004 case tok::kw___FUNCDNAME__:
1005 case tok::kw___FUNCSIG__:
1006 case tok::kw_L__FUNCTION__:
1007 case tok::kw___PRETTY_FUNCTION__:
1008 case tok::kw___uuidof:
1009 #define TYPE_TRAIT(N,Spelling,K) \
1010 case tok::kw_##Spelling:
1011 #include "clang/Basic/TokenKinds.def"
1017 case tok::kw_double:
1018 case tok::kw___float128:
1024 case tok::kw___int64:
1025 case tok::kw___int128:
1026 case tok::kw_restrict:
1028 case tok::kw_signed:
1029 case tok::kw_struct:
1031 case tok::kw_unsigned:
1033 case tok::kw_volatile:
1035 case tok::kw__Complex:
1037 case tok::kw_typename:
1038 case tok::kw_wchar_t:
1039 case tok::kw_char16_t:
1040 case tok::kw_char32_t:
1041 case tok::kw__Decimal32:
1042 case tok::kw__Decimal64:
1043 case tok::kw__Decimal128:
1044 case tok::kw___interface:
1045 case tok::kw___thread:
1046 case tok::kw_thread_local:
1047 case tok::kw__Thread_local:
1048 case tok::kw_typeof:
1049 case tok::kw___underlying_type:
1050 case tok::kw___cdecl:
1051 case tok::kw___stdcall:
1052 case tok::kw___fastcall:
1053 case tok::kw___thiscall:
1054 case tok::kw___vectorcall:
1055 case tok::kw___unaligned:
1056 case tok::kw___vector:
1057 case tok::kw___pixel:
1058 case tok::kw___bool:
1059 case tok::kw__Atomic:
1060 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1061 #include "clang/Basic/OpenCLImageTypes.def"
1062 case tok::kw___unknown_anytype:
1073 return std::find(TentativelyDeclaredIdentifiers.begin(),
1074 TentativelyDeclaredIdentifiers.end(), II)
1075 != TentativelyDeclaredIdentifiers.end();
1082 WantRemainingKeywords =
false;
1083 WantTypeSpecifiers = Next.
isOneOf(tok::l_paren, tok::r_paren, tok::greater,
1084 tok::l_brace, tok::identifier);
1087 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1091 std::all_of(Candidate.
begin(), Candidate.
end(),
1092 [](
NamedDecl *ND) {
return ND->isCXXInstanceMember(); }))
1206 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1207 bool *HasMissingTypename) {
1209 case tok::identifier: {
1212 if (TryAltiVecVectorToken())
1220 if (Next.
isNot(tok::coloncolon) && Next.
isNot(tok::less)) {
1225 switch (TryAnnotateName(
false ,
1226 llvm::make_unique<TentativeParseCCC>(Next))) {
1229 case ANK_TentativeDecl:
1231 case ANK_TemplateName:
1235 case ANK_Unresolved:
1240 assert(Tok.
isNot(tok::identifier) &&
1241 "TryAnnotateName succeeded without producing an annotation");
1252 if (Tok.
is(tok::identifier))
1257 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1260 case tok::kw_typename:
1265 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1267 case tok::coloncolon: {
1274 case tok::kw___super:
1275 case tok::kw_decltype:
1280 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1290 case tok::kw_friend:
1291 case tok::kw_typedef:
1292 case tok::kw_constexpr:
1293 case tok::kw_concept:
1295 case tok::kw_register:
1296 case tok::kw_static:
1297 case tok::kw_extern:
1298 case tok::kw_mutable:
1300 case tok::kw___thread:
1301 case tok::kw_thread_local:
1302 case tok::kw__Thread_local:
1304 case tok::kw_inline:
1305 case tok::kw_virtual:
1306 case tok::kw_explicit:
1309 case tok::kw___module_private__:
1312 case tok::kw___unknown_anytype:
1325 case tok::kw_struct:
1327 case tok::kw___interface:
1332 case tok::kw_volatile:
1335 case tok::kw_restrict:
1336 case tok::kw__Complex:
1337 case tok::kw___attribute:
1338 case tok::kw___auto_type:
1342 case tok::kw___declspec:
1343 case tok::kw___cdecl:
1344 case tok::kw___stdcall:
1345 case tok::kw___fastcall:
1346 case tok::kw___thiscall:
1347 case tok::kw___vectorcall:
1349 case tok::kw___sptr:
1350 case tok::kw___uptr:
1351 case tok::kw___ptr64:
1352 case tok::kw___ptr32:
1353 case tok::kw___forceinline:
1354 case tok::kw___unaligned:
1355 case tok::kw__Nonnull:
1356 case tok::kw__Nullable:
1357 case tok::kw__Null_unspecified:
1358 case tok::kw___kindof:
1362 case tok::kw___pascal:
1366 case tok::kw___vector:
1369 case tok::annot_template_id: {
1374 AnnotateTemplateIdTokenAsType();
1375 assert(Tok.
is(tok::annot_typename));
1379 case tok::annot_cxxscope:
1383 if (!Tok.
is(tok::annot_typename)) {
1386 if (Tok.
is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier)) {
1392 RevertingTentativeParsingAction PA(*
this);
1395 bool isIdentifier = Tok.
is(tok::identifier);
1398 TPR = isCXXDeclarationSpecifier(BracedCastResult,
1399 HasMissingTypename);
1405 if (HasMissingTypename) {
1408 *HasMissingTypename =
true;
1416 switch (TryAnnotateName(
false )) {
1419 case ANK_TentativeDecl:
1421 case ANK_TemplateName:
1425 case ANK_Unresolved:
1430 assert(Tok.
isNot(tok::annot_cxxscope) ||
1432 return isCXXDeclarationSpecifier(BracedCastResult,
1433 HasMissingTypename);
1459 case tok::annot_typename:
1464 RevertingTentativeParsingAction PA(*
this);
1467 TPResult TPR = TryParseProtocolQualifiers();
1468 bool isFollowedByParen = Tok.
is(tok::l_paren);
1469 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1474 if (isFollowedByParen)
1478 return BracedCastResult;
1484 case tok::kw_wchar_t:
1485 case tok::kw_char16_t:
1486 case tok::kw_char32_t:
1491 case tok::kw___int64:
1492 case tok::kw___int128:
1493 case tok::kw_signed:
1494 case tok::kw_unsigned:
1497 case tok::kw_double:
1498 case tok::kw___float128:
1500 case tok::annot_decltype:
1511 return BracedCastResult;
1513 if (isStartOfObjCClassMessageMissingOpenBracket())
1519 case tok::kw_typeof: {
1523 RevertingTentativeParsingAction PA(*
this);
1525 TPResult TPR = TryParseTypeofSpecifier();
1526 bool isFollowedByParen = Tok.
is(tok::l_paren);
1527 bool isFollowedByBrace = Tok.
is(tok::l_brace);
1532 if (isFollowedByParen)
1536 return BracedCastResult;
1542 case tok::kw___underlying_type:
1546 case tok::kw__Atomic:
1554 bool Parser::isCXXDeclarationSpecifierAType() {
1557 case tok::annot_decltype:
1558 case tok::annot_template_id:
1559 case tok::annot_typename:
1560 case tok::kw_typeof:
1561 case tok::kw___underlying_type:
1566 case tok::kw_struct:
1568 case tok::kw___interface:
1574 case tok::kw_wchar_t:
1575 case tok::kw_char16_t:
1576 case tok::kw_char32_t:
1581 case tok::kw___int64:
1582 case tok::kw___int128:
1583 case tok::kw_signed:
1584 case tok::kw_unsigned:
1587 case tok::kw_double:
1588 case tok::kw___float128:
1590 case tok::kw___unknown_anytype:
1591 case tok::kw___auto_type:
1597 case tok::kw__Atomic:
1610 Parser::TPResult Parser::TryParseTypeofSpecifier() {
1611 assert(Tok.
is(tok::kw_typeof) &&
"Expected 'typeof'!");
1614 assert(Tok.
is(tok::l_paren) &&
"Expected '('");
1625 Parser::TPResult Parser::TryParseProtocolQualifiers() {
1626 assert(Tok.
is(tok::less) &&
"Expected '<' for qualifier list");
1629 if (Tok.
isNot(tok::identifier))
1633 if (Tok.
is(tok::comma)) {
1638 if (Tok.
is(tok::greater)) {
1657 bool Parser::isCXXFunctionDeclarator(
bool *IsAmbiguous) {
1668 RevertingTentativeParsingAction PA(*
this);
1671 bool InvalidAsDeclaration =
false;
1672 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
1674 if (Tok.
isNot(tok::r_paren))
1678 if (Next.
isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1679 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1680 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1681 isCXX11VirtSpecifier(Next))
1686 else if (InvalidAsDeclaration)
1693 *IsAmbiguous =
true;
1717 Parser::TryParseParameterDeclarationClause(
bool *InvalidAsDeclaration,
1718 bool VersusTemplateArgument) {
1720 if (Tok.
is(tok::r_paren))
1732 if (Tok.
is(tok::ellipsis)) {
1734 if (Tok.
is(tok::r_paren))
1741 if (isCXX11AttributeSpecifier(
false,
1746 MaybeParseMicrosoftAttributes(attrs);
1752 InvalidAsDeclaration);
1757 bool SeenType =
false;
1759 SeenType |= isCXXDeclarationSpecifierAType();
1764 if (SeenType && Tok.
is(tok::identifier))
1768 InvalidAsDeclaration);
1781 TPR = TryParseDeclarator(
true);
1786 if (Tok.
is(tok::kw___attribute))
1799 if (VersusTemplateArgument)
1803 if (Tok.
is(tok::equal)) {
1811 if (Tok.
is(tok::ellipsis)) {
1813 if (Tok.
is(tok::r_paren))
1838 Parser::TPResult Parser::TryParseFunctionDeclarator() {
1842 TPResult TPR = TryParseParameterDeclarationClause();
1854 while (Tok.
isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict))
1858 if (Tok.
isOneOf(tok::amp, tok::ampamp))
1862 if (Tok.
is(tok::kw_throw)) {
1864 if (Tok.
isNot(tok::l_paren))
1872 if (Tok.
is(tok::kw_noexcept)) {
1875 if (Tok.
is(tok::l_paren)) {
1888 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 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.
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