diff options
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 62cd0d0d60..31d368043e 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1385,9 +1385,10 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) { } ExprResult -Sema::ActOnObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) { - assert(collection); - +Sema::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) { + if (!collection) + return ExprError(); + // Bail out early if we've got a type-dependent expression. if (collection->isTypeDependent()) return Owned(collection); @@ -1457,8 +1458,12 @@ Sema::ActOnObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) { StmtResult Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, SourceLocation LParenLoc, - Stmt *First, Expr *Second, - SourceLocation RParenLoc, Stmt *Body) { + Stmt *First, Expr *collection, + SourceLocation RParenLoc) { + + ExprResult CollectionExprResult = + CheckObjCForCollectionOperand(ForLoc, collection); + if (First) { QualType FirstType; if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) { @@ -1486,11 +1491,15 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, if (!FirstType->isDependentType() && !FirstType->isObjCObjectPointerType() && !FirstType->isBlockPointerType()) - Diag(ForLoc, diag::err_selector_element_type) - << FirstType << First->getSourceRange(); + return StmtError(Diag(ForLoc, diag::err_selector_element_type) + << FirstType << First->getSourceRange()); } - - return Owned(new (Context) ObjCForCollectionStmt(First, Second, Body, + + if (CollectionExprResult.isInvalid()) + return StmtError(); + + return Owned(new (Context) ObjCForCollectionStmt(First, + CollectionExprResult.take(), 0, ForLoc, RParenLoc)); } @@ -1900,6 +1909,17 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc, ColonLoc, RParenLoc)); } +/// FinishObjCForCollectionStmt - Attach the body to a objective-C foreach +/// statement. +StmtResult Sema::FinishObjCForCollectionStmt(Stmt *S, Stmt *B) { + if (!S || !B) + return StmtError(); + ObjCForCollectionStmt * ForStmt = cast<ObjCForCollectionStmt>(S); + + ForStmt->setBody(B); + return S; +} + /// FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement. /// This is a separate step from ActOnCXXForRangeStmt because analysis of the /// body cannot be performed until after the type of the range variable is |