summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-22 23:10:45 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-22 23:10:45 +0000
commitf68a50858675856c0fe474b81e7bf3229a00ea0e (patch)
treee58ca0b209ced58890b6943d6acb8ee85a569eef /clang/lib
parent4ba01ec869a82800490747646b8b02cab203484f (diff)
downloadbcm5719-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.cpp9
-rw-r--r--clang/lib/Sema/TreeTransform.h50
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));
}
OpenPOWER on IntegriCloud