diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-22 22:01:21 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-22 22:01:21 +0000 |
commit | 8fdc13a78a43f09ac396e682c35d57ca0b48216d (patch) | |
tree | 887f8288dc4624a6c13e46944f60a22564f81871 | |
parent | d1377b25a36adfe6604f78cbd3a23a07cf0f29e6 (diff) |
Template instantiation for Objective-C++ @synchronized statements.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102134 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 36 | ||||
-rw-r--r-- | test/SemaObjCXX/instantiate-stmt.mm | 9 |
3 files changed, 43 insertions, 5 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 4e460f4bf5..c7bb3c827c 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1583,7 +1583,8 @@ Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr, // Make sure the expression type is an ObjC pointer or "void *". Expr *SyncExpr = static_cast<Expr*>(SynchExpr.get()); - if (!SyncExpr->getType()->isObjCObjectPointerType()) { + if (!SyncExpr->getType()->isDependentType() && + !SyncExpr->getType()->isObjCObjectPointerType()) { const PointerType *PT = SyncExpr->getType()->getAs<PointerType>(); if (!PT || !PT->getPointeeType()->isVoidType()) return StmtError(Diag(AtLoc, diag::error_objc_synchronized_expects_object) diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index db44a36ccf..9d7f936bd7 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -890,7 +890,7 @@ public: RParenLoc, MSAsm); } - /// \brief Build a new Objective-C throw statement. + /// \brief Build a new Objective-C @throw statement. /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. @@ -899,6 +899,18 @@ public: return getSema().BuildObjCAtThrowStmt(AtLoc, move(Operand)); } + /// \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, + ExprArg Object, + StmtArg Body) { + return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, move(Object), + move(Body)); + } + /// \brief Build a new C++ exception declaration. /// /// By default, performs semantic analysis to build the new decaration. @@ -3676,9 +3688,25 @@ template<typename Derived> Sema::OwningStmtResult TreeTransform<Derived>::TransformObjCAtSynchronizedStmt( ObjCAtSynchronizedStmt *S) { - // FIXME: Implement this - assert(false && "Cannot transform an Objective-C @synchronized statement"); - return SemaRef.Owned(S->Retain()); + // Transform the object we are locking. + OwningExprResult Object = getDerived().TransformExpr(S->getSynchExpr()); + if (Object.isInvalid()) + return SemaRef.StmtError(); + + // Transform the body. + OwningStmtResult Body = getDerived().TransformStmt(S->getSynchBody()); + if (Body.isInvalid()) + return SemaRef.StmtError(); + + // If nothing change, just retain the current statement. + if (!getDerived().AlwaysRebuild() && + Object.get() == S->getSynchExpr() && + Body.get() == S->getSynchBody()) + return SemaRef.Owned(S->Retain()); + + // Build a new statement. + return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(), + move(Object), move(Body)); } template<typename Derived> diff --git a/test/SemaObjCXX/instantiate-stmt.mm b/test/SemaObjCXX/instantiate-stmt.mm index 4c477aaf6c..3d5c86ff91 100644 --- a/test/SemaObjCXX/instantiate-stmt.mm +++ b/test/SemaObjCXX/instantiate-stmt.mm @@ -12,4 +12,13 @@ void throw_test(T value) { template void throw_test(NSException *); template void throw_test(int); // expected-note{{in instantiation of}} +// @synchronized +template<typename T> +void synchronized_test(T value) { + @synchronized (value) { // expected-error{{@synchronized requires an Objective-C object type ('int' invalid)}} + value = 0; + } +} +template void synchronized_test(NSException *); +template void synchronized_test(int); // expected-note{{in instantiation of}} |