summaryrefslogtreecommitdiffstats
path: root/lib/Parse/ParseExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParseExpr.cpp')
-rw-r--r--lib/Parse/ParseExpr.cpp156
1 files changed, 108 insertions, 48 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 4e94ed9..fc64ae0 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -220,7 +220,7 @@ ExprResult Parser::ParseAssignmentExpression() {
if (Tok.is(tok::kw_throw))
return ParseThrowExpression();
- ExprResult LHS = ParseCastExpression(false, false, ParsedType());
+ ExprResult LHS = ParseCastExpression(/*isUnaryExpression=*/false);
return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment);
}
@@ -304,13 +304,14 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
ColonLoc = ConsumeToken();
} else {
// Otherwise, we're missing a ':'. Assume that this was a typo that the
- // user forgot. If we're not in a macro instantion, we can suggest a
+ // user forgot. If we're not in a macro instantiation, we can suggest a
// fixit hint. If there were two spaces before the current token,
// suggest inserting the colon in between them, otherwise insert ": ".
SourceLocation FILoc = Tok.getLocation();
const char *FIText = ": ";
- if (FILoc.isFileID()) {
- const SourceManager &SM = PP.getSourceManager();
+ const SourceManager &SM = PP.getSourceManager();
+ if (FILoc.isFileID() || PP.isAtStartOfMacroExpansion(FILoc)) {
+ FILoc = SM.getInstantiationLoc(FILoc);
bool IsInvalid = false;
const char *SourcePtr =
SM.getCharacterData(FILoc.getFileLocWithOffset(-1), &IsInvalid);
@@ -414,12 +415,12 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
///
ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
bool isAddressOfOperand,
- ParsedType TypeOfCast) {
+ bool isTypeCast) {
bool NotCastExpr;
ExprResult Res = ParseCastExpression(isUnaryExpression,
isAddressOfOperand,
NotCastExpr,
- TypeOfCast);
+ isTypeCast);
if (NotCastExpr)
Diag(Tok, diag::err_expected_expression);
return move(Res);
@@ -588,7 +589,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
bool isAddressOfOperand,
bool &NotCastExpr,
- ParsedType TypeOfCast) {
+ bool isTypeCast) {
ExprResult Res;
tok::TokenKind SavedKind = Tok.getKind();
NotCastExpr = false;
@@ -619,7 +620,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
ColonProtectionRAIIObject X(*this, false);
Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/,
- TypeOfCast, CastTy, RParenLoc);
+ isTypeCast, CastTy, RParenLoc);
}
switch (ParenExprType) {
@@ -791,7 +792,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
return ParseBuiltinPrimaryExpression();
case tok::kw___null:
return Actions.ActOnGNUNullExpr(ConsumeToken());
- break;
+
case tok::plusplus: // unary-expression: '++' unary-expression [C99]
case tok::minusminus: { // unary-expression: '--' unary-expression [C99]
// C++ [expr.unary] has:
@@ -951,12 +952,11 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
return ExprError();
if (!Tok.is(tok::annot_cxxscope))
return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
- NotCastExpr, TypeOfCast);
+ NotCastExpr, isTypeCast);
Token Next = NextToken();
if (Next.is(tok::annot_template_id)) {
- TemplateIdAnnotation *TemplateId
- = static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue());
+ TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
if (TemplateId->Kind == TNK_Type_template) {
// We have a qualified template-id that we know refers to a
// type, translate it into a type and continue parsing as a
@@ -965,7 +965,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
AnnotateTemplateIdTokenAsType();
return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
- NotCastExpr, TypeOfCast);
+ NotCastExpr, isTypeCast);
}
}
@@ -975,15 +975,14 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
}
case tok::annot_template_id: { // [C++] template-id
- TemplateIdAnnotation *TemplateId
- = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+ TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
if (TemplateId->Kind == TNK_Type_template) {
// We have a template-id that we know refers to a type,
// translate it into a type and continue parsing as a cast
// expression.
AnnotateTemplateIdTokenAsType();
return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
- NotCastExpr, TypeOfCast);
+ NotCastExpr, isTypeCast);
}
// Fall through to treat the template-id as an id-expression.
@@ -1101,17 +1100,20 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
return ParseObjCAtExpression(AtLoc);
}
case tok::caret:
- return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression());
- case tok::code_completion:
+ Res = ParseBlockLiteralExpression();
+ break;
+ case tok::code_completion: {
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
ConsumeCodeCompletionToken();
return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
- NotCastExpr, TypeOfCast);
+ NotCastExpr, isTypeCast);
+ }
case tok::l_square:
- // These can be followed by postfix-expr pieces.
- if (getLang().ObjC1)
- return ParsePostfixExpressionSuffix(ParseObjCMessageExpression());
- // FALL THROUGH.
+ if (getLang().ObjC1) {
+ Res = ParseObjCMessageExpression();
+ break;
+ }
+ // FALL THROUGH.
default:
NotCastExpr = true;
return ExprError();
@@ -1261,7 +1263,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
if (Tok.isNot(tok::r_paren)) {
if (ParseExpressionList(ArgExprs, CommaLocs, &Sema::CodeCompleteCall,
LHS.get())) {
- SkipUntil(tok::r_paren);
LHS = ExprError();
}
}
@@ -1424,7 +1425,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
EnterExpressionEvaluationContext Unevaluated(Actions,
Sema::Unevaluated);
Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/,
- ParsedType(), CastTy, RParenLoc);
+ false, CastTy, RParenLoc);
CastRange = SourceRange(LParenLoc, RParenLoc);
// If ParseParenExpression parsed a '(typename)' sequence only, then this is
@@ -1717,7 +1718,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
ConsumeParen());
break;
}
-}
+ }
if (Res.isInvalid())
return ExprError();
@@ -1740,10 +1741,15 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
/// '(' type-name ')' '{' initializer-list ',' '}'
/// cast-expression: [C99 6.5.4]
/// '(' type-name ')' cast-expression
-///
+/// [ARC] bridged-cast-expression
+///
+/// [ARC] bridged-cast-expression:
+/// (__bridge type-name) cast-expression
+/// (__bridge_transfer type-name) cast-expression
+/// (__bridge_retained type-name) cast-expression
ExprResult
Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
- ParsedType TypeOfCast, ParsedType &CastTy,
+ bool isTypeCast, ParsedType &CastTy,
SourceLocation &RParenLoc) {
assert(Tok.is(tok::l_paren) && "Not a paren expr!");
GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
@@ -1772,7 +1778,43 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// If the substmt parsed correctly, build the AST node.
if (!Stmt.isInvalid())
Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.take(), Tok.getLocation());
-
+ } else if (ExprType >= CompoundLiteral &&
+ (Tok.is(tok::kw___bridge) ||
+ Tok.is(tok::kw___bridge_transfer) ||
+ Tok.is(tok::kw___bridge_retained) ||
+ Tok.is(tok::kw___bridge_retain))) {
+ tok::TokenKind tokenKind = Tok.getKind();
+ SourceLocation BridgeKeywordLoc = ConsumeToken();
+
+ // Parse an Objective-C ARC ownership cast expression.
+ ObjCBridgeCastKind Kind;
+ if (tokenKind == tok::kw___bridge)
+ Kind = OBC_Bridge;
+ else if (tokenKind == tok::kw___bridge_transfer)
+ Kind = OBC_BridgeTransfer;
+ else if (tokenKind == tok::kw___bridge_retained)
+ Kind = OBC_BridgeRetained;
+ else {
+ // As a hopefully temporary workaround, allow __bridge_retain as
+ // a synonym for __bridge_retained, but only in system headers.
+ assert(tokenKind == tok::kw___bridge_retain);
+ Kind = OBC_BridgeRetained;
+ if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
+ Diag(BridgeKeywordLoc, diag::err_arc_bridge_retain)
+ << FixItHint::CreateReplacement(BridgeKeywordLoc,
+ "__bridge_retained");
+ }
+
+ TypeResult Ty = ParseTypeName();
+ SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, OpenLoc);
+ ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false);
+
+ if (Ty.isInvalid() || SubExpr.isInvalid())
+ return ExprError();
+
+ return Actions.ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind,
+ BridgeKeywordLoc, Ty.get(),
+ RParenLoc, SubExpr.get());
} else if (ExprType >= CompoundLiteral &&
isTypeIdInParens(isAmbiguousTypeId)) {
@@ -1787,20 +1829,23 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
return ParseCXXAmbiguousParenExpression(ExprType, CastTy,
OpenLoc, RParenLoc);
- TypeResult Ty;
-
- {
- InMessageExpressionRAIIObject InMessage(*this, false);
- Ty = ParseTypeName();
- }
+ // Parse the type declarator.
+ DeclSpec DS(AttrFactory);
+ ParseSpecifierQualifierList(DS);
+ Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+ ParseDeclarator(DeclaratorInfo);
// 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 (!Ty.isInvalid() && Tok.is(tok::identifier) && !InMessageExpression &&
- getLang().ObjC1 && !Ty.get().get().isNull() &&
- (NextToken().is(tok::colon) || NextToken().is(tok::r_square)) &&
- Ty.get().get()->isObjCObjectOrInterfaceType()) {
+ if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) &&
+ !InMessageExpression && getLang().ObjC1 &&
+ (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
+ TypeResult Ty;
+ {
+ InMessageExpressionRAIIObject InMessage(*this, false);
+ Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
+ }
Result = ParseObjCMessageExpressionBody(SourceLocation(),
SourceLocation(),
Ty.get(), 0);
@@ -1813,21 +1858,31 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
if (Tok.is(tok::l_brace)) {
ExprType = CompoundLiteral;
+ TypeResult Ty;
+ {
+ InMessageExpressionRAIIObject InMessage(*this, false);
+ Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
+ }
return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
}
if (ExprType == CastExpr) {
// We parsed '(' type-name ')' and the thing after it wasn't a '{'.
- if (Ty.isInvalid())
+ if (DeclaratorInfo.isInvalidType())
return ExprError();
- CastTy = Ty.get();
-
// Note that this doesn't parse the subsequent cast-expression, it just
// returns the parsed type to the callee.
- if (stopIfCastExpr)
+ if (stopIfCastExpr) {
+ TypeResult Ty;
+ {
+ InMessageExpressionRAIIObject InMessage(*this, false);
+ Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
+ }
+ CastTy = Ty.get();
return ExprResult();
+ }
// Reject the cast of super idiom in ObjC.
if (Tok.is(tok::identifier) && getLang().ObjC1 &&
@@ -1841,17 +1896,21 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// Parse the cast-expression that follows it next.
// TODO: For cast expression with CastTy.
- Result = ParseCastExpression(false, false, CastTy);
- if (!Result.isInvalid())
- Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, CastTy,
+ Result = ParseCastExpression(/*isUnaryExpression=*/false,
+ /*isAddressOfOperand=*/false,
+ /*isTypeCast=*/true);
+ if (!Result.isInvalid()) {
+ Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
+ DeclaratorInfo, CastTy,
RParenLoc, Result.take());
+ }
return move(Result);
}
Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
return ExprError();
}
- } else if (TypeOfCast) {
+ } else if (isTypeCast) {
// Parse the expression-list.
InMessageExpressionRAIIObject InMessage(*this, false);
@@ -1861,7 +1920,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
if (!ParseExpressionList(ArgExprs, CommaLocs)) {
ExprType = SimpleExpr;
Result = Actions.ActOnParenOrParenListExpr(OpenLoc, Tok.getLocation(),
- move_arg(ArgExprs), TypeOfCast);
+ move_arg(ArgExprs));
}
} else {
InMessageExpressionRAIIObject InMessage(*this, false);
@@ -2174,6 +2233,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
SourceLocation(),
0, 0, 0,
true, SourceLocation(),
+ SourceLocation(),
EST_None,
SourceLocation(),
0, 0, 0, 0,
OpenPOWER on IntegriCloud