32 #include "llvm/ADT/SmallString.h"
33 #include "llvm/ADT/SmallVector.h"
34 using namespace clang;
122 return ParseRHSOfBinaryExpression(LHS,
prec::Comma);
133 return ParseRHSOfBinaryExpression(LHS,
prec::Comma);
140 Parser::ParseExpressionWithLeadingExtension(
SourceLocation ExtLoc) {
146 LHS = ParseCastExpression(
false);
149 if (!LHS.isInvalid())
153 return ParseRHSOfBinaryExpression(LHS,
prec::Comma);
158 if (Tok.
is(tok::code_completion)) {
164 if (Tok.
is(tok::kw_throw))
165 return ParseThrowExpression();
183 Parser::ParseAssignmentExprWithObjCMessageExprStart(
SourceLocation LBracLoc,
186 Expr *ReceiverExpr) {
188 = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc,
189 ReceiverType, ReceiverExpr);
190 R = ParsePostfixExpressionSuffix(R);
203 ExprResult LHS(ParseCastExpression(
false,
false, isTypeCast));
226 bool Parser::isNotExpressionStart() {
228 if (K == tok::l_brace || K == tok::r_brace ||
229 K == tok::kw_for || K == tok::kw_while ||
230 K == tok::kw_if || K == tok::kw_else ||
231 K == tok::kw_goto || K == tok::kw_try)
234 return isKnownToBeDeclarationSpecifier();
249 GreaterThanIsOperator,
257 if (NextTokPrec < MinPrec)
269 if (OpToken.
is(tok::comma) && isNotExpressionStart()) {
288 if (Tok.
isNot(tok::colon)) {
297 if (TernaryMiddle.isInvalid()) {
300 TernaryMiddle =
nullptr;
305 TernaryMiddle =
nullptr;
306 Diag(Tok, diag::ext_gnu_conditional_expr);
315 const char *FIText =
": ";
319 bool IsInvalid =
false;
320 const char *SourcePtr =
322 if (!IsInvalid && *SourcePtr ==
' ') {
325 if (!IsInvalid && *SourcePtr ==
' ') {
332 Diag(Tok, diag::err_expected)
334 Diag(OpToken, diag::note_matching) << tok::question;
358 bool RHSIsInitList =
false;
360 RHS = ParseBraceInitializer();
361 RHSIsInitList =
true;
365 RHS = ParseCastExpression(
false);
371 if (TernaryMiddle.isUsable())
388 if (ThisPrec < NextTokPrec ||
389 (ThisPrec == NextTokPrec && isRightAssoc)) {
391 Diag(Tok, diag::err_init_list_bin_op)
400 RHS = ParseRHSOfBinaryExpression(RHS,
401 static_cast<prec::Level>(ThisPrec + !isRightAssoc));
402 RHSIsInitList =
false;
408 if (TernaryMiddle.isUsable())
419 Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists)
422 Diag(OpToken, diag::err_init_list_bin_op)
431 if (TernaryMiddle.isInvalid()) {
435 if (!GreaterThanIsOperator && OpToken.
is(tok::greatergreater))
437 diag::warn_cxx11_right_shift_in_template_arg,
445 LHS.
get(), TernaryMiddle.get(),
459 ExprResult Parser::ParseCastExpression(
bool isUnaryExpression,
460 bool isAddressOfOperand,
461 TypeCastState isTypeCast) {
463 ExprResult Res = ParseCastExpression(isUnaryExpression,
468 Diag(Tok, diag::err_expected_expression);
475 CastExpressionIdValidator(
Token Next,
bool AllowTypes,
bool AllowNonTypes)
476 : NextToken(Next), AllowNonTypes(AllowNonTypes) {
477 WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes;
480 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
485 if (isa<TypeDecl>(ND))
486 return WantTypeSpecifiers;
491 if (!NextToken.isOneOf(tok::equal, tok::arrow, tok::period))
494 for (
auto *
C : candidate) {
496 if (isa<ValueDecl>(ND) && !isa<FunctionDecl>(ND))
678 ExprResult Parser::ParseCastExpression(
bool isUnaryExpression,
679 bool isAddressOfOperand,
681 TypeCastState isTypeCast) {
701 ParenParseOption ParenExprType =
702 (isUnaryExpression && !
getLangOpts().CPlusPlus) ? CompoundLiteral
706 Res = ParseParenExpression(ParenExprType,
false,
709 switch (ParenExprType) {
710 case SimpleExpr:
break;
712 case CompoundLiteral:
726 case tok::numeric_constant:
736 return ParseCXXBoolLiteral();
738 case tok::kw___objc_yes:
739 case tok::kw___objc_no:
740 return ParseObjCBoolLiteral();
742 case tok::kw_nullptr:
743 Diag(Tok, diag::warn_cxx98_compat_nullptr);
746 case tok::annot_primary_expr:
747 assert(Res.
get() ==
nullptr &&
"Stray primary-expression annotation?");
748 Res = getExprAnnotation(Tok);
752 case tok::kw___super:
753 case tok::kw_decltype:
757 assert(Tok.
isNot(tok::kw_decltype) && Tok.
isNot(tok::kw___super));
758 return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
760 case tok::identifier: {
773 if (Next.
is(tok::l_paren) &&
774 Tok.
is(tok::identifier) &&
778 if (RevertibleTypeTraits.empty()) {
779 #define RTT_JOIN(X,Y) X##Y
780 #define REVERTIBLE_TYPE_TRAIT(Name) \
781 RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \
782 = RTT_JOIN(tok::kw_,Name)
833 #undef REVERTIBLE_TYPE_TRAIT
840 llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known
841 = RevertibleTypeTraits.find(II);
842 if (Known != RevertibleTypeTraits.end()) {
844 return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
845 NotCastExpr, isTypeCast);
849 if ((!ColonIsSacred && Next.
is(tok::colon)) ||
850 Next.
isOneOf(tok::coloncolon, tok::less, tok::l_paren,
855 if (!Tok.
is(tok::identifier))
856 return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
873 if (Tok.
isNot(tok::identifier) &&
875 Diag(Tok, diag::err_expected_property_name);
890 if (
getLangOpts().ObjC1 && &II == Ident_super && !InMessageExpression &&
892 ((Tok.
is(tok::identifier) &&
894 Tok.
is(tok::code_completion))) {
906 ((Tok.
is(tok::identifier) && !InMessageExpression) ||
907 Tok.
is(tok::code_completion))) {
909 if (Tok.
is(tok::code_completion) ||
910 Next.
is(tok::colon) || Next.
is(tok::r_square))
912 if (Typ.get()->isObjCObjectOrInterfaceType()) {
915 DS.SetRangeStart(ILoc);
916 DS.SetRangeEnd(ILoc);
917 const char *PrevSpec =
nullptr;
919 DS.SetTypeSpecType(
TST_typename, ILoc, PrevSpec, DiagID, Typ,
936 if (isAddressOfOperand && isPostfixExpressionSuffixStart())
937 isAddressOfOperand =
false;
946 auto Validator = llvm::make_unique<CastExpressionIdValidator>(
948 Validator->IsAddressOfOperand = isAddressOfOperand;
949 if (Tok.isOneOf(tok::periodstar, tok::arrowstar)) {
950 Validator->WantExpressionKeywords =
false;
951 Validator->WantRemainingKeywords =
false;
953 Validator->WantRemainingKeywords = Tok.
isNot(tok::r_paren);
957 getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren),
958 isAddressOfOperand, std::move(Validator),
960 Tok.is(tok::r_paren) ?
nullptr : &Replacement);
961 if (!Res.isInvalid() && !Res.get()) {
962 UnconsumeToken(Replacement);
963 return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
964 NotCastExpr, isTypeCast);
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:
976 case tok::kw___func__:
977 case tok::kw___FUNCTION__:
978 case tok::kw___FUNCDNAME__:
979 case tok::kw___FUNCSIG__:
980 case tok::kw_L__FUNCTION__:
981 case tok::kw___PRETTY_FUNCTION__:
985 case tok::string_literal:
986 case tok::wide_string_literal:
987 case tok::utf8_string_literal:
988 case tok::utf16_string_literal:
989 case tok::utf32_string_literal:
990 Res = ParseStringLiteralExpression(
true);
992 case tok::kw__Generic:
993 Res = ParseGenericSelectionExpression();
995 case tok::kw___builtin_va_arg:
996 case tok::kw___builtin_offsetof:
997 case tok::kw___builtin_choose_expr:
998 case tok::kw___builtin_astype:
999 case tok::kw___builtin_convertvector:
1000 return ParseBuiltinPrimaryExpression();
1001 case tok::kw___null:
1005 case tok::minusminus: {
1017 if (!Res.isInvalid())
1024 Res = ParseCastExpression(
false,
true);
1025 if (!Res.isInvalid())
1035 case tok::kw___real:
1036 case tok::kw___imag: {
1038 Res = ParseCastExpression(
false);
1039 if (!Res.isInvalid())
1044 case tok::kw___extension__:{
1048 Res = ParseCastExpression(
false);
1049 if (!Res.isInvalid())
1053 case tok::kw__Alignof:
1055 Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
1057 case tok::kw_alignof:
1058 case tok::kw___alignof:
1060 case tok::kw_sizeof:
1062 case tok::kw_vec_step:
1064 case tok::kw___builtin_omp_required_simd_align:
1065 return ParseUnaryExprOrTypeTraitExpression();
1068 if (Tok.isNot(tok::identifier))
1069 return ExprError(
Diag(Tok, diag::err_expected) << tok::identifier);
1072 return ExprError(
Diag(Tok, diag::err_address_of_label_outside_fn));
1074 Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
1081 case tok::kw_const_cast:
1082 case tok::kw_dynamic_cast:
1083 case tok::kw_reinterpret_cast:
1084 case tok::kw_static_cast:
1085 Res = ParseCXXCasts();
1087 case tok::kw_typeid:
1088 Res = ParseCXXTypeid();
1090 case tok::kw___uuidof:
1091 Res = ParseCXXUuidof();
1094 Res = ParseCXXThis();
1097 case tok::annot_typename:
1098 if (isStartOfObjCClassMessageMissingOpenBracket()) {
1103 DS.SetRangeStart(Tok.getLocation());
1104 DS.SetRangeEnd(Tok.getLastLoc());
1106 const char *PrevSpec =
nullptr;
1108 DS.SetTypeSpecType(
TST_typename, Tok.getAnnotationEndLoc(),
1109 PrevSpec, DiagID, Type,
1124 case tok::annot_decltype:
1126 case tok::kw_wchar_t:
1127 case tok::kw_char16_t:
1128 case tok::kw_char32_t:
1133 case tok::kw___int64:
1134 case tok::kw___int128:
1135 case tok::kw_signed:
1136 case tok::kw_unsigned:
1139 case tok::kw_double:
1141 case tok::kw_typename:
1142 case tok::kw_typeof:
1143 case tok::kw___vector: {
1145 Diag(Tok, diag::err_expected_expression);
1149 if (SavedKind == tok::kw_typename) {
1166 ParseCXXSimpleTypeSpecifier(DS);
1167 if (Tok.isNot(tok::l_paren) &&
1168 (!
getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace)))
1169 return ExprError(
Diag(Tok, diag::err_expected_lparen_after_type)
1170 << DS.getSourceRange());
1172 if (Tok.is(tok::l_brace))
1173 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1175 Res = ParseCXXTypeConstructExpression(DS);
1179 case tok::annot_cxxscope: {
1184 if (!Tok.is(tok::annot_cxxscope))
1185 return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
1186 NotCastExpr, isTypeCast);
1189 if (Next.
is(tok::annot_template_id)) {
1196 ParseOptionalCXXScopeSpecifier(SS,
ParsedType(),
1198 AnnotateTemplateIdTokenAsType();
1199 return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
1200 NotCastExpr, isTypeCast);
1205 Res = ParseCXXIdExpression(isAddressOfOperand);
1209 case tok::annot_template_id: {
1215 AnnotateTemplateIdTokenAsType();
1216 return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
1217 NotCastExpr, isTypeCast);
1223 case tok::kw_operator:
1224 Res = ParseCXXIdExpression(isAddressOfOperand);
1227 case tok::coloncolon: {
1232 if (!Tok.is(tok::coloncolon))
1233 return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
1238 if (Tok.is(tok::kw_new))
1239 return ParseCXXNewExpression(
true, CCLoc);
1240 if (Tok.is(tok::kw_delete))
1241 return ParseCXXDeleteExpression(
true, CCLoc);
1244 Diag(CCLoc, diag::err_expected_expression);
1249 return ParseCXXNewExpression(
false, Tok.getLocation());
1251 case tok::kw_delete:
1252 return ParseCXXDeleteExpression(
false, Tok.getLocation());
1254 case tok::kw_noexcept: {
1255 Diag(Tok, diag::warn_cxx98_compat_noexcept_expr);
1259 if (T.expectAndConsume(diag::err_expected_lparen_after,
"noexcept"))
1271 Result.
get(), T.getCloseLocation());
1275 #define TYPE_TRAIT(N,Spelling,K) \
1276 case tok::kw_##Spelling:
1277 #include "clang/Basic/TokenKinds.def"
1278 return ParseTypeTrait();
1280 case tok::kw___array_rank:
1281 case tok::kw___array_extent:
1282 return ParseArrayTypeTrait();
1284 case tok::kw___is_lvalue_expr:
1285 case tok::kw___is_rvalue_expr:
1286 return ParseExpressionTrait();
1290 return ParseObjCAtExpression(AtLoc);
1293 Res = ParseBlockLiteralExpression();
1295 case tok::code_completion: {
1308 Res = TryParseLambdaExpression();
1309 if (!Res.isInvalid() && !Res.get())
1310 Res = ParseObjCMessageExpression();
1313 Res = ParseLambdaExpression();
1317 Res = ParseObjCMessageExpression();
1327 return ParsePostfixExpressionSuffix(Res);
1351 Parser::ParsePostfixExpressionSuffix(
ExprResult LHS) {
1356 switch (Tok.getKind()) {
1357 case tok::code_completion:
1358 if (InMessageExpression)
1365 case tok::identifier:
1369 if (
getLangOpts().ObjC1 && !InMessageExpression &&
1380 case tok::l_square: {
1387 if (
getLangOpts().ObjC1 && Tok.isAtStartOfLine() &&
1388 isSimpleObjCMessageExpression())
1393 if (CheckProhibitedCXX11Attribute())
1398 Loc = T.getOpenLocation();
1401 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1402 Idx = ParseBraceInitializer();
1424 case tok::lesslessless: {
1429 Expr *ExecConfig =
nullptr;
1433 if (OpKind == tok::lesslessless) {
1434 ExprVector ExecConfigExprs;
1435 CommaLocsTy ExecConfigCommaLocs;
1438 if (ParseSimpleExpressionList(ExecConfigExprs, ExecConfigCommaLocs)) {
1449 Diag(Tok, diag::err_expected) << tok::greatergreatergreater;
1450 Diag(OpenLoc, diag::note_matching) << tok::lesslessless;
1456 if (ExpectAndConsume(tok::l_paren))
1459 Loc = PrevTokLocation;
1470 ExecConfig = ECResult.
get();
1474 Loc = PT.getOpenLocation();
1477 ExprVector ArgExprs;
1478 CommaLocsTy CommaLocs;
1480 if (Tok.is(tok::code_completion)) {
1486 if (OpKind == tok::l_paren || !LHS.
isInvalid()) {
1487 if (Tok.isNot(tok::r_paren)) {
1488 if (ParseExpressionList(ArgExprs, CommaLocs, [&] {
1494 for (
auto &E : ArgExprs)
1503 }
else if (Tok.isNot(tok::r_paren)) {
1504 bool HadDelayedTypo =
false;
1506 HadDelayedTypo =
true;
1507 for (
auto &E : ArgExprs)
1509 HadDelayedTypo =
true;
1519 assert((ArgExprs.size() == 0 ||
1520 ArgExprs.size()-1 == CommaLocs.size())&&
1521 "Unexpected number of commas!");
1523 ArgExprs, Tok.getLocation(),
1539 bool MayBePseudoDestructor =
false;
1543 if (BaseType && Tok.is(tok::l_paren) &&
1546 Diag(OpLoc, diag::err_function_is_not_record)
1547 << OpKind << Base->getSourceRange()
1549 return ParsePostfixExpressionSuffix(Base);
1553 OpLoc, OpKind, ObjectType,
1554 MayBePseudoDestructor);
1558 ParseOptionalCXXScopeSpecifier(SS, ObjectType,
1560 &MayBePseudoDestructor);
1565 if (Tok.is(tok::code_completion)) {
1568 OpLoc, OpKind == tok::arrow);
1574 if (MayBePseudoDestructor && !LHS.
isInvalid()) {
1575 LHS = ParseCXXPseudoDestructor(LHS.
get(), OpLoc, OpKind, SS,
1589 if (
getLangOpts().ObjC2 && OpKind == tok::period &&
1590 Tok.is(tok::kw_class)) {
1606 ObjectType, TemplateKWLoc, Name)) {
1613 OpKind, SS, TemplateKWLoc, Name,
1614 CurParsedObjCImpl ? CurParsedObjCImpl->Dcl
1619 case tok::minusminus:
1622 Tok.getKind(), LHS.
get());
1654 Parser::ParseExprAfterUnaryExprOrTypeTrait(
const Token &OpTok,
1659 assert(OpTok.
isOneOf(tok::kw_typeof, tok::kw_sizeof, tok::kw___alignof,
1660 tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step,
1661 tok::kw___builtin_omp_required_simd_align) &&
1662 "Not a typeof/sizeof/alignof/vec_step expression!");
1667 if (Tok.isNot(tok::l_paren)) {
1670 if (OpTok.
isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof,
1671 tok::kw__Alignof)) {
1672 if (isTypeIdUnambiguously()) {
1674 ParseSpecifierQualifierList(DS);
1676 ParseDeclarator(DeclaratorInfo);
1680 Diag(LParenLoc, diag::err_expected_parentheses_around_typename)
1696 Operand = ParseCastExpression(
true);
1702 ParenParseOption ExprType =
CastExpr;
1705 Operand = ParseParenExpression(ExprType,
true,
1706 false, CastTy, RParenLoc);
1721 if (!Operand.isInvalid())
1722 Operand = ParsePostfixExpressionSuffix(Operand.get());
1744 ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
1745 assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof,
1746 tok::kw__Alignof, tok::kw_vec_step,
1747 tok::kw___builtin_omp_required_simd_align) &&
1748 "Not a sizeof/alignof/vec_step expression!");
1753 if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) {
1758 if (Tok.is(tok::l_paren)) {
1761 LParenLoc = T.getOpenLocation();
1762 if (Tok.is(tok::identifier)) {
1763 Name = Tok.getIdentifierInfo();
1766 RParenLoc = T.getCloseLocation();
1770 Diag(Tok, diag::err_expected_parameter_pack);
1773 }
else if (Tok.is(tok::identifier)) {
1774 Name = Tok.getIdentifierInfo();
1778 Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack)
1783 Diag(Tok, diag::err_sizeof_parameter_pack);
1793 OpTok.getLocation(),
1798 if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
1799 Diag(OpTok, diag::warn_cxx98_compat_alignof);
1807 ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok,
1813 if (OpTok.isOneOf(tok::kw_alignof, tok::kw___alignof, tok::kw__Alignof))
1815 else if (OpTok.is(tok::kw_vec_step))
1817 else if (OpTok.is(tok::kw___builtin_omp_required_simd_align))
1827 if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
1828 Diag(OpTok, diag::ext_alignof_expr) << OpTok.getIdentifierInfo();
1856 ExprResult Parser::ParseBuiltinPrimaryExpression() {
1864 if (Tok.isNot(tok::l_paren))
1865 return ExprError(
Diag(Tok, diag::err_expected_after) << BuiltinII
1874 default: llvm_unreachable(
"Not a builtin primary expression!");
1875 case tok::kw___builtin_va_arg: {
1878 if (ExpectAndConsume(tok::comma)) {
1885 if (Tok.isNot(tok::r_paren)) {
1886 Diag(Tok, diag::err_expected) << tok::r_paren;
1896 case tok::kw___builtin_offsetof: {
1904 if (ExpectAndConsume(tok::comma)) {
1910 if (Tok.isNot(tok::identifier)) {
1911 Diag(Tok, diag::err_expected) << tok::identifier;
1920 Comps.back().isBrackets =
false;
1921 Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
1922 Comps.back().LocStart = Comps.back().LocEnd =
ConsumeToken();
1926 if (Tok.is(tok::period)) {
1929 Comps.back().isBrackets =
false;
1932 if (Tok.isNot(tok::identifier)) {
1933 Diag(Tok, diag::err_expected) << tok::identifier;
1937 Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
1940 }
else if (Tok.is(tok::l_square)) {
1941 if (CheckProhibitedCXX11Attribute())
1946 Comps.back().isBrackets =
true;
1949 Comps.back().LocStart = ST.getOpenLocation();
1955 Comps.back().U.E = Res.
get();
1958 Comps.back().LocEnd = ST.getCloseLocation();
1960 if (Tok.isNot(tok::r_paren)) {
1968 Ty.
get(), &Comps[0], Comps.size(),
1969 PT.getCloseLocation());
1976 case tok::kw___builtin_choose_expr: {
1978 if (Cond.isInvalid()) {
1982 if (ExpectAndConsume(tok::comma)) {
1988 if (Expr1.isInvalid()) {
1992 if (ExpectAndConsume(tok::comma)) {
1998 if (Expr2.isInvalid()) {
2002 if (Tok.isNot(tok::r_paren)) {
2003 Diag(Tok, diag::err_expected) << tok::r_paren;
2007 Expr2.get(), ConsumeParen());
2010 case tok::kw___builtin_astype: {
2013 if (
Expr.isInvalid()) {
2018 if (ExpectAndConsume(tok::comma)) {
2029 if (Tok.isNot(tok::r_paren)) {
2030 Diag(Tok, diag::err_expected) << tok::r_paren;
2039 case tok::kw___builtin_convertvector: {
2042 if (
Expr.isInvalid()) {
2047 if (ExpectAndConsume(tok::comma)) {
2058 if (Tok.isNot(tok::r_paren)) {
2059 Diag(Tok, diag::err_expected) << tok::r_paren;
2075 return ParsePostfixExpressionSuffix(Res.
get());
2104 Parser::ParseParenExpression(ParenParseOption &ExprType,
bool stopIfCastExpr,
2107 assert(Tok.is(tok::l_paren) &&
"Not a paren expr!");
2110 if (T.consumeOpen())
2115 bool isAmbiguousTypeId;
2118 if (Tok.is(tok::code_completion)) {
2128 Tok.isOneOf(tok::kw___bridge,
2129 tok::kw___bridge_transfer,
2130 tok::kw___bridge_retained,
2131 tok::kw___bridge_retain));
2132 if (BridgeCast && !
getLangOpts().ObjCAutoRefCount) {
2134 StringRef BridgeCastName = Tok.getName();
2137 Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc)
2146 if (ExprType >=
CompoundStmt && Tok.is(tok::l_brace)) {
2147 Diag(Tok, diag::ext_gnu_statement_expr);
2150 Result =
ExprError(
Diag(OpenLoc, diag::err_stmtexpr_file_scope));
2156 while (CodeDC->
isRecord() || isa<EnumDecl>(CodeDC)) {
2159 "statement expr not in code context");
2169 if (!
Stmt.isInvalid()) {
2175 }
else if (ExprType >= CompoundLiteral && BridgeCast) {
2181 if (tokenKind == tok::kw___bridge)
2183 else if (tokenKind == tok::kw___bridge_transfer)
2185 else if (tokenKind == tok::kw___bridge_retained)
2190 assert(tokenKind == tok::kw___bridge_retain);
2193 Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain)
2195 "__bridge_retained");
2200 ColonProtection.restore();
2201 RParenLoc = T.getCloseLocation();
2202 ExprResult SubExpr = ParseCastExpression(
false);
2208 BridgeKeywordLoc, Ty.
get(),
2209 RParenLoc, SubExpr.
get());
2210 }
else if (ExprType >= CompoundLiteral &&
2211 isTypeIdInParens(isAmbiguousTypeId)) {
2220 if (isAmbiguousTypeId && !stopIfCastExpr) {
2221 ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T,
2223 RParenLoc = T.getCloseLocation();
2229 ParseSpecifierQualifierList(DS);
2231 ParseDeclarator(DeclaratorInfo);
2236 if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) &&
2250 ColonProtection.restore();
2251 RParenLoc = T.getCloseLocation();
2252 if (Tok.is(tok::l_brace)) {
2253 ExprType = CompoundLiteral;
2259 return ParseCompoundLiteralExpression(Ty.
get(), OpenLoc, RParenLoc);
2265 if (DeclaratorInfo.isInvalidType())
2270 if (stopIfCastExpr) {
2281 if (Tok.is(tok::identifier) &&
getLangOpts().ObjC1 &&
2282 Tok.getIdentifierInfo() == Ident_super &&
2284 GetLookAheadToken(1).
isNot(tok::period)) {
2285 Diag(Tok.getLocation(), diag::err_illegal_super_cast)
2292 Result = ParseCastExpression(
false,
2297 DeclaratorInfo, CastTy,
2298 RParenLoc, Result.
get());
2303 Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
2306 }
else if (Tok.is(tok::ellipsis) &&
2309 }
else if (isTypeCast) {
2313 ExprVector ArgExprs;
2314 CommaLocsTy CommaLocs;
2316 if (!ParseSimpleExpressionList(ArgExprs, CommaLocs)) {
2321 return ParseFoldExpression(Result, T);
2323 ExprType = SimpleExpr;
2336 ExprType = SimpleExpr;
2339 return ParseFoldExpression(Result, T);
2342 if (!Result.
isInvalid() && Tok.is(tok::r_paren))
2354 RParenLoc = T.getCloseLocation();
2367 Parser::ParseCompoundLiteralExpression(
ParsedType Ty,
2370 assert(Tok.is(tok::l_brace) &&
"Not a compound literal!");
2372 Diag(LParenLoc, diag::ext_c99_compound_literal);
2387 ExprResult Parser::ParseStringLiteralExpression(
bool AllowUserDefinedLiteral) {
2388 assert(isTokenStringLiteral() &&
"Not a string literal!");
2395 StringToks.push_back(Tok);
2396 ConsumeStringToken();
2397 }
while (isTokenStringLiteral());
2418 ExprResult Parser::ParseGenericSelectionExpression() {
2419 assert(Tok.is(tok::kw__Generic) &&
"_Generic keyword expected");
2423 Diag(KeyLoc, diag::ext_c11_generic_selection);
2426 if (T.expectAndConsume())
2442 if (ExpectAndConsume(tok::comma)) {
2452 if (Tok.is(tok::kw_default)) {
2456 Diag(Tok, diag::err_duplicate_default_assoc);
2457 Diag(DefaultLoc, diag::note_previous_default_assoc);
2472 Types.push_back(Ty);
2474 if (ExpectAndConsume(tok::colon)) {
2483 if (ER.isInvalid()) {
2487 Exprs.push_back(ER.get());
2491 if (T.getCloseLocation().isInvalid())
2495 T.getCloseLocation(),
2496 ControllingExpr.
get(),
2518 Kind = Tok.getKind();
2523 assert(Tok.is(tok::ellipsis) &&
"not a fold-expression");
2527 if (Tok.isNot(tok::r_paren)) {
2529 return Diag(Tok.getLocation(), diag::err_expected_fold_operator);
2531 if (Kind != tok::unknown && Tok.getKind() !=
Kind)
2532 Diag(Tok.getLocation(), diag::err_fold_operator_mismatch)
2534 Kind = Tok.getKind();
2545 ? diag::warn_cxx14_compat_fold_expression
2546 : diag::ext_fold_expression);
2577 std::function<
void()> Completer) {
2578 bool SawError =
false;
2580 if (Tok.is(tok::code_completion)) {
2591 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2592 Expr = ParseBraceInitializer();
2596 if (Tok.is(tok::ellipsis))
2602 Exprs.push_back(Expr.
get());
2605 if (Tok.isNot(tok::comma))
2613 for (
auto &E : Exprs) {
2637 Exprs.push_back(Expr.
get());
2639 if (Tok.isNot(tok::comma))
2654 if (Tok.is(tok::code_completion)) {
2656 return cutOffParsing();
2661 ParseSpecifierQualifierList(DS);
2665 ParseDeclarator(DeclaratorInfo);
2667 MaybeParseGNUAttributes(DeclaratorInfo);
2683 ExprResult Parser::ParseBlockLiteralExpression() {
2684 assert(Tok.is(tok::caret) &&
"block literal starts with ^");
2688 "block literal parsing");
2705 ParamInfo.SetSourceRange(
SourceRange(Tok.getLocation(), Tok.getLocation()));
2709 if (Tok.is(tok::l_paren)) {
2710 ParseParenDeclarator(ParamInfo);
2715 ParamInfo.SetIdentifier(
nullptr, CaretLoc);
2716 ParamInfo.SetRangeEnd(Tmp);
2717 if (ParamInfo.isInvalidType()) {
2725 MaybeParseGNUAttributes(ParamInfo);
2729 }
else if (!Tok.is(tok::l_brace)) {
2730 ParseBlockId(CaretLoc);
2760 MaybeParseGNUAttributes(ParamInfo);
2768 if (!Tok.is(tok::l_brace)) {
2770 Diag(Tok, diag::err_expected_expression);
2777 if (!
Stmt.isInvalid())
SourceManager & getSourceManager() const
SourceLocation getCloseLocation() const
Defines the clang::ASTContext interface.
ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc, Declarator &D, ParsedType &Ty, SourceLocation RParenLoc, Expr *CastExpr)
no exception specification
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
Simple class containing the result of Sema::CorrectTypo.
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ObjCBridgeCastKind
The kind of bridging performed by the Objective-C bridge cast.
const LangOptions & getLangOpts() const
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
const Scope * getFnParent() const
Bridging via __bridge, which does nothing but reinterpret the bits.
ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc)
void CodeCompleteAssignmentRHS(Scope *S, Expr *LHS)
ActionResult< Expr * > ExprResult
void ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, Scope *CurScope)
ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen, Expr *Operand, SourceLocation RParen)
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer...
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
bool isAtStartOfMacroExpansion(SourceLocation loc, SourceLocation *MacroBegin=nullptr) const
Returns true if the given MacroID location points at the first token of the macro expansion...
const char * getName() const
ExprResult ActOnVAArg(SourceLocation BuiltinLoc, Expr *E, ParsedType Ty, SourceLocation RPLoc)
This indicates that the scope corresponds to a function, which means that labels are set here...
ExprResult ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, ParsedType Type, SourceLocation RParenLoc, Expr *SubExpr)
TemplateNameKind Kind
The kind of template that Template refers to.
TypeCastState
TypeCastState - State whether an expression is or may be a type cast.
ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc)
void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef< Expr * > Args)
RAII object that enters a new expression evaluation context.
void EnterToken(const Token &Tok)
Enters a token in the token stream to be lexed next.
Information about one declarator, including the parsed type information and the identifier.
#define REVERTIBLE_TYPE_TRAIT(Name)
void ActOnStartStmtExpr()
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
Information about a template-id annotation token.
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false)
Base wrapper for a particular "section" of type source info.
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
const Token & NextToken()
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
bool TryConsumeToken(tok::TokenKind Expected)
ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Kind, Expr *Input)
OpaquePtr< QualType > ParsedType
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc)
ActOnCXXNullPtrLiteral - Parse 'nullptr'.
void setKind(tok::TokenKind K)
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind)
ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
SourceRange getExprRange(Expr *E) const
Code completion occurs where only a type is permitted.
ExprResult ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, ParsedType &ObjectType, bool &MayBePseudoDestructor)
This is a scope that corresponds to a block/closure object. Blocks serve as top-level scopes for some...
ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body, Scope *CurScope)
ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, Expr *ControllingExpr, ArrayRef< ParsedType > ArgTypes, ArrayRef< Expr * > ArgExprs)
Represents a C++ unqualified-id that has been parsed.
ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc, MultiExprArg ExecConfig, SourceLocation GGGLoc)
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
bool isSpecificPlaceholderType(unsigned K) const
isSpecificPlaceholderType - Test for a specific placeholder type.
void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope)
ActOnBlockStart - This callback is invoked when a block literal is started.
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=ParsedType(), bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type...
void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, SourceLocation OpLoc, bool IsArrow)
Code completion occurs within an expression.
ExprResult ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, bool IsType, void *TyOrEx, const SourceRange &ArgRange)
ExprResult ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, tok::TokenKind Operator, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc)
Handle a C++1z fold-expression: ( expr op ... op expr ).
Represents a C++ nested-name-specifier or a global scope specifier.
LabelDecl * LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, SourceLocation GnuLabelLoc=SourceLocation())
tok::TokenKind getKind() const
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope=nullptr)
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC...
void ActOnStmtExprError()
TypeResult ParseTypeName(SourceRange *Range=nullptr, Declarator::TheContext Context=Declarator::TypeNameContext, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc, Expr *InitExpr)
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
const Type * getTypePtrOrNull() const
This file defines the classes used to store parsed information about declaration-specifiers and decla...
TypeResult ActOnTypeName(Scope *S, Declarator &D)
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
bool isNot(tok::TokenKind K) const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
static bool isFoldOperator(prec::Level Level)
ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr, SourceLocation RPLoc)
The result type of a method or function.
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion...
const clang::PrintingPolicy & getPrintingPolicy() const
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
ExprResult ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
__builtin_convertvector(...)
ASTContext & getASTContext() const
Scope * getCurScope() const
ExprResult ActOnCharacterConstant(const Token &Tok, Scope *UDLScope=nullptr)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
ExprResult ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, IdentifierInfo &propertyName, SourceLocation receiverNameLoc, SourceLocation propertyNameLoc)
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, unsigned TypeQuals, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation ConstQualifierLoc, SourceLocation VolatileQualifierLoc, SourceLocation RestrictQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceLocation ESpecLoc, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult())
bool isFileContext() const
bool is(tok::TokenKind K) const
bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, ParsedType ObjectType, SourceLocation &TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc)
SourceLocation getOpenLocation() const
ExprResult ActOnBuiltinOffsetOf(Scope *S, SourceLocation BuiltinLoc, SourceLocation TypeLoc, ParsedType ParsedArgTy, OffsetOfComponent *CompPtr, unsigned NumComponents, SourceLocation RParenLoc)
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input)
ExprResult ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
__builtin_astype(...)
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
ExprResult ParseConstraintExpression()
Parse a constraint-expression.
bool isSimpleTypeSpecifier(tok::TokenKind Kind) const
Determine whether the token kind starts a simple-type-specifier.
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind)
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
ExprResult ActOnConstantExpression(ExprResult Res)
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
bool isInObjcMethodScope() const
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
bool isFunctionType() const
void * getAsOpaquePtr() const
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
This is a scope that can contain a declaration. Some scopes just contain loop constructs but don't co...
ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, std::unique_ptr< CorrectionCandidateCallback > CCC=nullptr, bool IsInlineAsmIdentifier=false, Token *KeywordReplacement=nullptr)
static ParsedType getTypeAnnotation(Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
ExprResult ParseConstantExpression(TypeCastState isTypeCast=NotTypeCast)
bool hasRevertedTokenIDToIdentifier() const
True if RevertTokenIDToIdentifier() was called.
Captures information about "declaration specifiers".
SourceLocation ConsumeToken()
void CodeCompletePostfixExpression(Scope *S, ExprResult LHS)
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult{return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
bool TryAnnotateTypeOrScopeToken(bool EnteringContext=false, bool NeedType=false)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
static Decl::Kind getKind(const Decl *D)
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7)...
ExprResult ActOnStringLiteral(ArrayRef< Token > StringToks, Scope *UDLScope=nullptr)
A trivial tuple used to represent a source range.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
ExprResult ActOnSizeofParameterPackExpr(Scope *S, SourceLocation OpLoc, IdentifierInfo &Name, SourceLocation NameLoc, SourceLocation RParenLoc)
Called when an expression computing the size of a parameter pack is parsed.
SourceLocation ColonLoc
Location of ':'.
This class handles loading and caching of source files into memory.
Code completion occurs in a parenthesized expression, which might also be a type cast.
ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, LabelDecl *TheDecl)
ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope)
Stop skipping at specified token, but don't skip the token itself.
IdentifierInfo * getIdentifierInfo() const