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

Douglas Gregor dgregor at apple.com
Mon Apr 26 10:57:09 PDT 2010


Author: dgregor
Date: Mon Apr 26 12:57:08 2010
New Revision: 102356

URL: http://llvm.org/viewvc/llvm-project?rev=102356&view=rev
Log:
Implement template instantiation for Objective-C @catch
statements. This is the last of the Objective-C statements.

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

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=102356&r1=102355&r2=102356&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Mon Apr 26 12:57:08 2010
@@ -1726,6 +1726,8 @@
   // FIXME: Recover from "NSObject foo" by inserting the * in "NSObject *foo"?
   if (Invalid) {
     // Don't do any further checking.
+  } else if (T->isDependentType()) {
+    // Okay: we don't know what this type will instantiate to.
   } else if (!T->isObjCObjectPointerType()) {
     Invalid = true;
     Diag(NameLoc ,diag::err_catch_param_not_objc_type);

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=102356&r1=102355&r2=102356&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Apr 26 12:57:08 2010
@@ -589,6 +589,11 @@
                                   IdentifierInfo *Name,
                                   SourceLocation Loc, SourceRange TypeRange);
 
+    /// \brief Rebuild the Objective-C exception declaration and register the 
+    /// declaration as an instantiated local.
+    VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, 
+                                      TypeSourceInfo *TSInfo, QualType T);
+      
     /// \brief Check for tag mismatches when instantiating an
     /// elaborated type.
     QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag);
@@ -687,7 +692,16 @@
                                            SourceRange TypeRange) {
   VarDecl *Var = inherited::RebuildExceptionDecl(ExceptionDecl, T, Declarator,
                                                  Name, Loc, TypeRange);
-  if (Var && !Var->isInvalidDecl())
+  if (Var)
+    getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
+  return Var;
+}
+
+VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, 
+                                                        TypeSourceInfo *TSInfo, 
+                                                        QualType T) {
+  VarDecl *Var = inherited::RebuildObjCExceptionDecl(ExceptionDecl, TSInfo, T);
+  if (Var)
     getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
   return Var;
 }

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=102356&r1=102355&r2=102356&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Apr 26 12:57:08 2010
@@ -901,6 +901,30 @@
                                         move(Finally));
   }
 
+  /// \brief Rebuild an Objective-C exception declaration.
+  ///
+  /// By default, performs semantic analysis to build the new declaration.
+  /// Subclasses may override this routine to provide different behavior.
+  VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
+                                    TypeSourceInfo *TInfo, QualType T) {
+    return getSema().BuildObjCExceptionDecl(TInfo, T, 
+                                            ExceptionDecl->getIdentifier(), 
+                                            ExceptionDecl->getLocation());
+  }
+  
+  /// \brief Build a new Objective-C @catch statement.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OwningStmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
+                                          SourceLocation RParenLoc,
+                                          VarDecl *Var,
+                                          StmtArg Body) {
+    return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
+                                          Sema::DeclPtrTy::make(Var),
+                                          move(Body));
+  }
+  
   /// \brief Build a new Objective-C @finally statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
@@ -3722,9 +3746,37 @@
 template<typename Derived>
 Sema::OwningStmtResult
 TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
-  // FIXME: Implement this
-  assert(false && "Cannot transform an Objective-C @catch statement");
-  return SemaRef.Owned(S->Retain());
+  // Transform the @catch parameter, if there is one.
+  VarDecl *Var = 0;
+  if (VarDecl *FromVar = S->getCatchParamDecl()) {
+    TypeSourceInfo *TSInfo = 0;
+    if (FromVar->getTypeSourceInfo()) {
+      TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
+      if (!TSInfo)
+        return SemaRef.StmtError();
+    }
+    
+    QualType T;
+    if (TSInfo)
+      T = TSInfo->getType();
+    else {
+      T = getDerived().TransformType(FromVar->getType());
+      if (T.isNull())
+        return SemaRef.StmtError();        
+    }
+    
+    Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
+    if (!Var)
+      return SemaRef.StmtError();
+  }
+  
+  OwningStmtResult Body = getDerived().TransformStmt(S->getCatchBody());
+  if (Body.isInvalid())
+    return SemaRef.StmtError();
+  
+  return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(), 
+                                             S->getRParenLoc(),
+                                             Var, move(Body));
 }
 
 template<typename Derived>

Modified: cfe/trunk/test/SemaObjCXX/instantiate-stmt.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/instantiate-stmt.mm?rev=102356&r1=102355&r2=102356&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/instantiate-stmt.mm (original)
+++ cfe/trunk/test/SemaObjCXX/instantiate-stmt.mm Mon Apr 26 12:57:08 2010
@@ -65,11 +65,13 @@
   @try {
     value = 1; // expected-error{{assigning to 'int *' from incompatible type 'int'}}
   }
-  // FIXME: Add @catch
-  @finally {
+  @catch (T obj) { // expected-error{{@catch parameter is not a pointer to an interface type}}
+    id x = obj;
+  } @finally {
     value = 0;
   }
 }
 
 template void try_catch_finally_test<NSString *>(int);
 template void try_catch_finally_test<NSString *>(int*); // expected-note{{in instantiation of}}
+template void try_catch_finally_test<NSString>(int); // expected-note{{in instantiation of function template specialization 'try_catch_finally_test<NSString, int>' requested here}}





More information about the cfe-commits mailing list