[cfe-commits] r102133 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaStmt.cpp lib/Sema/TreeTransform.h test/SemaObjCXX/instantiate-stmt.mm

Douglas Gregor dgregor at apple.com
Thu Apr 22 14:44:01 PDT 2010


Author: dgregor
Date: Thu Apr 22 16:44:01 2010
New Revision: 102133

URL: http://llvm.org/viewvc/llvm-project?rev=102133&view=rev
Log:
Implement template instantiation for Objective-C++ @throw statements.

Added:
    cfe/trunk/test/SemaObjCXX/instantiate-stmt.mm
Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/lib/Sema/TreeTransform.h

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=102133&r1=102132&r2=102133&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Apr 22 16:44:01 2010
@@ -1687,6 +1687,8 @@
                                               StmtArg Try,
                                               StmtArg Catch, StmtArg Finally);
 
+  virtual OwningStmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc,
+                                                ExprArg Throw);
   virtual OwningStmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
                                                 ExprArg Throw,
                                                 Scope *CurScope);

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=102133&r1=102132&r2=102133&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Apr 22 16:44:01 2010
@@ -1542,10 +1542,28 @@
                                            Finally.takeAs<Stmt>()));
 }
 
+Sema::OwningStmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc,
+                                                  ExprArg ThrowE) {
+  Expr *Throw = static_cast<Expr *>(ThrowE.get());
+  if (Throw) {
+    QualType ThrowType = Throw->getType();
+    // Make sure the expression type is an ObjC pointer or "void *".
+    if (!ThrowType->isDependentType() &&
+        !ThrowType->isObjCObjectPointerType()) {
+      const PointerType *PT = ThrowType->getAs<PointerType>();
+      if (!PT || !PT->getPointeeType()->isVoidType())
+        return StmtError(Diag(AtLoc, diag::error_objc_throw_expects_object)
+                         << Throw->getType() << Throw->getSourceRange());
+    }
+  }
+  
+  return Owned(new (Context) ObjCAtThrowStmt(AtLoc, ThrowE.takeAs<Expr>()));
+}
+
 Action::OwningStmtResult
-Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg expr,Scope *CurScope) {
-  Expr *ThrowExpr = expr.takeAs<Expr>();
-  if (!ThrowExpr) {
+Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg Throw, 
+                           Scope *CurScope) {
+  if (!Throw.get()) {
     // @throw without an expression designates a rethrow (which much occur
     // in the context of an @catch clause).
     Scope *AtCatchParent = CurScope;
@@ -1553,17 +1571,9 @@
       AtCatchParent = AtCatchParent->getParent();
     if (!AtCatchParent)
       return StmtError(Diag(AtLoc, diag::error_rethrow_used_outside_catch));
-  } else {
-    QualType ThrowType = ThrowExpr->getType();
-    // Make sure the expression type is an ObjC pointer or "void *".
-    if (!ThrowType->isObjCObjectPointerType()) {
-      const PointerType *PT = ThrowType->getAs<PointerType>();
-      if (!PT || !PT->getPointeeType()->isVoidType())
-        return StmtError(Diag(AtLoc, diag::error_objc_throw_expects_object)
-                        << ThrowExpr->getType() << ThrowExpr->getSourceRange());
-    }
-  }
-  return Owned(new (Context) ObjCAtThrowStmt(AtLoc, ThrowExpr));
+  } 
+  
+  return BuildObjCAtThrowStmt(AtLoc, move(Throw));
 }
 
 Action::OwningStmtResult

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=102133&r1=102132&r2=102133&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Apr 22 16:44:01 2010
@@ -890,6 +890,15 @@
                                   RParenLoc, MSAsm);
   }
   
+  /// \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.
+  OwningStmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
+                                          ExprArg Operand) {
+    return getSema().BuildObjCAtThrowStmt(AtLoc, move(Operand));
+  }
+  
   /// \brief Build a new C++ exception declaration.
   ///
   /// By default, performs semantic analysis to build the new decaration.
@@ -3649,9 +3658,18 @@
 template<typename Derived>
 Sema::OwningStmtResult
 TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
-  // FIXME: Implement this
-  assert(false && "Cannot transform an Objective-C @throw statement");
-  return SemaRef.Owned(S->Retain());
+  OwningExprResult Operand(SemaRef);
+  if (S->getThrowExpr()) {
+    Operand = getDerived().TransformExpr(S->getThrowExpr());
+    if (Operand.isInvalid())
+      return getSema().StmtError();
+  }
+  
+  if (!getDerived().AlwaysRebuild() &&
+      Operand.get() == S->getThrowExpr())
+    return getSema().Owned(S->Retain());
+    
+  return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), move(Operand));
 }
 
 template<typename Derived>

Added: cfe/trunk/test/SemaObjCXX/instantiate-stmt.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/instantiate-stmt.mm?rev=102133&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjCXX/instantiate-stmt.mm (added)
+++ cfe/trunk/test/SemaObjCXX/instantiate-stmt.mm Thu Apr 22 16:44:01 2010
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+ at interface NSException
+ at end
+
+// @throw
+template<typename T>
+void throw_test(T value) {
+  @throw value; // expected-error{{@throw requires an Objective-C object type ('int' invalid)}}
+}
+
+template void throw_test(NSException *);
+template void throw_test(int); // expected-note{{in instantiation of}}
+
+





More information about the cfe-commits mailing list