diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-07-01 22:22:59 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-07-01 22:22:59 +0000 |
commit | 0a85183be6930571f3af8e5a976d24c3f95e5b25 (patch) | |
tree | 83072ae87cdf8bb2a24b8f4ab6861f502d05d711 /lib/Parse/ParseExpr.cpp | |
parent | 707f101d3302b76ee01e8ca29b1a61f081137b9f (diff) |
[ARC] When casting from a pointer to an objective-c object with known ownership, if the
cast type has no ownership specified, implicitly "transfer" the ownership of the cast'ed type
to the cast type:
id x;
(NSString**)&x; // Casting as (__strong NSString**).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134275 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseExpr.cpp')
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 77 |
1 files changed, 47 insertions, 30 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index bd723f0325..5e8bb53b2d 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); } @@ -415,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); @@ -589,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; @@ -620,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) { @@ -952,7 +952,7 @@ 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)) { @@ -965,7 +965,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false); AnnotateTemplateIdTokenAsType(); return ParseCastExpression(isUnaryExpression, isAddressOfOperand, - NotCastExpr, TypeOfCast); + NotCastExpr, isTypeCast); } } @@ -982,7 +982,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, // expression. AnnotateTemplateIdTokenAsType(); return ParseCastExpression(isUnaryExpression, isAddressOfOperand, - NotCastExpr, TypeOfCast); + NotCastExpr, isTypeCast); } // Fall through to treat the template-id as an id-expression. @@ -1105,7 +1105,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, 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) @@ -1422,7 +1422,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 @@ -1746,7 +1746,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { /// (__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); @@ -1804,7 +1804,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, TypeResult Ty = ParseTypeName(); SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, OpenLoc); - ExprResult SubExpr = ParseCastExpression(false, false, ParsedType()); + ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false); if (Ty.isInvalid() || SubExpr.isInvalid()) return ExprError(); @@ -1826,20 +1826,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); @@ -1852,21 +1855,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 && @@ -1880,17 +1893,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); |