]> granicus.if.org Git - clang/commitdiff
Template instantiation for @try and @finally (but not @catch, yet).
authorDouglas Gregor <dgregor@apple.com>
Thu, 22 Apr 2010 23:59:56 +0000 (23:59 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 22 Apr 2010 23:59:56 +0000 (23:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102147 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/TreeTransform.h
test/SemaObjCXX/instantiate-stmt.mm

index 7bcfeb1006350811630f4da2b7919ad0cdd54944..a41cbc38a292005eb0954b30aadfca3bd0acaaf6 100644 (file)
@@ -889,6 +889,27 @@ public:
                                   move(Exprs), move(AsmString), move(Clobbers),
                                   RParenLoc, MSAsm);
   }
+
+  /// \brief Build a new Objective-C @try statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
+                                        StmtArg TryBody,
+                                        StmtArg Catch,
+                                        StmtArg Finally) {
+    return getSema().ActOnObjCAtTryStmt(AtLoc, move(TryBody), move(Catch),
+                                        move(Finally));
+  }
+
+  /// \brief Build a new Objective-C @finally statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
+                                            StmtArg Body) {
+    return getSema().ActOnObjCAtFinallyStmt(AtLoc, move(Body));
+  }
   
   /// \brief Build a new Objective-C @throw statement.
   ///
@@ -3662,9 +3683,37 @@ TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
 template<typename Derived>
 Sema::OwningStmtResult
 TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
-  // FIXME: Implement this
-  assert(false && "Cannot transform an Objective-C @try statement");
-  return SemaRef.Owned(S->Retain());
+  // Transform the body of the @try.
+  OwningStmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
+  if (TryBody.isInvalid())
+    return SemaRef.StmtError();
+  
+  // Transform the @catch statement (if present).
+  OwningStmtResult Catch(SemaRef);
+  if (S->getCatchStmts()) {
+    Catch = getDerived().TransformStmt(S->getCatchStmts());
+    if (Catch.isInvalid())
+      return SemaRef.StmtError();
+  }
+  
+  // Transform the @finally statement (if present).
+  OwningStmtResult Finally(SemaRef);
+  if (S->getFinallyStmt()) {
+    Finally = getDerived().TransformStmt(S->getFinallyStmt());
+    if (Finally.isInvalid())
+      return SemaRef.StmtError();
+  }
+
+  // If nothing changed, just retain this statement.
+  if (!getDerived().AlwaysRebuild() &&
+      TryBody.get() == S->getTryBody() &&
+      Catch.get() == S->getCatchStmts() &&
+      Finally.get() == S->getFinallyStmt())
+    return SemaRef.Owned(S->Retain());
+  
+  // Build a new statement.
+  return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), move(TryBody),
+                                           move(Catch), move(Finally));
 }
 
 template<typename Derived>
@@ -3678,9 +3727,19 @@ TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
 template<typename Derived>
 Sema::OwningStmtResult
 TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
-  // FIXME: Implement this
-  assert(false && "Cannot transform an Objective-C @finally statement");
-  return SemaRef.Owned(S->Retain());
+  // Transform the body.
+  OwningStmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
+  if (Body.isInvalid())
+    return SemaRef.StmtError();
+  
+  // If nothing changed, just retain this statement.
+  if (!getDerived().AlwaysRebuild() &&
+      Body.get() == S->getFinallyBody())
+    return SemaRef.Owned(S->Retain());
+
+  // Build a new statement.
+  return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
+                                               move(Body));
 }
 
 template<typename Derived>
index 5e9abecc6dde8bff5f1fe480c9b240402fa1dd69..5e14a99b9bdb827c9ccbe300c5fd5b37182363eb 100644 (file)
@@ -57,3 +57,19 @@ void fast_enumeration_test(T collection) {
 template void fast_enumeration_test<NSString *>(NSArray*);
 template void fast_enumeration_test<int>(NSArray*); // expected-note{{in instantiation of}}
 template void fast_enumeration_test<NSString *>(vector); // expected-note{{in instantiation of}}
+
+// @try/@catch/@finally
+
+template<typename T, typename U>
+void try_catch_finally_test(U value) {
+  @try {
+    value = 1; // expected-error{{assigning to 'int *' from incompatible type 'int'}}
+  }
+  // FIXME: Add @catch
+  @finally {
+    value = 0;
+  }
+}
+
+template void try_catch_finally_test<NSString *>(int);
+template void try_catch_finally_test<NSString *>(int*); // expected-note{{in instantiation of}}