diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-04-22 23:10:45 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-04-22 23:10:45 +0000 |
| commit | f68a50858675856c0fe474b81e7bf3229a00ea0e (patch) | |
| tree | e58ca0b209ced58890b6943d6acb8ee85a569eef /clang/lib | |
| parent | 4ba01ec869a82800490747646b8b02cab203484f (diff) | |
| download | bcm5719-llvm-f68a50858675856c0fe474b81e7bf3229a00ea0e.tar.gz bcm5719-llvm-f68a50858675856c0fe474b81e7bf3229a00ea0e.zip | |
Template instantiation for the Objective-C "fast enumeration"
statement, i.e.,
for (element in collection) {
// do something
}
llvm-svn: 102138
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 9 | ||||
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 50 |
2 files changed, 52 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index c7bb3c827c0..9c7affdb968 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -988,19 +988,22 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, return StmtError(Diag(VD->getLocation(), diag::err_non_variable_decl_in_for)); } else { - if (cast<Expr>(First)->isLvalue(Context) != Expr::LV_Valid) + Expr *FirstE = cast<Expr>(First); + if (!FirstE->isTypeDependent() && + FirstE->isLvalue(Context) != Expr::LV_Valid) return StmtError(Diag(First->getLocStart(), diag::err_selector_element_not_lvalue) << First->getSourceRange()); FirstType = static_cast<Expr*>(First)->getType(); } - if (!FirstType->isObjCObjectPointerType() && + if (!FirstType->isDependentType() && + !FirstType->isObjCObjectPointerType() && !FirstType->isBlockPointerType()) Diag(ForLoc, diag::err_selector_element_type) << FirstType << First->getSourceRange(); } - if (Second) { + if (Second && !Second->isTypeDependent()) { DefaultFunctionArrayLvalueConversion(Second); QualType SecondType = Second->getType(); if (!SecondType->isObjCObjectPointerType()) diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 9d7f936bd72..7bcfeb10063 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -901,7 +901,6 @@ public: /// \brief Build a new Objective-C @synchronized statement. /// - /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. OwningStmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc, @@ -910,6 +909,23 @@ public: return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, move(Object), move(Body)); } + + /// \brief Build a new Objective-C fast enumeration statement. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + OwningStmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc, + SourceLocation LParenLoc, + StmtArg Element, + ExprArg Collection, + SourceLocation RParenLoc, + StmtArg Body) { + return getSema().ActOnObjCForCollectionStmt(ForLoc, LParenLoc, + move(Element), + move(Collection), + RParenLoc, + move(Body)); + } /// \brief Build a new C++ exception declaration. /// @@ -3713,9 +3729,35 @@ template<typename Derived> Sema::OwningStmtResult TreeTransform<Derived>::TransformObjCForCollectionStmt( ObjCForCollectionStmt *S) { - // FIXME: Implement this - assert(false && "Cannot transform an Objective-C for-each statement"); - return SemaRef.Owned(S->Retain()); + // Transform the element statement. + OwningStmtResult Element = getDerived().TransformStmt(S->getElement()); + if (Element.isInvalid()) + return SemaRef.StmtError(); + + // Transform the collection expression. + OwningExprResult Collection = getDerived().TransformExpr(S->getCollection()); + if (Collection.isInvalid()) + return SemaRef.StmtError(); + + // Transform the body. + OwningStmtResult Body = getDerived().TransformStmt(S->getBody()); + if (Body.isInvalid()) + return SemaRef.StmtError(); + + // If nothing changed, just retain this statement. + if (!getDerived().AlwaysRebuild() && + Element.get() == S->getElement() && + Collection.get() == S->getCollection() && + Body.get() == S->getBody()) + return SemaRef.Owned(S->Retain()); + + // Build a new statement. + return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(), + /*FIXME:*/S->getForLoc(), + move(Element), + move(Collection), + S->getRParenLoc(), + move(Body)); } |

