summaryrefslogtreecommitdiff
path: root/lib/Parse/ParseExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParseExpr.cpp')
-rw-r--r--lib/Parse/ParseExpr.cpp148
1 files changed, 79 insertions, 69 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 4a0e1c5e34130..2a65eec8a0f63 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -441,7 +441,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
// is okay, to bind exactly as tightly. For example, compile A=B=C=D as
// A=(B=(C=D)), where each paren is a level of recursion here.
// The function takes ownership of the RHS.
- RHS = ParseRHSOfBinaryExpression(RHS,
+ RHS = ParseRHSOfBinaryExpression(RHS,
static_cast<prec::Level>(ThisPrec + !isRightAssoc));
RHSIsInitList = false;
@@ -656,14 +656,14 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {
///
/// id-expression: [C++ 5.1]
/// unqualified-id
-/// qualified-id
+/// qualified-id
///
/// unqualified-id: [C++ 5.1]
/// identifier
/// operator-function-id
/// conversion-function-id
-/// '~' class-name
-/// template-id
+/// '~' class-name
+/// template-id
///
/// new-expression: [C++ 5.3.4]
/// '::'[opt] 'new' new-placement[opt] new-type-id
@@ -729,7 +729,7 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {
/// '__trivially_copyable'
///
/// binary-type-trait:
-/// [GNU] '__is_base_of'
+/// [GNU] '__is_base_of'
/// [MS] '__is_convertible_to'
/// '__is_convertible'
/// '__is_same'
@@ -789,6 +789,10 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
// We have parsed the cast-expression and no postfix-expr pieces are
// following.
return Res;
+ case FoldExpr:
+ // We only parsed a fold-expression. There might be postfix-expr pieces
+ // afterwards; parse them now.
+ break;
}
break;
@@ -807,7 +811,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::kw_false:
Res = ParseCXXBoolLiteral();
break;
-
+
case tok::kw___objc_yes:
case tok::kw___objc_no:
return ParseObjCBoolLiteral();
@@ -831,7 +835,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
return ExprError();
assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super));
return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
-
+
case tok::identifier: { // primary-expression: identifier
// unqualified-id: identifier
// constant: enumeration-constant
@@ -953,14 +957,14 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
return ExprError();
}
// Allow either an identifier or the keyword 'class' (in C++).
- if (Tok.isNot(tok::identifier) &&
+ if (Tok.isNot(tok::identifier) &&
!(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) {
Diag(Tok, diag::err_expected_property_name);
return ExprError();
}
IdentifierInfo &PropertyName = *Tok.getIdentifierInfo();
SourceLocation PropertyLoc = ConsumeToken();
-
+
Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName,
ILoc, PropertyLoc);
break;
@@ -969,7 +973,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
// In an Objective-C method, if we have "super" followed by an identifier,
// the token sequence is ill-formed. However, if there's a ':' or ']' after
// that identifier, this is probably a message send with a missing open
- // bracket. Treat it as such.
+ // bracket. Treat it as such.
if (getLangOpts().ObjC1 && &II == Ident_super && !InMessageExpression &&
getCurScope()->isInObjcMethodScope() &&
((Tok.is(tok::identifier) &&
@@ -979,17 +983,17 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
nullptr);
break;
}
-
+
// If we have an Objective-C class name followed by an identifier
// and either ':' or ']', this is an Objective-C class message
// send that's missing the opening '['. Recovery
// appropriately. Also take this path if we're performing code
// completion after an Objective-C class name.
- if (getLangOpts().ObjC1 &&
- ((Tok.is(tok::identifier) && !InMessageExpression) ||
+ if (getLangOpts().ObjC1 &&
+ ((Tok.is(tok::identifier) && !InMessageExpression) ||
Tok.is(tok::code_completion))) {
const Token& Next = NextToken();
- if (Tok.is(tok::code_completion) ||
+ if (Tok.is(tok::code_completion) ||
Next.is(tok::colon) || Next.is(tok::r_square))
if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope()))
if (Typ.get()->isObjCObjectOrInterfaceType()) {
@@ -1001,24 +1005,24 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
unsigned DiagID;
DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ,
Actions.getASTContext().getPrintingPolicy());
-
+
Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
- TypeResult Ty = Actions.ActOnTypeName(getCurScope(),
+ TypeResult Ty = Actions.ActOnTypeName(getCurScope(),
DeclaratorInfo);
if (Ty.isInvalid())
break;
- Res = ParseObjCMessageExpressionBody(SourceLocation(),
- SourceLocation(),
+ Res = ParseObjCMessageExpressionBody(SourceLocation(),
+ SourceLocation(),
Ty.get(), nullptr);
break;
}
}
-
+
// Make sure to pass down the right value for isAddressOfOperand.
if (isAddressOfOperand && isPostfixExpressionSuffixStart())
isAddressOfOperand = false;
-
+
// Function designators are allowed to be undeclared (C99 6.5.1p2), so we
// need to know whether or not this identifier is a function designator or
// not.
@@ -1175,7 +1179,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
if (getCurScope()->getFnParent() == nullptr)
return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn));
-
+
Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
Tok.getLocation());
@@ -1380,7 +1384,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
T.consumeClose();
if (!Result.isInvalid())
- Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(),
+ Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(),
Result.get(), T.getCloseLocation());
return Result;
}
@@ -1389,7 +1393,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::kw_##Spelling:
#include "clang/Basic/TokenKinds.def"
return ParseTypeTrait();
-
+
case tok::kw___array_rank:
case tok::kw___array_extent:
return ParseArrayTypeTrait();
@@ -1397,7 +1401,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::kw___is_lvalue_expr:
case tok::kw___is_rvalue_expr:
return ParseExpressionTrait();
-
+
case tok::at: {
SourceLocation AtLoc = ConsumeToken();
return ParseObjCAtExpression(AtLoc);
@@ -1485,16 +1489,16 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
case tok::code_completion:
if (InMessageExpression)
return LHS;
-
+
Actions.CodeCompletePostfixExpression(getCurScope(), LHS);
cutOffParsing();
return ExprError();
-
+
case tok::identifier:
// If we see identifier: after an expression, and we're not already in a
// message send, then this is probably a message send with a missing
// opening bracket '['.
- if (getLangOpts().ObjC1 && !InMessageExpression &&
+ if (getLangOpts().ObjC1 && !InMessageExpression &&
(NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
nullptr, LHS.get());
@@ -1616,8 +1620,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
if (!LHS.isInvalid()) {
ExprResult ECResult = Actions.ActOnCUDAExecConfigExpr(getCurScope(),
- OpenLoc,
- ExecConfigExprs,
+ OpenLoc,
+ ExecConfigExprs,
CloseLoc);
if (ECResult.isInvalid())
LHS = ExprError();
@@ -1631,7 +1635,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
ExprVector ArgExprs;
CommaLocsTy CommaLocs;
-
+
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteCall(getCurScope(), LHS.get(), None);
cutOffParsing();
@@ -1671,7 +1675,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
PT.consumeClose();
LHS = ExprError();
} else {
- assert((ArgExprs.size() == 0 ||
+ assert((ArgExprs.size() == 0 ||
ArgExprs.size()-1 == CommaLocs.size())&&
"Unexpected number of commas!");
LHS = Actions.ActOnCallExpr(getCurScope(), LHS.get(), Loc,
@@ -1712,7 +1716,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
if (LHS.isInvalid())
break;
- ParseOptionalCXXScopeSpecifier(SS, ObjectType,
+ ParseOptionalCXXScopeSpecifier(SS, ObjectType,
/*EnteringContext=*/false,
&MayBePseudoDestructor);
if (SS.isNotEmpty())
@@ -1745,7 +1749,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
}
if (MayBePseudoDestructor && !LHS.isInvalid()) {
- LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS,
+ LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS,
ObjectType);
break;
}
@@ -1766,24 +1770,24 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
// 'class' as if it were an identifier.
//
// This hack allows property access to the 'class' method because it is
- // such a common method name. For other C++ keywords that are
+ // such a common method name. For other C++ keywords that are
// Objective-C method names, one must use the message send syntax.
IdentifierInfo *Id = Tok.getIdentifierInfo();
SourceLocation Loc = ConsumeToken();
Name.setIdentifier(Id, Loc);
- } else if (ParseUnqualifiedId(SS,
- /*EnteringContext=*/false,
+ } else if (ParseUnqualifiedId(SS,
+ /*EnteringContext=*/false,
/*AllowDestructorName=*/true,
/*AllowConstructorName=*/
- getLangOpts().MicrosoftExt,
+ getLangOpts().MicrosoftExt,
/*AllowDeductionGuide=*/false,
ObjectType, &TemplateKWLoc, Name)) {
(void)Actions.CorrectDelayedTyposInExpr(LHS);
LHS = ExprError();
}
-
+
if (!LHS.isInvalid())
- LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc,
+ LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc,
OpKind, SS, TemplateKWLoc, Name,
CurParsedObjCImpl ? CurParsedObjCImpl->Dcl
: nullptr);
@@ -1878,7 +1882,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
ParenParseOption ExprType = CastExpr;
SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
- Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/,
+ Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/,
false, CastTy, RParenLoc);
CastRange = SourceRange(LParenLoc, RParenLoc);
@@ -1892,7 +1896,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
if (getLangOpts().CPlusPlus || OpTok.isNot(tok::kw_typeof)) {
// GNU typeof in C requires the expression to be parenthesized. Not so for
// sizeof/alignof or in C++. Therefore, the parenthesized expression is
- // the start of a unary-expression, but doesn't include any postfix
+ // the start of a unary-expression, but doesn't include any postfix
// pieces. Parse these now if present.
if (!Operand.isInvalid())
Operand = ParsePostfixExpressionSuffix(Operand.get());
@@ -1958,7 +1962,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
} else {
Diag(Tok, diag::err_sizeof_parameter_pack);
}
-
+
if (!Name)
return ExprError();
@@ -1967,7 +1971,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
Sema::ReuseLambdaContextDecl);
return Actions.ActOnSizeofParameterPackExpr(getCurScope(),
- OpTok.getLocation(),
+ OpTok.getLocation(),
*Name, NameLoc,
RParenLoc);
}
@@ -2202,15 +2206,15 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
TypeResult DestTy = ParseTypeName();
if (DestTy.isInvalid())
return ExprError();
-
+
// Attempt to consume the r-paren.
if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected) << tok::r_paren;
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
-
- Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc,
+
+ Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc,
ConsumeParen());
break;
}
@@ -2231,15 +2235,15 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
TypeResult DestTy = ParseTypeName();
if (DestTy.isInvalid())
return ExprError();
-
+
// Attempt to consume the r-paren.
if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected) << tok::r_paren;
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
-
- Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc,
+
+ Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc,
ConsumeParen());
break;
}
@@ -2294,7 +2298,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
CastTy = nullptr;
if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteOrdinaryName(getCurScope(),
+ Actions.CodeCompleteOrdinaryName(getCurScope(),
ExprType >= CompoundLiteral? Sema::PCC_ParenthesizedExpression
: Sema::PCC_Expression);
cutOffParsing();
@@ -2318,7 +2322,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
}
BridgeCast = false;
}
-
+
// None of these cases should fall through with an invalid Result
// unless they've already reported an error.
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
@@ -2372,16 +2376,16 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
<< FixItHint::CreateReplacement(BridgeKeywordLoc,
"__bridge_retained");
}
-
+
TypeResult Ty = ParseTypeName();
T.consumeClose();
ColonProtection.restore();
RParenLoc = T.getCloseLocation();
ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false);
-
+
if (Ty.isInvalid() || SubExpr.isInvalid())
return ExprError();
-
+
return Actions.ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind,
BridgeKeywordLoc, Ty.get(),
RParenLoc, SubExpr.get());
@@ -2407,8 +2411,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
ParseSpecifierQualifierList(DS);
Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
ParseDeclarator(DeclaratorInfo);
-
- // If our type is followed by an identifier and either ':' or ']', then
+
+ // If our type is followed by an identifier and either ':' or ']', then
// this is probably an Objective-C message send where the leading '[' is
// missing. Recover as if that were the case.
if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) &&
@@ -2419,10 +2423,10 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
InMessageExpressionRAIIObject InMessage(*this, false);
Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
}
- Result = ParseObjCMessageExpressionBody(SourceLocation(),
- SourceLocation(),
+ Result = ParseObjCMessageExpressionBody(SourceLocation(),
+ SourceLocation(),
Ty.get(), nullptr);
- } else {
+ } else {
// Match the ')'.
T.consumeClose();
ColonProtection.restore();
@@ -2499,7 +2503,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// Reject the cast of super idiom in ObjC.
if (Tok.is(tok::identifier) && getLangOpts().ObjC1 &&
- Tok.getIdentifierInfo() == Ident_super &&
+ Tok.getIdentifierInfo() == Ident_super &&
getCurScope()->isInObjcMethodScope() &&
GetLookAheadToken(1).isNot(tok::period)) {
Diag(Tok.getLocation(), diag::err_illegal_super_cast)
@@ -2514,7 +2518,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
/*isTypeCast=*/IsTypeCast);
if (!Result.isInvalid()) {
Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
- DeclaratorInfo, CastTy,
+ DeclaratorInfo, CastTy,
RParenLoc, Result.get());
}
return Result;
@@ -2523,8 +2527,9 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
return ExprError();
}
- } else if (Tok.is(tok::ellipsis) &&
+ } else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) &&
isFoldOperator(NextToken().getKind())) {
+ ExprType = FoldExpr;
return ParseFoldExpression(ExprResult(), T);
} else if (isTypeCast) {
// Parse the expression-list.
@@ -2536,9 +2541,11 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
if (!ParseSimpleExpressionList(ArgExprs, CommaLocs)) {
// FIXME: If we ever support comma expressions as operands to
// fold-expressions, we'll need to allow multiple ArgExprs here.
- if (ArgExprs.size() == 1 && isFoldOperator(Tok.getKind()) &&
- NextToken().is(tok::ellipsis))
+ if (ExprType >= FoldExpr && ArgExprs.size() == 1 &&
+ isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) {
+ ExprType = FoldExpr;
return ParseFoldExpression(ArgExprs[0], T);
+ }
ExprType = SimpleExpr;
Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),
@@ -2553,10 +2560,13 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// expressions are parsed correctly.
Result = Actions.CorrectDelayedTyposInExpr(Result);
}
- ExprType = SimpleExpr;
- if (isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis))
+ if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) &&
+ NextToken().is(tok::ellipsis)) {
+ ExprType = FoldExpr;
return ParseFoldExpression(Result, T);
+ }
+ ExprType = SimpleExpr;
// Don't build a paren expression unless we actually match a ')'.
if (!Result.isInvalid() && Tok.is(tok::r_paren))
@@ -2712,7 +2722,7 @@ ExprResult Parser::ParseGenericSelectionExpression() {
if (T.getCloseLocation().isInvalid())
return ExprError();
- return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc,
+ return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc,
T.getCloseLocation(),
ControllingExpr.get(),
Types, Exprs);
@@ -2815,7 +2825,7 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
Expr = ParseAssignmentExpression();
if (Tok.is(tok::ellipsis))
- Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());
+ Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());
if (Expr.isInvalid()) {
SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch);
SawError = true;
@@ -2882,7 +2892,7 @@ void Parser::ParseBlockId(SourceLocation CaretLoc) {
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type);
return cutOffParsing();
}
-
+
// Parse the specifier-qualifier-list piece.
DeclSpec DS(AttrFactory);
ParseSpecifierQualifierList(DS);